adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
457 stars 349 forks source link

FT2232H I2C frequency not set properly/reliably #479

Open securelyfitz opened 3 years ago

securelyfitz commented 3 years ago

I'm testing out the FT2232H support in the latest release using stats.py (because I have lots of oled displays on hand)

With an Adafruit FT2232H breakout board, it works fine: BLINKA_FT232H=1 ./stats.py I can run, quit, and re-run the command over and over.

After swapping to FT2232H hardware and changing all the instances of SDA and SCL to SDA1 and SCL1 it works once: BLINKA_FT2232H=1 ./stats-2232.py I can run it once and sometimes a few times, but eventually it gets a NACK and can't see the display.

Observing with a logic analyzer shows I2C clock going at 400khz the first few times, but 4Mhz when it eventually fails because the oled display doesn't respond at such a high speed.

Things i've tried:

Then, I changed stats.py to exit after running once, and running it in a bash loop. It works flawlessly. That leads me to believe there's something not getting cleaned up on exit from keyboard interrupt, or something not fully initialized in code that is properly cleared on power cycle.

At this point I can't be sure whether this is a Blinka, PyFTDI, or FTDI problem, but I figured I'd log it here until I figure out more.

securelyfitz commented 3 years ago

Had some time to revisit this:

Going through these paces reminds me of some issues i had when building the tigard test flow - some tests would automatically fail if run too soon after the previous test.

Combined with the fact that this just works on the ft232h, I'm suspecting more that this is a pyftdi or FTDI problem and not due to blinka. I will investigate more.

securelyfitz commented 3 years ago

Tried to do a little more debugging by monitoring with i2cscan.py, and discovered

This reinforces my suspicion that there's a pyftdi issue where something is getting cleaned up that's not getting initialized. i2cscan should always work the first time.

However, I went back and tested the ft232h:

So, there's magic block of code getting run during initialization or cleanup: i2cscan.py is doing magic during cleanup, but not doing it during initialization ft232h through blinka is doing magic during initialization but not during cleanup ft2232h through blinka is not doing magic in either initialization or cleanup

So, this is almost certainly a pyftdi issue, even if the magic initialization/cleanup could be added at the blinka layer.