Closed StevenBruinen closed 5 years ago
lgtm, @caternuson wanna try it out?
I'm not seeing this used in the FRAM library: https://github.com/adafruit/Adafruit_CircuitPython_FRAM/blob/master/adafruit_fram.py Can you show where this is. Or, even better, provide an example showing how the TCA and FRAM are not working together?
Thought that might be the intention here. But PR is writeto_then_readfrom
. Was it suppose to be write_then_readinto
?
But also, I think my code comment here is wrong:
https://github.com/adafruit/Adafruit_CircuitPython_TCA9548A/blob/master/adafruit_tca9548a.py#L53
The TCA is more of a passthru for busio.i2c
, not i2c_device
. The key bit being the override of try_lock
to insert the channel switch:
https://github.com/adafruit/Adafruit_CircuitPython_TCA9548A/blob/master/adafruit_tca9548a.py#L65
which gets called by i2c_device
's context manager here:
https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blob/master/adafruit_bus_device/i2c_device.py#L175
Went ahead and wired up a TCA and I2C FRAM and it's currently working OK:
Adafruit CircuitPython 3.1.2 on 2019-01-07; Adafruit ItsyBitsy M4 Express with samd51g19
>>> import board, busio
>>> import adafruit_tca9548a
>>> import adafruit_fram
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> tca = adafruit_tca9548a.TCA9548A(i2c)
>>> fram = adafruit_fram.FRAM_I2C(tca[1])
>>> fram[0] = 1
>>> fram[0]
bytearray(b'\x01')
>>>
maybe a typo? :) you hit the issue on raspberry pi more because it cant do repeated start in two commands
With the new code the FRAM module works ok on my RaspberryPi. Without it I get the error below when running:
try:
import adafruit_fram
fram = adafruit_fram.FRAM_I2C(tca[1])
logging.info('FRAM memory: Module active.')
except Exception as e:
logging.exception('FRAM memory: Module not responding.')
Traceback (most recent call last):
File "/home/pi/MainProgram.py", line 50, in <module>
fram = adafruit_fram.FRAM_I2C(tca[1])
File "/usr/local/lib/python3.5/dist-packages/adafruit_fram.py", line 211, in __init__
read_buf, stop=False)
File "/usr/local/lib/python3.5/dist-packages/adafruit_bus_device/i2c_device.py", line 167, in write_then_readinto
self.readinto(in_buffer, start=in_start, end=in_end)
File "/usr/local/lib/python3.5/dist-packages/adafruit_bus_device/i2c_device.py", line 97, in readinto
self.i2c.readfrom_into(self.device_address, buf, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/adafruit_tca9548a.py", line 76, in readfrom_into
return self.tca.i2c.readfrom_into(address, buffer, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/busio.py", line 55, in readfrom_into
return self._i2c.readfrom_into(address, buffer, stop=stop)
File "/usr/local/lib/python3.5/dist-packages/adafruit_blinka/microcontroller/generic_linux/i2c.py", line 44, in readfrom_into
readin = self._i2c_bus.read_bytes(address, end-start)
File "/usr/local/lib/python3.5/dist-packages/Adafruit_PureIO/smbus.py", line 155, in read_bytes
return self._device.read(number)
OSError: [Errno 121] Remote I/O error
Oh, I see what's going on. It's to support this:
https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blob/master/adafruit_bus_device/i2c_device.py#L150
Things are conditionally different in write_then_readinto
. It went down the other branch since there is no writeto_then_readfrom
, which doesn't work as @ladyada pointed out. So gets the I/O Error.
@StevenBruinen Thanks. Set this up on a Pi and got same error. Tested your fix and it works.
Can you add a code comment to the function similar to this: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blob/8a5b9974cda321771941f2e69513c9cee13e07fb/adafruit_bus_device/i2c_device.py#L154 which might help highlight this as a linuxy specific thing in the future.
Great! I've added the comment as requested.
Sorry, I think I did something wrong now but I don't know what. This is my first pull request ever... :-)
Awesome! Thanks for finding this and submitting the fix.
Look ma, no I/O errors:
pi@raspberrypi:~ $ python3
Python 3.5.3 (default, Sep 27 2018, 17:25:39)
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import board, busio
>>> import adafruit_tca9548a
>>> import adafruit_fram
>>> i2c = busio.I2C(board.SCL, board.SDA)
>>> tca = adafruit_tca9548a.TCA9548A(i2c)
>>> fram = adafruit_fram.FRAM_I2C(tca[1])
>>> fram[0] = 0x10
>>> fram[0]
bytearray(b'\x10')
Cool! Solved for everybody now \0/ Thank you all for your support!
Added support for the busio 'write_then_readfrom' function as some i2c devices require this (e.g. the Adafruit i2c FRAM module)