TFS on I2C memory

Is there an example of TFS running on an I2C memory device? I am looking to see how the driver file is implemented.

No, but we have example for QSPI.

All you need is change interface, I guess.

File System (ghielectronics.com)

I have read through the one for QSPI but I guess I am still missing some info. (This is my first attempt are writing a driver like this.) I see what methods I need to support but I can’t seem to find the details on what the parameters are exactly and what the expected return values are when they are necessary.

Some of the other examples online that I have seen used the Storage class that appears to have been changed to IStorageControllerProvider.

1 Like

Something like this:

var i2cController = I2cController.FromName(SCxxxx....);

 var i2cSettings = new I2cConnectionSettings(your address)
                {
                    BusSpeed = 100000,
                    AddressFormat = I2cAddressFormat.SevenBit
                };

var  i2cDevice = controller.GetDevice(i2cSettings);

const int CLUSTER_SIZE = 1024;

var tfs = new TinyFileSystem(new I2cMemory (i2cDevice, your size), CLUSTER_SIZE);

// the rest should be same QSPI.
public sealed class I2cMemory : IStorageControllerProvider
{
    public StorageDescriptor Descriptor => this.descriptor;
    const int SectorSize = your_SectorSize;

    private StorageDescriptor descriptor = new StorageDescriptor()
    {
        CanReadDirect = your_,
        CanWriteDirect = your_,
        CanExecuteDirect = your_,
        EraseBeforeWrite = your_,
        Removable = your_,
        RegionsContiguous = your_,
        RegionsEqualSized = your_,
        RegionAddresses = new long[] { 0 },
        RegionSizes = new int[] { SectorSize },
        RegionCount = your_totalsize / (SectorSize)
    };

    private I2cDevice i2cDevice;


    public I2cMemory(I2cDevice i2cDevice, uint size)
    {
        
        if (size <= SectorSize)
            throw new ArgumentOutOfRangeException("size too small.");

        if (size != descriptor.RegionCount * SectorSize)
        {
            descriptor.RegionCount = (int)(size / SectorSize);
        }

       
        this.Open();
    }

    public void Open()
    {
        // You may need write something to wakeup chip - read datasheet
		// TODO
    }

    public void Close()
    {
        // TODO
    }

    public void Dispose()
    {
        // TODO
    }

    public int Erase(long address, int count, TimeSpan timeout)
    {
        // TODO
		
		return something
    }

    public bool IsErased(long address, int count)
    {
        // TODO
		i2cDevice.WriteRead....
		
		return something
    }

    public int Read(long address, int count, byte[] buffer, int offset, TimeSpan timeout)
    {
        // TODO
		// Issue command to read
		i2cDevice.WriteRead....
		return something
    }

    public int Write(long address, int count, byte[] buffer, int offset, TimeSpan timeout)
    {
        // TODO
		// Issue command to write
		i2cDevice.WriteRead....
		
		return something
    }

    public void EraseAll(TimeSpan timeout)
    {
        // TODO
		// Issue command to erase all chip if suppotrt
		i2cDevice.WriteRead....
		
		return something
    }
}

Thanks for the info. I will see what I can do with that.

What do the CanRead/Write/Execute Direct descriptors represent and how does that translate to a physical device like Flash or FRAM?

ReadDirect or WriteDirect mean you can read/write data directly.

Like RAM you can read/write directly.
Internal Flash you can read directly but you can’t write directly, you need send special command to write data…
ExecuteDirect mean can XIP.

EraseBeforeWrite = mean you need to erase before write if data exist.

If I2C flash, check with your datasheet but likely:

CanReadDirect = False
CanWriteDirect = False
CanExecuteDirect = False
EraseBeforeWrite = True

I am getting pretty close I think to get this to work.

what is the purpose of IsErased() and what/how is it checked? Is it checking to see if a specific block or cluster is empty?

It needs to know if a clock is ready to be written to or it should be erased first.

I guess the simplest return value would be False to force an erase every time.

Is there a quick way to check a block to see if it needs to be erased?

I have found and have been referencing the documentation for MBN-TinyCLR implementation of TFS. (MBN-TinyCLR/TinyFileSystem.cs at master · MBNSoftware/MBN-TinyCLR · GitHub)

Is the TFS version built into TinyCLR the same?

Firstly, TinyCLR took that driver.
Secondly, thanks to MBNSoftware
Finally, they are same :)).

1 Like

I guess the biggest hurdle for me was that examples and code shown on MBN’s repo rely on the Storage interface but the TinyCLR interface uses IStorageControllerProvider. But between MBN’s code and examples as well as GHI’s, and of course, everyone’s help here, I think I have pieced it together.

I know documentation is hard and time-consuming but a little more documentation on how interfaces like IStorageControllerProvider actually work would be helpful. And possibly it is just me and I have overlooked some resources I am not aware of.

As of now, it seems to be working. Next week I will put it through more rigorous testing to see if I got it right.

Thanks!

1 Like