Skip to content

solve issues #69 I2C init bug Jetson #70

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
wants to merge 3 commits into from
Closed

Conversation

tokiAi
Copy link

@tokiAi tokiAi commented Jun 30, 2021

exact description of the error and solution here:
#69

exact description of the error and solution here:
adafruit#69
@ladyada
Copy link
Member

ladyada commented Jun 30, 2021

please look at the full history of this file for the many times this has come up, it has gone back and forth a few times
https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blame/5089bd169444ed64c48fd2d22719c5839eebe2c7/adafruit_bus_device/i2c_device.py#L155
it would be better if this was fixed in the jetson kernel or i2c implementation since it isnt an issue for any other SBC

Copy link
Contributor

@dhalbert dhalbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This solution is not general: some devices don't respond to a read when trying to poll them. We have found a write to be the best way to poll.

@tokiAi
Copy link
Author

tokiAi commented Jun 30, 2021

This solution is not general: some devices don't respond to a read when trying to poll them. We have found a write to be the best way to poll.

A solution that always waits for an error is not really nice.
The error will mostly appear because you only send a write command to the I2C and an ACK follows from the board device and then an empty byte is interpreted as to whether it is to be sent or not. Linux devices will have problems with what to send, as the Jetson and BeagleBone Black show.

Waiting for the error is slower than waiting for the scan. And even more so on the Nvidia Jetson. 10 seconds make Adafruit's I2c library unusable.

please look at the full history of this file for the many times this has come up, it has gone back and forth a few times
https://github.com/adafruit/Adafruit_CircuitPython_BusDevice/blame/5089bd169444ed64c48fd2d22719c5839eebe2c7/adafruit_bus_device/i2c_device.py#L155
it would be better if this was fixed in the jetson kernel or i2c implementation since it isnt an issue for any other SBC

This is also the reason why I described the history so extensively in the issue #69 .
It also a issue on BeagleBone Black as can be seen in the history.

@ladyada
Copy link
Member

ladyada commented Jun 30, 2021

i wish each linux board did not have this problem, but they are not consistent. if you change it and other boards fail, thats not a solution either :) you could try and add specific code to Blinka to handle this if you like, but it does not go in this library that works great except for jetson. please tell nvidia to fix this issue in their i2c driver.

@tokiAi
Copy link
Author

tokiAi commented Jun 30, 2021

i wish each linux board did not have this problem, but they are not consistent. if you change it and other boards fail, thats not a solution either :) you could try and add specific code to Blinka to handle this if you like, but it does not go in this library that works great except for jetson. please tell nvidia to fix this issue in their i2c driver.

Editing the i2c driver would shorten the wait for the error, but it would still be a slower method than scanning for each of the addresses.
The handling of empty bytes is more of the problem.

According to my understanding with the construction of the libraries. "Adafruit_CircuitPython_BusDevice" is not called by "blinka". Instead, "Adafruit_CircuitPython_BusDevice" is used via the individual sensors library. Which makes it difficult to rewrite "blinka".

some devices don't respond to a read when trying to poll them.

I would really be interested which ones they are.
That's why I went through the whole history as described in #69 and at least found no reason why a read shouldn't do it, only that write doesn't work on the BeagleBone Black. (and Jetson)
Found only the following: #22 (comment)

@dhalbert
Copy link
Contributor

It looks like you basically you want to revert aea9d07, which changed the probe from a single-byte read to an empty write attempt. If the write fails, it tries the read. So you want to go back to just a read first.

As mentioned in #22 (comment), doing the read first causes at least one I2C sensor (VEML6075) to not work. So we abandoned that.

Instead of modifying the BusDevice library here, I think the code in adafruit-blinka (which is called by this library) could be changed to error on a zero-byte write immediately.

Ideally the Jetson driver could be fixed.

We have seen issues with zero-byte I2C writes on the RPi RP2040 chip. That chip uses an I2C peripheral licensed from Synopsis, and it does not handle zero-byte writes. We worked around that by bit-banging zero-byte writes. I don't know whether the I2C peripheral on the Jetson is the same and has this same issue, but possibly.

@dhalbert
Copy link
Contributor

According to my understanding with the construction of the libraries. "Adafruit_CircuitPython_BusDevice" is not called by "blinka". Instead, "Adafruit_CircuitPython_BusDevice" is used via the individual sensors library. Which makes it difficult to rewrite "blinka".

It is the other way round. Blinka implements the low-level I2C routines (busio.I2C) for each SBC. BusDevice calls the blinka code to do the reads and writes.

