Closed rgrizzell closed 11 months ago
Just to be up-front, I only just started learning about I2C the other week and haven't worked with hardware on this level before. That said, I've attempted to patch in support for addresses of any length. It's a lot easier to work with when it's converted into a bytes. Unfortunately, when you plug the address into bytes(0x8140)
, you just end up with an object that's 33088 bytes in size.
After reading through a lot of different threads, this is what I piece together to get around that issue.
register_address_bytes = register_address.to_bytes((register_address.bit_length() + 7) // 8, 'big')
self.buffer = bytearray(len(register_address_bytes) + register_width)
self.buffer[0:len(register_address_bytes)] = register_address_bytes
The downside is that (register_address.bit_length() + 7) // 8
returns 0
when address 0x00
is specified. For that to address to work, its probably just better to create a function to handle the conversion.
def register_in_bytes(address: int):
if address == 0x00:
return bytearray(1)
return address.to_bytes((address.bit_length() + 7) // 8, 'big')
If it's better to limit that conversion to just 8 and 16 bits, then bitwise works. I haven't figure out how to make this work for any length, though.
if 0xFFFF >= register_address > 0xFF:
self.buffer = bytearray(2 + register_width)
self.buffer[0] = register_address >> 8
self.buffer[1] = register_address & 0xFF
else:
self.buffer bytearray(1 + register_width)
self.buffer[0] = register_address
You can use i2c_struct
with a type code for a 16 bit value: https://github.com/adafruit/Adafruit_CircuitPython_Register/blob/main/adafruit_register/i2c_struct.py
You can use
i2c_struct
with a type code for a 16 bit value: https://github.com/adafruit/Adafruit_CircuitPython_Register/blob/main/adafruit_register/i2c_struct.py
I'm sorry, but I don't understand how to use that function. There are no existing examples where anyone else has used the i2c_struct
to get a 16-bit register address.
Addr | Access | Descrption |
---|---|---|
0x8140 | Read | Product ID (first byte,ASCII) |
0x8141 | Read | Product ID (second byte,ASCII) |
0x8142 | Read | Product ID (third byte,ASCII) |
0x8143 | Read | Product ID (fourth byte,ASCII) |
Would you please give an example using the above? It'll go a long way toward helping me understand how to make this driver work.
Sorry, I misread your issue. I read value
instead of address
. You are right that this library assumes 8 bit addresses.
It is probably easiest to make a version that works for you. Supporting arbitrary address lengths will increase code complexity that most thing won't use.
It is probably easiest to make a version that works for you. Supporting arbitrary address lengths will increase code complexity that most thing won't use.
I'm inclined to agree, I haven't seen examples of other I2C devices that use 16-bit registers.
Thanks for the input!
I'm working on a driver for the GT911 touchscreen and the touch presses are returned via I2C. However, they're read from 16-bit registers rather than 8-bit. For example, to get the Product ID of the touchscreen you must read from
0x8140
.After looking through this library, adding support for 16-bit appears feasible. However, would that cause issues for 8-bit devices? Further more, I2C doesn't seem to set any limits on register size. Should support extend to sizes beyond 16 bits? Should I just implement my own read and write functions inside the driver instead?
Any insights will be appreciated, thanks!