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]

Reply via email to