-
Notifications
You must be signed in to change notification settings - Fork 616
Description
I started a binding for the At24Cxx Serial EEPROM and wanted to ping for thoughts before proceeding.
The problem I noticed while reading the datasheets is the I2C addresses vary based on the size of memory. For example, the AT24C01/AT24C02 uses the hardware pins for addressing A0-A2 and the page addresses are in the first byte read/written (as in most cases).
However, as you work your way up to the AT24C16, it begins using the address bits A0-A2 instead to address the pages. Figure 7. Device Address in datasheet link above explains. This is somewhat of a hindrance in the I2cDevice implementation as you must assign the I2C address to the I2cConnectionSettings and then instantiate the I2cDevice. The I2cDevice object is assigned the I2C address for the lifetime of the object.
I'm hesitantly okay with this as you could design the binding where certain devices would have to use multiple I2cDevice objects to access all available memory. Basically, the one device would look like multiple devices on the bus. For example, the AT24C16 would need 8 I2cDevice objects to address all memory using addresses 0x50 - 0x57 where each object could access 16 pages.
The problem I see with this approach, is there will be some users that want to interact with the device/memory as a whole. I've personally seen where an IoT device has a 4K size of configuration data that is loaded into EEPROM. Ideally, I would use a method call that provides starting address and bytes of data to write. In general use, the binding API would need some internal logic to determine the paging (no matter what AT24C device) and would offer a little more appeasing API surface for Reads/Writes. However, I'm not sure of a good solution being forced to instantiate multiple I2cDevice objects to accomplish this.
/cc @joperezr @JeremyKuhne @krwq I'm copying you as you might have some thoughts how to get around this with current implementation or ideas on how to improve the II2cController that is in the works.
Since most of our current bindings pass in an I2cDevice object to instantiate the binding, I'm not sure how we could recreate another I2cDevice object with the new address to use when attempting to access related pages.
Would it be beneficial to add the following methods where it would override the initial address and use one provided? I could see this confusing some users as they'll see this as an option and think they have to use instead of how the current method includes the address.
public abstract byte ReadByte(int deviceAddress);
public abstract void Read(int deviceAddress, Span<byte> buffer);
public abstract void WriteByte(int deviceAddress, byte data);
public abstract void Write(int deviceAddress, Span<byte> data);One other tidbit, I personally don't want the bindings to provide me with "best" I2cDevice for platform (similar to GpioController) as I might want to use my own (e.g. GpioI2cDevice, etc.) in particular cases.