FelipeMdeO opened a new pull request, #20227:
URL: https://github.com/apache/nuttx/pull/20227
## Summary
Light sleep gates the APB clock the I2C peripheral runs on. A transfer in
flight stops mid-message and never raises its completion interrupt, so the
caller blocks in `i2c_sem_waitdone()` until `ESP32S3_I2CTIMEOTICKS` expires
and gets `-ETIMEDOUT` for a bus that was working perfectly.
The caller is what causes it: blocking in `i2c_sem_waitdone()` is exactly
what makes the idle task runnable, and the idle task is what decides to
sleep — so the longer the transfer, the likelier it is to be cut in half
by its own wait. Nothing about this is driver-specific; it surfaced
through a sensor doing a 6000-byte FIFO burst read (~135 ms at 400 kHz),
the longest transaction on this board, but any I2C driver on this port is
exposed the same way.
The consequences went past one failed read: with the FIFO left undrained,
the sensor's level-triggered INT1 stayed asserted, its worker was
re-entered the instant the IRQ was re-enabled, and that hot loop starved
every other task until the board wedged with no console output and no
crash dump.
Fix: `pm_stay(PM_IDLE_DOMAIN, PM_IDLE)` around the transfer in
`esp32s3_i2c.c`, released unconditionally afterward (no early return
between the stay and the relax). `PM_IDLE` is the lightest lock that
suffices — `greedy_governor_checkstate()` walks up from `PM_NORMAL` and
stops at the first state holding a wakelock, so staying at `PM_IDLE` keeps
the domain out of `PM_STANDBY`/`PM_SLEEP` while still allowing the plain
WFI idle.
## Impact
* Is new feature added? No — pure bug fix.
* Is existing feature changed? No behavior change for configs without
`CONFIG_PM`. For `CONFIG_PM` configs that reach `PM_STANDBY`, prevents
every I2C transfer on this port from racing light sleep.
* Impact on hardware? `arch/xtensa/src/esp32s3/esp32s3_i2c.c` — every I2C
driver on the esp32s3 port; long transfers are the ones actually exposed
in practice.
## Testing
I confirm that changes are verified on local setup and works as intended:
* Build Host: Ubuntu 24.04, x86_64, `xtensa-esp-elf-gcc`.
* Target: Xtensa, Seeed XIAO ESP32-S3 (esp32s3-xiao), `CONFIG_PM=y` +
`CONFIG_SCHED_TICKLESS=y`, LSM6DS3TR-C over I2C at 12.5 Hz with FIFO
watermark drains.
Before the fix: the same workload wedged the board within seconds of the
first `-ETIMEDOUT`. After the fix, validated over 3 h 45 of continuous
acquisition across two sessions — wakes and drains stayed 1:1 (302/302,
then 375/375), zero I2C failures of any kind, light sleep itself
unaffected (11.8% of wall time asleep in both, median sleep 2.08 s). Zero
I2C failures also held for a 12 h 25 continuous production run across
thousands of light-sleep cycles at a raised FIFO watermark.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]