@tokiAi
Copy link
Author

tokiAi commented Jun 30, 2021

According to my understanding with the construction of the libraries. "Adafruit_CircuitPython_BusDevice" is not called by "blinka". Instead, "Adafruit_CircuitPython_BusDevice" is used via the individual sensors library. Which makes it difficult to rewrite "blinka".

It is the other way round. Blinka implements the low-level I2C routines (busio.I2C) for each SBC. BusDevice calls the blinka code to do the reads and writes.

Yes I know. Therefore the init write command would always be called and would then have to be fixed with zero-byte write like with the RPi RP2040 chip. It would be much nicer if you could prevent init writing via a bool.

@tokiAi
Copy link
Author

tokiAi commented Jun 30, 2021

It looks like you basically you want to revert aea9d07, which changed the probe from a single-byte read to an empty write attempt. If the write fails, it tries the read. So you want to go back to just a read first.

As mentioned in #22 (comment), doing the read first causes at least one I2C sensor (VEML6075) to not work. So we abandoned that.

I have read through the documentation for VEML6075 and it is also clear that it does not support "read only" without writing. But why is this not handled on the sensor VEML6075 library. It is a property of the sensor not of the I2C.

I don't know if it is a good trade off to move the special features of the sensors into the I2C library and thus to slow down the I2C connection.

This enables probing with I2C-read (without write) from the sensor libraries.
@tokiAi
Copy link
Author

tokiAi commented Jun 30, 2021

i wish each linux board did not have this problem, but they are not consistent. if you change it and other boards fail, thats not a solution either :) you could try and add specific code to Blinka to handle this if you like, but it does not go in this library that works great except for jetson. please tell nvidia to fix this issue in their i2c driver.

@ladyada I can understand your concerns and have now made a new commit ea17818 in which you could switch on reading without writing via a bool.
The idea of ​​this bool then gives the individual sensor libraries the opportunity to decide whether to use the write probing or not like e.g. mcp = MCP23017(i2c, address=0x24, probe=True, probe_with_write=False) for read probe without write (for advanced programmers). Of course, the sensor libraries must be adapted.

I think probing should be a property of the sensor libraries not of the I2C librarie or blinka librarie.

@tokiAi
Copy link
Author

tokiAi commented Jul 1, 2021

Can someone explain why "All checks have failed". What do I have to change in the code?

@dhalbert
Copy link
Contributor

dhalbert commented Jul 1, 2021

Click on the "Details" link. You'll see that it is failing the black formatting test.

It is a good idea to use pre-commit to run the checks locally before you commit and push. See here: https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/check-your-code

@tokiAi
Copy link
Author

tokiAi commented Jul 1, 2021

Click on the "Details" link. You'll see that it is failing the black formatting test.

@dhalbert I have never worked with black and the details only show the "Error: Process completed with exit code 1." - which is really meaningless for me.
Could you take a quick look at the code and maybe explain where it could fail?

@dhalbert
Copy link
Contributor

dhalbert commented Jul 1, 2021

This guide https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library gives all the details. Look at https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/black for black in particular, but it's worth reading the whole guide.

@tokiAi
Copy link
Author

tokiAi commented Jul 1, 2021

This guide https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library gives all the details. Look at https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/black for black in particular, but it's worth reading the whole guide.

My mistake read it over that black only runs in check mode on the server and should run it in the other mode localy before commit.

@tokiAi
Copy link
Author

tokiAi commented Jul 1, 2021

Is that okay? Can you then merge into the current version?
The behavior remains the same as main-git-path, but the bool (probe_with_write) allows the library to be called without an init i2c write probe - only with read probe.

@tokiAi
Copy link
Author

tokiAi commented Jul 9, 2021

@ladyada @dhalbert Can you then merge into the current version?
Then it would be possible to skip the writing probe for sensors where a read is sufficient.

@dhalbert
Copy link
Contributor

@tokiAi We do want to solve this in a general way, and may change the scanning technique on Linux boards only from write to read, due to Linux limitations. Our microcontroller experience is that 0-byte writes are in general the best, but not always available, as you have seen.

So use a fork as needed for now for your work, and we will put this on our to-do queue, with not necessarily this exact solution, but with a solution.

@FoamyGuy
Copy link
Contributor

Closing this for now as we're waiting for a more general solution.

@FoamyGuy FoamyGuy closed this Dec 24, 2021
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

Successfully merging this pull request may close these issues.

4 participants