esp32: Slow I2C on S2 after bus failures.
After a certain number (usually <10) of failures (e.g. ENODEV due to non-existent address), the clock frequency seems to drop to 1/16 of the requested value.
Unfortunately, this is exactly how i2c.scan() is implemented, so the behavior I see is that everything is fine if I don't do a scan first.
i2c_get_period continues to report the original frequency. If add a call i2c_param_config to re-set the frequency, then all is fine.
Can replicate on IDF 4.4 and 5.0, and only on S2.
esp32/i2c: Use idf function for calculating main timeout.
<!-- Thanks for submitting a Pull Request! We appreciate you spending the
time to improve MicroPython. Please provide enough information so that
others can review your Pull Request.
Before submitting, please read:
https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md
https://github.com/micropython/micropython/wiki/ContributorGuidelines
Please check any CI failures that appear after your Pull Request is opened.
-->
Summary
The esp32 I2C driver sets a global timeout during init. The functionality for this is currently only correct for original esp32 and esp32-s2, newer parts have a slightly different argument.
When searching through the IDF code for this driver I found this function that handles the chip-specific differences.
ESP32-S2
ESP32-S3
Testing
This has been implemented from the reference manual & inspecting the IDF codebase, I haven't pysically tested it so far.