FelipeMdeO opened a new pull request, #20036:
URL: https://github.com/apache/nuttx/pull/20036
## Summary
Adds optional hardware-FIFO draining to the LSM6DS3TR-C uORB driver
(`drivers/sensors/lsm6ds3trc_uorb.c`, added in #19997), as a follow-up to
that base driver.
Interrupt-driven mode currently pushes one uORB event per physical sample:
one I2C burst read and one interrupt per sample, at whatever ODR the topic
is running. That is the dominant power cost for a battery-constrained use
case that samples continuously. This PR adds a new whole-driver mode,
`CONFIG_SENSORS_LSM6DS3TRC_FIFO`, that instead drains the chip's hardware
FIFO in batches on a watermark interrupt, cutting both I2C transactions and
interrupt wakeups by roughly the configured watermark size.
The LSM6DS3TR-C's FIFO is the older ST "pattern" style (no per-sample tag
byte, unlike LSM6DSO/ISM330): `FIFO_CTRL3`'s per-sub-sensor decimation bits
choose which of gyro/accel feed the FIFO, `FIFO_CTRL5` sets one shared
FIFO-only ODR, and `FIFO_STATUS1/2`'s `DIFF_FIFO` reports how many 16-bit
words are waiting. The existing INT1 wiring is reused, switching from DRDY
(per-sample) to FTH (threshold reached) when the option is on.
Included in this PR:
- `lsm6ds3trc_fifo_configure()`: re-derives and writes decimation bits,
shared FIFO ODR, and watermark threshold from the current
gyro/accel enabled+ODR state, called from `activate()` and
`set_interval()`.
- `lsm6ds3trc_fifo_worker()`: replaces the per-sample DRDY worker under the
Kconfig guard -- reads `DIFF_FIFO`, bursts the available words (rounded
down to a whole pattern chunk, capped so a late drain can't overflow the
read buffer), and decodes each chunk into a `push_event()`, with
per-sample timestamps interpolated backwards from the ISR timestamp by
the configured ODR interval.
- A fix so `activate()` restores the last ODR explicitly requested via
`set_interval()` instead of always resetting to a hardcoded 52 Hz on
every re-activation -- previously this defeated the point of choosing a
lower ODR for power savings once FIFO mode was involved.
- Two real FIFO-correctness fixes found via register-level hardware
testing: the FIFO's data-ready write trigger only fires while *both*
sub-sensors are physically running (confirmed in the datasheet and by
register dumps), so a single-topic subscription previously left the
FIFO never accumulating data; and reconfiguring FIFO settings while
still in Continuous mode left `DIFF_FIFO` stuck reporting a stale count,
fixed by resetting through Bypass mode (which also empties the FIFO)
before writing new settings and re-entering Continuous mode last, per
the datasheet's documented procedure. Two related bit-definition bugs
(`MASK_FIFO_DIFF_HI`, `MASK_DEC_FIFO_XL`/`SHIFT_DEC_FIFO_GY`) were also
fixed against the real ST datasheet rather than the in-tree `lsm6dsl.h`
header the original driver was ported from.
- A documented, deliberately-not-"fixed" chip quirk: `DIFF_FIFO` reads 0
at the exact moment a real overrun occurs, even though the FIFO is still
full of valid data. This matches ST's own guidance for this chip family
and mainline Linux's `st_lsm6dsx` driver, which doesn't attempt to
recover from it either.
- Documentation additions covering FIFO mode and its three limitations:
both sub-sensors forced to the same ODR, temperature no longer
per-sample (one read per drain applied to the whole batch), and both
sub-sensors must stay physically enabled regardless of subscription.
## Impact
- No impact on existing users: `CONFIG_SENSORS_LSM6DS3TRC_FIFO` defaults
to `n`, and only takes effect for boards that already register this
driver with a real interrupt `attach()` (silently unused in kthread
polling mode).
- `boards/xtensa/esp32s3/esp32s3-xiao` (the only board currently using
this driver) is unaffected unless its defconfig opts in.
- New Kconfig option `SENSORS_LSM6DS3TRC_FIFO_WATERMARK` (default 8
samples) controls the batch size; its help text notes the relationship
to the accel/gyro uORB ring buffer sizes.
- Documentation-only addition otherwise
(`Documentation/components/drivers/special/sensors/lsm6ds3trc.rst`).
## Testing
**Host:** Linux, xtensa-esp32s3-elf toolchain.
**Board:** Seeed XIAO ESP32-S3, LSM6DS3TR-C over I2C, interrupt-driven mode
(shared INT1 pin, per the driver's existing single-IRQ design).
- Bench-validated on hardware, both FIFO pattern widths:
- Both `sensor_accel0`/`sensor_gyro0` topics subscribed (6-word
pattern) and accel-only (3-word pattern): samples arrive in
watermark-sized bursts, interpolated timestamps spaced by the exact
configured ODR interval (52 Hz -> 19230 us between consecutive
samples, matched exactly), sane accel/gyro values, no I2C errors, no
overruns, sustained for 15+ seconds of continuous streaming.
- Accel-only and gyro-only single-topic subscriptions confirmed to
drain correctly after the write-trigger fix (previously silently
never accumulated data).
- Re-activation after `set_interval()` confirmed to resume at the
previously requested ODR instead of resetting to 52 Hz.
- Deliberate FIFO overrun test: ~7.80 s to fill+overrun both topics at
52 Hz, ~324 samples lost per trial if left unread that long --
consistent with a healthy design given the default watermark drains
roughly every 150 ms in real use.
--
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]