From e4cc7b72581d72f6a41f10f52ff6feb964cb843a Mon Sep 17 00:00:00 2001 From: Felipe Moura Date: Sat, 19 Sep 2026 17:57:47 -0300 Subject: [PATCH] boards/esp32s3: the LSM6DS3TR-C INT1 is a level, not an edge The FIFO watermark flag is a level: it stays high until the worker actually drains the FIFO below the threshold. Configuring INT1 as RISING made that a race the driver could lose permanently. lsm6ds3trc_interrupt() disables its IRQ on entry and re-enables it after the worker has run. With an edge trigger, if the line is still high when the IRQ is re-enabled -- which is precisely what happens whenever a drain does not take the FIFO below the watermark -- there is no new low-to-high transition left to detect, and the line goes mute forever. Observed as a board that serviced exactly one watermark after boot and then never again, reproducible 2 out of 2 reflashes. ONHIGH matches the physical meaning of the pin and is immune to it: a level trigger re-asserts on its own for as long as the condition holds, and the disable/enable pairing around servicing is what stops that from live-locking. Validated with more than 900 consecutive drains (~100 min) including real sleep -> GPIO-wake -> resume transitions, the exact case that used to wedge. Signed-off-by: Felipe Moura Assisted-by: Claude:claude-opus-5 --- .../esp32s3/common/src/esp32s3_board_lsm6ds3trc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/boards/xtensa/esp32s3/common/src/esp32s3_board_lsm6ds3trc.c b/boards/xtensa/esp32s3/common/src/esp32s3_board_lsm6ds3trc.c index f7588b99fcc..e4a0df016e3 100644 --- a/boards/xtensa/esp32s3/common/src/esp32s3_board_lsm6ds3trc.c +++ b/boards/xtensa/esp32s3/common/src/esp32s3_board_lsm6ds3trc.c @@ -110,13 +110,13 @@ int board_lsm6ds3trc_initialize(int devno, int busno) .attach = board_lsm6ds3trc_attach, }; - /* The IMU drives INT1 push-pull, active high by default (CTRL3_C - * H_LACTIVE reset value) -- rising edge signals data ready. No pull - * needed once the sensor drives the line, but PULLDOWN gives a defined - * idle state before CTRL registers are written during registration. + /* INT1 is a level (FIFO over watermark), not a pulse -- ONHIGH, not + * RISING, or the disable/re-enable around servicing can miss the line + * already back high and never fire again. PULLDOWN just gives a defined + * idle state before CTRL registers are written. */ - esp_configgpio(LSM6DS3TRC_IRQ_PIN, INPUT_FUNCTION_2 | PULLDOWN | RISING); + esp_configgpio(LSM6DS3TRC_IRQ_PIN, INPUT_FUNCTION_2 | PULLDOWN | ONHIGH); i2c = esp32s3_i2cbus_initialize(busno); if (i2c == NULL)