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]

Reply via email to