MicroPython Driver for MB85RC256V FRAM

MB85RC256V FRAM Driver Code for micro:bit

Download as zip file

'''
MB85RC256V
32KB FRAM Memory
MicroPython driver for micro:bit

AUTHOR: fredscave.com
DATE  : 2025/01
VERSION : 1.00
'''

from microbit import *
from ustruct import pack, unpack

I2C_ADDRESS = 0x50
I2C_DEVICE_ID = 0x7C
MEM_END = 0x7FFF

class MB85RC256V():
    def __init__(self, I2C_Addr = I2C_ADDRESS, WP = None):
        self.I2C_Addr = I2C_Addr
        self.WP = WP
        self.WriteProtect(False)
        self.MemPtr = 0
        self.Bytes = 0
        self.Status = False


    def _MSB(self, Addr):
        return (Addr >> 8)  & 0xFF

    def _LSB(self, Addr):
        return Addr & 0xFF

    def _UpdateInternals(self, Status, Bytes, Mem):
        self.Status = Status
        self.Bytes = Bytes
        Mem += self.Bytes
        if Mem > MEM_END:
            self.MemPtr = Mem - MEM_END - 1
        else:
            self.MemPtr = Mem

    def GetMemPtr(self):
        return self.MemPtr

    def SetMemPtr(self, MemPtr):
        if (MemPtr >= 0) and (MemPtr <= MEM_END):
            i2c.write(self.I2C_Addr,
                      bytes([self._MSB(MemPtr),
                      self._LSB(MemPtr)]))
            self._UpdateInternals(True, 0, MemPtr)

    def GetStatus(self):
        return self.Status

    def GetByteCount(self):
        return self.Bytes

    def WriteProtect(self, On =False):
        if self.WP != None:
            if On == True:
                self.WP.write_digital(1)
            else:
                self.WP.write_digital(0)

    def ReadDeviceID(self):
        i2c.write(I2C_DEVICE_ID,
                  bytes([I2C_ADDRESS << 1]),
                  True)
        buf = i2c.read(I2C_DEVICE_ID, 3)
        manufacturer = (buf[0]*256 + buf[1]) >> 4
        product = buf[1] & 0b1111
        return (hex(manufacturer), hex(product))

    def Clear(self, Ch = 0):
        buf = bytearray([Ch])
        for x in range(257):
            buf.append(Ch)
        self.SetMemPtr(0)
        for x in range(128):
            addr = x * 256
            buf[0] = self._MSB(addr)
            buf[1] = self._LSB(addr)
            i2c.write(self.I2C_Addr, buf)
        self._UpdateInternals(True, 0x8000, 0)

    def WriteBlob(self, Buffer, MemAddr=None):
        self._UpdateInternals(False, 0, self.MemPtr)
        if MemAddr == None:
            mem = self.MemPtr
        elif MemAddr in range(MEM_END + 1):
            mem = MemAddr
        else:
            return
        if not isinstance(Buffer, (bytes, bytearray)):
            return
        MSB = bytes([self._MSB(mem)])
        LSB = bytes([self._LSB(mem)])
        buf = MSB + LSB + Buffer
        i2c.write(self.I2C_Addr, buf)
        self._UpdateInternals(True, len(Buffer), mem)

    def ReadBlob(self, N, MemAddr=None):
        self._UpdateInternals(False, 0, self.MemPtr)
        if MemAddr == None:
            mem = self.MemPtr
        elif MemAddr in range(MEM_END + 1):
            mem = MemAddr
        else:
            return bytes([0])
        i2c.write(self.I2C_Addr,
                  bytes([self._MSB(mem),
                  self._LSB(mem)]))
        buf = i2c.read(self.I2C_Addr, N)
        self._UpdateInternals(True, N, mem)
        return buf

    def WriteStr(self, String, MemAddr=None):
        if isinstance(String, str):
            String = String[0:255]
            Buffer = bytearray(0)
            for e in String:
                Buffer = Buffer + bytes([ord(e)])
            Buffer = bytes([len(String)]) + Buffer
            self.WriteBlob(Buffer, MemAddr)
        else:
            self._UpdateInternals(False, 0, self.MemPtr)

    def ReadStr(self, MemAddr = None):
        String=''
        buf = self.ReadBlob(1, MemAddr)
        if buf[0] > 0:
            String = self.ReadBlob(buf[0], self.GetMemPtr())
        return String

    def WriteInt(self, Integer, MemAddr=None):
        if isinstance(Integer, int):
            Buffer = pack('l', Integer)
            self.WriteBlob(Buffer, MemAddr)
        else:
            self._UpdateInternals(False, 0, self.MemPtr)

    def ReadInt(self, MemAddr=None):
        Buffer = self.ReadBlob(4, MemAddr)
        return unpack('l', Buffer)[0]

    def WriteFloat(self, Float, MemAddr=None):
        if isinstance(Float, (int, float)):
            Buffer = pack('f', Float)
            self.WriteBlob(Buffer, MemAddr)
        else:
           self._UpdateInternals(False, 0, self.MemPtr)

    def ReadFloat(self, MemAddr=None):
        Buffer = self.ReadBlob(4, MemAddr)
        return unpack('f', Buffer)[0]