FelipeMdeO opened a new pull request, #19601:
URL: https://github.com/apache/nuttx/pull/19601
# Título
```
drivers/sensors/mpu6050: deliver samples from the data ready interrupt
```
# Corpo
## Summary
The MPU6050 driver only implemented `fetch()`, so samples were read on
demand: timestamped when the application asked rather than when the device
measured, with the scheduler's jitter baked in, and with accelerometer and
gyroscope coming from two separate I2C reads so the two topics were never
sampled at the same instant. The part has an INT pin and a data ready
interrupt; nothing used them.
Four commits:
1. **Factor out the register decoding.** The expression converting a big
endian register pair appeared seven times, each with a cast to `int16_t`,
which is load bearing, and one to `float`, which is not. Two helpers, no
functional change; the rest of the series builds on them.
2. **Optional push mode behind `CONFIG_SENSORS_MPU6050_INT`.** The board
supplies `mpu6050_config_s::attach` to wire the INT pin; the handler
timestamps and defers to HPWORK, and the worker reads the device once
and pushes both topics facrom that single sample. The I2C read cannot run
in the interrupt, hence the work queue. An instance exposes one model or
the other, never both: with the option enabled the ops table has no
`fetch()`, which is the mixture that made `poll()` unusable on l3gd20
(apache/nuttx#19596). A board that enables the option without supplying
`attach` is misconfigured, so registration fails with `-EINVAL` rather
than silently falling back.
3. **Configure the DLPF so `SMPLRT_DIV` means what it says.** The sample
rate is the gyroscope output rate divided by `1 + SMPLRT_DIV`, and that
output is 1 kHz only while the DLPF is enabled. `CONFIG` was left at its
0 reset value, which disables the DLPF and puts the output at 8 kHz, so
the divider of 9 gave 800 Hz rather than the intended 100 Hz. `fetch()`
hid this because the application set the pace and simply read the most
recent sample; the interrupt made the real rate visible.
4. **Update the driver documentation** for the new registration signature
and the two acquisition modes.
## Impact
Boards that wire the INT pin get samples timestamped at acquisition, both
topics sampled from the same read, and one I2C transaction per sample
instead of one per `read()`. Boards that do not wire it are unaffected:
the option defaults to `n` and the `fetch()` path is unchanged. The DLPF
fix applies to both modes and corrects the configured rate to the 100 Hz
the code already documented, additionally giving the anti-alias filtering
that a 100 Hz sampler should have.
## Testing
Host: Ubuntu 24.04.3 LTS. `checkpatch.sh` (style + `-m` commit messages)
clean on all four commits.
**Compiles clean** in both modes — `sim` (x86_64) with
`CONFIG_SENSORS_MPU6050_INT` on and off, and xtensa-esp-elf-gcc 14.2.0 for
the hardware runs below. The refactor was re-verified on hardware after the
fact: same 101 Hz and no duplicates, so it is behaviour neutral as claimed.
**On hardware** — ESP32-S3-DevKitC + MPU6050 (GY-521), I2C0 on
SDA GPIO5 / SCL GPIO4, INT on GPIO6. The board glue providing `attach()`
for that target is not part of this PR.
Sample rate, measured over 100 samples of `uorb_listener sensor_accel0`,
before and after the DLPF commit:
| | rate | consecutive duplicate samples |
|---|---|---|
| before | 833 Hz | 36 of 100 |
| after | 101 Hz | 0 of 100 |
The duplicates before the fix are the worker being re-triggered faster than
the device produced new data. After it, every interrupt yields a fresh
sample at the intended rate.
Both topics from one interrupt, note the shared timestamp:
```
nsh> uorb_listener -n 6 sensor_accel0,sensor_gyro0
Monitor objects num:2
object_name:sensor_gyro, object_instance:0
object_name:sensor_accel, object_instance:0
sensor_gyro(now:72560000):timestamp:72560000,x:2.424675,y:0.108184,z:0.039836,temperature:22.394705
sensor_accel(now:72560000):timestamp:72560000,x:0.790087,y:1.301249,z:10.234015,temperature:22.394705
sensor_gyro(now:72570000):timestamp:72570000,x:-0.380109,y:0.310962,z:0.613530,temperature:23.668234
sensor_accel(now:72570000):timestamp:72570000,x:0.776918,y:1.278504,z:10.190920,temperature:23.668234
sensor_gyro(now:72580000):timestamp:72580000,x:-0.024781,y:0.089131,z:0.303501,temperature:23.682940
sensor_accel(now:72580000):timestamp:72580000,x:0.785298,y:1.274912,z:10.144233,temperature:23.682940
Object name:sensor_gyro0, received:3
Object name:sensor_accel0, received:3
Total number of received Message:6/6
```
**Teardown**: 8 rounds of `uorb_listener -r 5 sensor_accel0 &` followed by
`SIGINT` mid-poll. `ps` afterward shows no leaked task and an idle `hpwork`
thread, and `uorb_listener -n 3 sensor_accel0` right after still completes
3/3 — the interrupt is disabled when the last subscriber leaves and
re-enabled when one returns.
--
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]