Skip to content

Commit 2f67002

Browse files
committed
intial SPI
1 parent f4997ee commit 2f67002

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

adafruit_fram.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
_I2C_MANF_ID = const(0x0A)
5858
_I2C_PROD_ID = const(0x510)
5959

60+
_SPI_MANF_ID = const(0x04)
61+
_SPI_PROD_ID = const(0x302)
62+
6063
class FRAM:
6164
"""
6265
Driver base for the FRAM Breakout.
@@ -257,3 +260,100 @@ def _write(self, start_register, data, wraparound=False):
257260
buffer[1] = ((start_register + i) - self._max_size) & 0xFF
258261
buffer[2] = data[i]
259262
i2c.write(buffer)
263+
264+
# the following pylint disables are related to the '_SPI_OPCODE' consts, the super
265+
# class setter '@FRAM.write_protected.setter', and pylint not being able to see
266+
# 'spi.write()' in SPIDevice. Travis run for reference:
267+
# https://travis-ci.com/sommersoft/Adafruit_CircuitPython_FRAM/builds/87112669
268+
269+
# pylint: disable=no-member,undefined-variable
270+
class FRAM_SPI(FRAM):
271+
""" SPI class for FRAM.
272+
273+
:param: ~busio.SPI spi_bus: The SPI bus the FRAM is connected to.
274+
:param: ~digitalio.DigitalInOut spi_cs: The SPI CS pin.
275+
:param: bool write_protect: Turns on/off initial write protection.
276+
Default is ``False``.
277+
:param: wp_pin: (Optional) Physical pin connected to the ``WP`` breakout pin.
278+
Must be a ``digitalio.DigitalInOut`` object.
279+
:param int baudrate: SPI baudrate to use. Default is ``1000000``.
280+
"""
281+
282+
_SPI_OPCODE_WREN = const(0x6) # Set write enable latch
283+
_SPI_OPCODE_WRDI = const(0x4) # Reset write enable latch
284+
_SPI_OPCODE_RDSR = const(0x5) # Read status register
285+
_SPI_OPCODE_WRSR = const(0x1) # Write status register
286+
_SPI_OPCODE_READ = const(0x3) # Read memory code
287+
_SPI_OPCODE_WRITE = const(0x2) # Write memory code
288+
_SPI_OPCODE_RDID = const(0x9F) # Read device ID
289+
290+
#pylint: disable=too-many-arguments,too-many-locals
291+
def __init__(self, spi_bus, spi_cs, write_protect=False,
292+
wp_pin=None, baudrate=100000):
293+
from adafruit_bus_device.spi_device import SPIDevice as spidev
294+
_spi = spidev(spi_bus, spi_cs, baudrate=baudrate)
295+
296+
read_buffer = bytearray(4)
297+
with _spi as spi:
298+
spi.write(bytearray([_SPI_OPCODE_RDID]))
299+
spi.readinto(read_buffer)
300+
prod_id = (read_buffer[3] << 8) + (read_buffer[2])
301+
if (read_buffer[0] != _SPI_MANF_ID) and (prod_id != _SPI_PROD_ID):
302+
raise OSError("FRAM SPI device not found.")
303+
304+
self._spi = _spi
305+
super().__init__(_MAX_SIZE_SPI, write_protect, wp_pin)
306+
307+
def _read_register(self, register, read_buffer):
308+
write_buffer = bytearray(3)
309+
write_buffer[0] = _SPI_OPCODE_READ
310+
write_buffer[1] = register >> 8
311+
write_buffer[2] = register & 0xFF
312+
#read_buffer = bytearray(1)
313+
with self._spi as spi:
314+
spi.write(write_buffer)
315+
spi.readinto(read_buffer)
316+
return read_buffer
317+
318+
def _write(self, start_register, data, wraparound=False):
319+
buffer = bytearray(3)
320+
if not isinstance(data, int):
321+
data_length = len(data)
322+
else:
323+
data_length = 1
324+
data = [data]
325+
if (start_register + data_length) - 1 > self._max_size:
326+
if wraparound:
327+
pass
328+
else:
329+
raise ValueError("Starting register + data length extends beyond"
330+
" FRAM maximum size. Use 'wraparound=True' to"
331+
" override this warning.")
332+
with self._spi as spi:
333+
spi.write(bytearray([_SPI_OPCODE_WREN]))
334+
with self._spi as spi:
335+
buffer[0] = _SPI_OPCODE_WRITE
336+
buffer[1] = start_register >> 8
337+
buffer[2] = start_register & 0xFF
338+
spi.write(buffer)
339+
for i in range(0, data_length):
340+
spi.write(bytearray([data[i]]))
341+
with self._spi as spi:
342+
spi.write(bytearray([_SPI_OPCODE_WRDI]))
343+
344+
@FRAM.write_protected.setter
345+
def write_protected(self, value):
346+
# While it is possible to protect block ranges on the SPI chip,
347+
# it seems superfluous to do so. So, block protection always protects
348+
# the entire memory (BP0 and BP1).
349+
self._wp = value
350+
write_buffer = bytearray(2)
351+
write_buffer[0] = _SPI_OPCODE_WRSR
352+
if value:
353+
write_buffer[1] = 0x8C # set WPEN, BP0, and BP1
354+
else:
355+
write_buffer[1] = 0x00 # clear WPEN, BP0, and BP1
356+
with self._spi as spi:
357+
spi.write(write_buffer)
358+
if not self._wp_pin is None:
359+
self._wp_pin.value = value

0 commit comments

Comments
 (0)