Skip to content

I2C init bug causes 10 seconds delay on the Jetson TX2 / Nano #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tokiAi opened this issue Jun 30, 2021 · 2 comments
Closed

I2C init bug causes 10 seconds delay on the Jetson TX2 / Nano #69

tokiAi opened this issue Jun 30, 2021 · 2 comments

Comments

@tokiAi
Copy link

tokiAi commented Jun 30, 2021

Issue:

I2C init bug causes 10 seconds delay on the Jetson TX2 / Nano. This problem is described on the following forums:
https://forums.developer.nvidia.com/t/slow-initial-connection-to-i2c-sensor-from-python/161657
https://forums.adafruit.com/viewtopic.php?t=172811
https://forums.adafruit.com/viewtopic.php?t=180616

What is happening:

Logic Analyzer:

  • [write(address)+ ACK]
  • Nothing happens for about 10 seconds because the SCL is LOW (because of the ACK)
  • SCL is pushed up after about 10 seconds
  • a few milliseconds after that there is a [read (address) + ACK] [data + NAK]

Guess what happens:

  • Jetson receives a write command without data or with data that can be interpreted according to the system
  • Throws an error
  • Then continues with the read command

Code that causes this behavior:
Adafruit_CircuitPython_BusDevice/adafruit_bus_device/i2c_device.py
__init__ -> self.__probe_for_device() -> line 153 to 160

try:
                self.i2c.writeto(self.device_address, b"")
except OSError:
              # some OS's dont like writing an empty bytesting...
              # Retry by reading a byte
              try:
                    result = bytearray(1)
                    self.i2c.readfrom_into(self.device_address, result)

History of the write command

In order to understand whether this is necessary or useful:

  • commit fc7b805 adafruit_bus_device/i2c_device.py line 52 scan = i2c.scan() was added
  • commit 143df86 adafruit_bus_device/i2c_device.py changed in line 56 to i2c.writeto(device_address, b'') with the reason: Don't scan the whole bus to verify existence of i2c device
    -> A mistake happens here - but more on that later
  • commit 3a1339c solves the error on the BeagleBone Black with i2c.writeto(device_address, b'x') adafruit_bus_device/i2c_device.py in line 64
  • commit 796e0a1 solves the error on the BeagleBone Black with dafruit_bus_device/i2c_device.py changed in line 67, 68 to
    result = bytearray(2)
    i2c.readfrom_into(device_address, result)
  • commit 793537e solves the error on the BeagleBone Black with adafruit_bus_device/i2c_device.py changed in line 67, 68 to result = bytearray(1)with the reason: it is not needed to read more than 1 byte
    -> This is probably also the best solution - but more on that later
  • commit aea9d07 solves the error on the BeagleBone Black with adafruit_bus_device/i2c_device.py changed in line 67 - 76 to
            i2c.writeto(device_address, b'')
        except OSError:
            # some OS's dont like writing an empty bytesting...
            # Retry by reading a byte
            try:
                result = bytearray(1)
                i2c.readfrom_into(device_address, result)
  • From here on the code only changes in place and is now a part of the function self.__ probe_for_device()

Solution and the error that was overlooked

Error:
The idea was good not to scan all addresses in commit 143df86 , but a false assumption was made that this is done with writing and not with reading.
If you look at the scan() function you can see that it is done with read.
For Linux is located in the blinka library https://github.com/adafruit/Adafruit_Blinka/blob/a79eb436569f2c4d1390571eba5779fc5aedf6db/src/adafruit_blinka/microcontroller/generic_linux/i2c.py :
line 38 self._i2c_bus.read_byte(addr)

Solution:
Back to the origin:
Scan the necessary address. In other words, read 1 byte on the address.

tokiAi added a commit to tokiAi/Adafruit_CircuitPython_BusDevice that referenced this issue Jun 30, 2021
exact description of the error and solution here:
adafruit#69
@dhalbert
Copy link
Contributor

dhalbert commented Jun 30, 2021

See comments in #70.

@FoamyGuy
Copy link
Contributor

Closing this issue here. If anyone who finds this would like to work on it please submit a solution in Blinka to try to account for the jetson having a different I2C behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants