mirror of
https://github.com/apache/nuttx.git
synced 2026-10-02 19:58:01 +00:00
sensors/lsm6ds3trc: recover from a failed FIFO drain instead of wedging
A single failed burst read of FIFO_DATA_OUT was enough to take the board down. The drain path gave up on error, unlocked and returned, leaving the FIFO above its watermark. INT1 is level triggered on exactly that condition, so the line stayed asserted, the worker was re-entered the instant the IRQ was re-enabled, failed again, and that hot loop starved every other task until the board wedged -- console cut off mid-line, no crash dump. Observed killing a board within seconds of the first failure. Fix: if the read fails, empty the FIFO through Bypass and restore the previous mode bits, which deasserts INT1. That costs one batch of samples and acquisition resumes on the next watermark. Restoring the saved bits rather than recomputing them preserves the FIFO-only ODR set by fifo_configure(). Losing a batch is a far better outcome than losing the board. The underlying cause of these timeouts on esp32s3 was light sleep cutting the transfer in half; that is fixed separately in esp32s3_i2c.c. This commit is the driver recovering gracefully from a failed read whatever its cause, which it was not before. Assisted-by: Claude:claude-opus-5 Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
This commit is contained in:
parent
08ee713b4d
commit
c4c9eab46f
1 changed files with 18 additions and 3 deletions
|
|
@ -933,8 +933,23 @@ static void lsm6ds3trc_fifo_worker_body(FAR struct lsm6ds3trc_dev_s *dev)
|
|||
nwords * sizeof(int16_t));
|
||||
if (err < 0)
|
||||
{
|
||||
nxmutex_unlock(&dev->devlock);
|
||||
uint8_t ctrl5;
|
||||
|
||||
snerr("ERROR: Failed to read FIFO data: %d\n", err);
|
||||
|
||||
/* Recover instead of wedging: a FIFO left above watermark holds
|
||||
* level-triggered INT1 asserted, re-entering this worker forever.
|
||||
* Emptying it through Bypass costs one batch but deasserts the line;
|
||||
* restore the previous mode bits to keep fifo_configure()'s ODR.
|
||||
*/
|
||||
|
||||
if (lsm6ds3trc_read_bytes(dev, FIFO_CTRL5, &ctrl5, 1) >= 0)
|
||||
{
|
||||
lsm6ds3trc_set_bits(dev, FIFO_CTRL5, FIFO_MODE_BYPASS, 0x07);
|
||||
lsm6ds3trc_set_bits(dev, FIFO_CTRL5, ctrl5 & 0x07, 0x07);
|
||||
}
|
||||
|
||||
nxmutex_unlock(&dev->devlock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1726,8 +1741,8 @@ int lsm6ds3trc_register(FAR struct i2c_master_s *i2c, uint8_t addr,
|
|||
* the device at all: an unregistered sensor leaves the application
|
||||
* with no /dev/uorb/sensor_accel0 to open, which is fatal to it.
|
||||
* Losing the whole sensor to protect against a maybe-storm is the
|
||||
* wrong trade -- and it is exactly what happened on 2026-09-19, when
|
||||
* a single -EIO here took the collar down completely.
|
||||
* wrong trade -- a single -EIO here has taken a board down completely
|
||||
* before.
|
||||
*/
|
||||
|
||||
if (!reset_done)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue