# uPy - RPi Pico SPI read and write bytes to fram MB85RS64
# provided by Anthony Vogelaar, Perth Scotland
# rev 0.10  2025-01-12  initial release

# ================== Fram Constants ====================

WREN	= 0x06					# MB85R64 set   write enable latch
WRDI	= 0x04					# MB85R64 reset write enable latch
RDSR	= 0x05					# MB85R64 read  status register
WRSR	= 0x01					# MB85R64 write status register, protected by /WP = gnd
READ	= 0x03					# MB85R64 read  date
WRITE	= 0x02					# MB85R64 write data

# ==================== class Fram =====================

# see: https://docs.micropython.org/en/latest/rp2/quickref.html#hardware-spi-bus
#      https://docs.micropython.org/en/latest/library/machine.SPI.html#machine-spi

class Fram:
    
    def __init__(self, spi, cs):
        self.spi     = spi
        self.cs		 = cs
        self.buf1	 = bytearray(1)
        
    
    # return fram status byte
    def getStatus(self):
        self.cs(0)
        data_rx = self.spi.read(2, RDSR)
        self.cs(1)
        return(data_rx[1])
        

    # set fram write enable latch to protect
    def writeProtect(self, protect=True):
        self.cs(0)
        self.buf1[0] = WRDI if protect else WREN
        self.spi.write(self.buf1)
        self.cs(1)


    # write bytes / bytearray to addr
    def write(self, addr=0x0000, data=b'\x00'):
        if not isinstance(data, (bytes, bytearray)): return
        self.data_tx = bytes([WRITE, addr >> 8, addr & 0xFF]) + data
        self.writeProtect(False)
        self.cs(0)
        self.spi.write(self.data_tx)
        self.cs(1)
        self.writeProtect(True)
        
        
    # read n bytearray from addr
    def read(self, addr=0x0000, n=1):
        data_tx = bytes([READ, addr >> 8, addr & 0xFF]) + bytes(n)
        data_rx = bytearray(3+n)
        self.cs(0)
        self.spi.write_readinto(data_tx, data_rx)
        self.cs(1)
        return data_rx[3:]
    
# ==================== test ========================

from	machine		import	Pin, SPI

# ============== Hardware definitions ==============

pin_led         = 25				# on-board green led
pin_spi_sck		= 18
pin_spi_mosi	= 19
pin_spi_miso	= 16
pin_spi_cs		= 17

# ============ Hardware setup  =================

led		= Pin(pin_led, Pin.OUT, value=1)
spi	    = SPI(0, 10_000_000, sck=pin_spi_sck, mosi=pin_spi_mosi,
              miso=pin_spi_miso)
spi_cs  = Pin(pin_spi_cs, Pin.OUT, value=1)


def test():
    fram = Fram(spi, spi_cs)
    fram.write(0x0100, bytes([1, 2, 3, 4, 5]))
    print(fram.read(0x0100, 5))
    fram.write(0x0100, bytes([5, 4, 3, 2, 1]))
    print(fram.read(0x0100, 5))
    fram.write(0x0100, bytes([0, 0, 0, 0, 0]))
    print(fram.read(0x0100, 5))
    
 
test()
spi.deinit()
    
# ====================== End ==========================
