Skip to content

feat(imu, gpio)!: Add Timestamped BMI088 telemetry & digital read support#54

Merged
qzhhhi merged 3 commits into
mainfrom
dev/imuheat
May 13, 2026
Merged

feat(imu, gpio)!: Add Timestamped BMI088 telemetry & digital read support#54
qzhhhi merged 3 commits into
mainfrom
dev/imuheat

Conversation

@qzhhhi
Copy link
Copy Markdown
Member

@qzhhhi qzhhhi commented May 6, 2026

feat(firmware/rmcs_board): Add MCHTMR-based timestamp service for rmcs_board

  • Replace the GPTMR1 tick helper with an MCHTMR-backed timer service that keeps the 1 kHz LED heartbeat while exposing quarter-microsecond timestamps for later board events.
  • Move lite and pro board clock setup to a fixed 4 MHz mchtmr time base so timestamp_quarter_us() has a stable unit contract across both rmcs_board variants.
  • Remove board-specific GPTMR tick IRQ plumbing in favor of the shared machine-timer ISR path to prepare rmcs_board for timestamped sensor and GPIO reporting.

feat(imu)!: Add Timestamped BMI088 telemetry and remove invalid host IMU transmit APIs

  • Extend the shared IMU protocol and host callback pipeline with quarter-microsecond timestamps for accelerometer and gyroscope samples, and add a dedicated temperature payload.
  • Rework the c_board and rmcs_board BMI088 paths to latch capture-time timestamps, defer SPI reads through a shared pending-read service, and preserve board-side sampling time in uplink telemetry.
  • Add BMI088 temperature telemetry on both firmware boards, carrying the raw temperature register value plus board-side timestamp through the typed IMU pipeline.
  • Remove the host-side IMU transmit builders because IMU traffic is firmware-originated telemetry only and the existing host transmit API was both invalid and unused.

BREAKING CHANGE: IMU accelerometer and gyroscope payloads now carry timestamps, a new temperature IMU payload is emitted, host callback implementations must handle temperature_receive_callback(), and the public host IMU transmit helpers have been removed.

feat(gpio)!: Add Timestamped digital read support

  • Extend GPIO read configuration with capture_timestamp and add an optional timestamp field to digital read results so host consumers can align GPIO events with board-side IMU telemetry.
  • Update the GPIO wire format to encode timestamped digital read requests and results, move pull configuration into the read payload, and widen period_ms storage to 16 bits.
  • Implement timestamp capture for ASAP, periodic, and interrupt-driven digital reads in both c_board and rmcs_board while keeping analog read and write paths explicitly non-timestamped.

BREAKING CHANGE: GPIO read-config packets use a new wire layout and timestamped digital read results may include an additional 32-bit timestamp payload.

PR 摘要:新增 BMI088 温度与时间戳支持、GPIO 时间戳与定时器重构(dev/imuheat → main)

概述

本 PR 为固件与主机协议引入四分之一微秒(quarter-µs)级时间戳支持,并新增 BMI088 温度传感器采集与上报。为保证一致性与高分辨率时间戳,替换与统一了板级定时器实现(MCHTMR 4 MHz 基准),并将 BMI088 驱动改为“中断捕获 → pending → service”延迟读取模式。协议、序列化/反序列化与数→据视图、主机回调链均相应扩展;若主机或固件未配套更新,将导致协议不兼容。

主要变更点

  • core(协议与数据结构)

    • 为 AccelerometerDataView、GyroscopeDataView、TemperatureDataView 添加 timestamp_quarter_us 字段。
    • 为 GpioDigitalDataView 增加可选 timestamp_quarter_us(std::optional<uint32_t>),并在 GpioReadConfigView 增加 capture_timestamp 标志;当 capture_timestamp 为真时,要求设备具备 spec::GpioCapability::kTimestampedDigitalRead。
    • 在 GpioCapability 中增加 kTimestampedDigitalRead 并并入 kDigitalCapabilities。
    • 在 DataCallback / DeserializeCallback 中新增温度回调 temperature_receive_callback / temperature_deserialized_callback。
    • 协议位域调整:GpioHeader 增加 Timestamped 标志;GpioReadConfigPayload 将 pull 字段移入 payload、period_ms 扩为 16 位;新增 GpioDigitalReadTimestampPayload;IMU payload 新增 kTemperature,Accelerometer/Gyroscope/Temperature payload 均加入 TimestampQuarterUs。
    • Serializer/Deserializer 更新以支持 timestamped 数字读写与 IMU 温度/时间戳的序列化解析,并在不支持组合(如模拟读取带时间戳、边沿标志冲突)时拒绝。
  • 固件(rmcs_board 与 c_board)

    • 定时器与板级时钟:
      • 新增 MCHTMR-backed 高分辨率 Timer(timer.hpp/.cpp),提供 timestamp_quarter_us() / timestamp64_quarter_us()(32/64 位),并保持 1 kHz LED 心跳。
      • 统一 lite/pro 板的 MCHTMR 时钟基准为 4 MHz(mchtmr0 divider 从 1 → 6)。
      • 移除旧的 tick_clock 接口与实现,改由 shared machine-timer ISR 转发给新 timer。
    • BMI088 驱动:
      • 加速计/陀螺仪:data_ready_callback 改为接收 capture_timestamp_quarter_us,使用 InterruptLockGuard + 原子量管理 pending/active 时间戳;新增 service_pending_read(),在实际发起 SPI 读取时将 pending 时间戳设为 active;在 SPI RX 回调中消费 active 时间戳并随样本上报。
      • 新增 Temperature 驱动(c_board 与 rmcs_board 均实现):周期性 probe、GPTMR1/定时器 ISR 驱动、读取时记录“launch”时间戳、RX 完成后解析原始寄存器并上报(含时间戳),并实现基于变化的立即上报与心跳限频。
      • 新增 bmi088 service_pending_reads() 协调函数:按顺序服务 gyro → accel → temperature 的 pending 读取。
      • 在 IRQ/EXTI 路径与 SPI 中断处理处采集并传递 capture_timestamp_quarter_us,App::run 增加对 BMI088 pending/probe 服务的调度调用。
    • GPIO 驱动:
      • 数字输入采样可选记录时间戳:ChannelState 增加 capture_timestamp,publish_digital_input_sample 改为接收 (channel_index, high, timestamp_quarter_us),条件性以 std::optional<uint32_t> 序列化时间戳;ASAP、周期、边沿中断路径均支持时间戳采集;模拟读/写仍不支持时间戳(会被拒绝)。
      • 部分实现从旧 tick API 切换为新 timer 的 timestamp64_quarter_us()。
  • 主机端(host)

    • 在各 Agent(c_board、rmcs_board_lite、rmcs_board_pro)添加 temperature_receive_callback 覆盖(当前为空实现以保持兼容)。
    • 在 protocol Handler 中新增 temperature_deserialized_callback 的转发实现。
    • 移除 Handler::PacketBuilder 中用于构造 IMU 发包的 host-side 写入器 write_imu_accelerometer 与 write_imu_gyroscope(IMU 采样现在由固件发起为 telemetry)。

破坏性更改与兼容性注意

  • 协议位域与载荷布局被修改(GPIO 与 IMU payload/header),序列化格式有变。必须同时更新固件与主机端以避免互操作失败。
  • IMU 加速度计/陀螺仪数据包现在包含时间戳;新增温度 IMU payload;主机需实现 temperature_receive_callback();主机侧用于发送 IMU 数据的 PacketBuilder 写入方法已移除。
  • GPIO read-config 的线下布局改变,timestamped digital read 结果可能包含额外 32 位时间戳,pull 配置项移入 read payload,period_ms 扩宽为 16 位。

建议审阅重点

  • protocol.hpp / serializer / deserializer 的位域定义与验证逻辑是否一致且健壮(尤其 timestamp 标志与 analog/read 组合的拒绝路径)。
  • BMI088 accel/gyro pending/active timestamp 的中断保护、原子操作与竞态条件处理(无丢失、重入安全)。
  • Timer 的 64 位稳定读取(high–low–high 重试)与 ISR 编排、板级时钟分频在不同板型的统一性与 LED 心跳保持。
  • service_pending_reads() 的调度顺序与 SPI 总线竞争(CS 管理)是否安全。
  • 主机适配工作:移除的 PacketBuilder 接口对上层调用方的影响与 temperature 回调的使用点。

影响范围(主要文件/组件)

  • core:data/datas.hpp、spec/gpio.hpp、protocol/{protocol.hpp,serializer.hpp,deserializer.*} 等多处修改。
  • firmware:rmcs_board 与 c_board 的 timer、GPIO、spi/bmi088(accel/gyro/temperature/service)、board clock 配置与多处 IRQ/ISR 改动。
  • host:Agent 回调扩展、protocol Handler 调整与 PacketBuilder 写入方法移除。

(注:PR 评论区仅含重复的自动触发/暂停评审命令与 bot 回复,无人工代码审查评论。)

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

为数据通路引入可选与每样本时间戳,扩展协议/序列化/反序列化与数据视图;将 BMI088 IMU 驱动改为中断锚定 + 延迟读以携带时间戳;新增高精度 Timer 并调整板级时钟与 ISR 集成;添加 BMI088 温度驱动与服务编排;主机与 Vendor/Agent 层新增温度回调占位。

Changes

数据契约、协议与序列化/反序列化

Layer / File(s) Summary
数据契约与回调
core/include/librmcs/data/datas.hpp
新增 GpioDigitalDataView::timestamp_quarter_usstd::optional<uint32_t>)、GpioReadConfigView::capture_timestamp、Accelerometer/Gyroscope/Temperature 的 timestamp_quarter_us 字段,并新增 DataCallback::temperature_receive_callback
GPIO 能力位
core/include/librmcs/spec/gpio.hpp
新增 GpioCapability::kTimestampedDigitalRead 并将其并入 kDigitalCapabilities
协议位域
core/src/protocol/protocol.hpp
GpioHeader 增加 Timestamped 位;GpioReadConfigPayload 扩展并加入 Pull 字段;新增 GpioDigitalReadTimestampPayload;IMU payload 扩展以包含 TimestampQuarterUs 并新增 kTemperature
序列化/尺寸与校验
core/src/protocol/serializer.hpp
GPIO 与 IMU 写入路径更新以条件序列化时间戳(数字读结果可选时间戳)、新增温度序列化、并调整 required_gpio_size / required_imu_size 大小计算与校验;写入路径在不允许时拒绝 timestamp。
反序列化与回调派发
core/src/protocol/deserializer.hpp, core/src/protocol/deserializer.cpp
解析并验证 GPIO/IMU 的 timestamp 字段(在不允许时拒绝特定载荷),DeserializeCallback 新增 temperature_deserialized_callback,并在反序列化链中新增温度分支调用。

BMI088 驱动、服务与上行流程

Layer / File(s) Summary
驱动中断到待处理流(加速/陀螺)
firmware/*/spi/bmi088/accel.hpp, firmware/*/spi/bmi088/gyro.hpp, `firmware//spi/bmi088/.(cpp
hpp)`
BMI088 温度驱动与编排
firmware/*/spi/bmi088/temperature.*, firmware/*/spi/bmi088/service.hpp
新增 Temperature 类:GPTMR 定时探测、异步 SPI 读、在 SPI 发起时锚定 launch timestamp、RX 回调解析原始寄存器并按中点/心跳策略上报温度;新增 service_pending_reads() 以 gyro→accel→temperature 顺序服务。
IRQ 与应用集成
firmware/*/app/src/app.cpp, firmware/*/spi/*/accel.cpp, .../gyro.cpp, .../spi.cpp
IRQ 处理在触发时读取 Timer 时间并传入 data_ready_callback(timestamp),IRQ 后或主循环中调用 service_pending_reads() 并轮询 temperature 探测。
固件/主机回调占位
firmware/*/usb/vendor.hpp, host/include/*, host/src/protocol/handler.cpp
在 Vendor/Agent/Handler 层添加或转发 temperature 接收回调(当前为 no-op);移除/调整 Handler::PacketBuilder 中原有部分 IMU 写入声明以匹配序列化变更。

GPIO 输入采样与可选时间戳

Layer / File(s) Summary
固件 GPIO 发布路径
firmware/*/gpio/gpio.hpp, firmware/*/gpio/gpio.cpp
在 ASAP / 周期 / 边沿中断路径捕获 pin level 与 quarter-microsecond 时间戳,新增 ChannelState::capture_timestamp 并通过配置传递;publish_digital_input_sample 改为带 (channel, high, timestamp_quarter_us),且基于 capture_timestamp 使用 std::optional<uint32_t> 条件序列化。

高精度 Timer 与板级时钟调整

Layer / File(s) Summary
新增高精度 Timer
firmware/rmcs_board/app/src/timer/timer.hpp, .../timer.cpp
新增 Timer 类与全局 timer 实例:MCHTMR 初始化、IRQ 转发、tick 维护以及 timestamp_quarter_us()/timestamp64_quarter_us() 方法,供 IRQ/驱动采样使用。
移除旧 Tick 与板级改动
firmware/rmcs_board/app/src/timer/tick.*, firmware/rmcs_board/boards/*/*, firmware/rmcs_board/boards/*/board.c
删除旧 Tick 实现与其 ISR,移除 BOARD_TICK_CLOCK 接口;板级 board.cmchtmr0 分频从 1→6(约 24MHz→4MHz)以配合新定时方案。
sequenceDiagram
    autonumber
    participant IRQ as BMI088 IRQ
    participant Timer as Timer (MCHTMR)
    participant Driver as BMI088 Driver
    participant Service as service_pending_reads
    participant SPI as SPI Controller
    participant Serializer as USB Serializer
    participant Host as Host/Deserializer

    IRQ->>Timer: 读取 timestamp_quarter_us()
    Timer-->>IRQ: 返回 timestamp
    IRQ->>Driver: data_ready_callback(timestamp)
    Driver->>Driver: 存储 pending timestamp (InterruptLockGuard)
    IRQ->>Service: service_pending_reads()
    Service->>Driver: service_pending_read()(按优先级)
    Driver->>SPI: 发起异步 SPI 读取(锚定 launch timestamp)
    SPI-->>Driver: transmit_receive_async_callback(rx_buf)
    Driver->>Driver: 原子消费 active timestamp
    Driver->>Serializer: handle_uplink(data, active_timestamp)
    Serializer->>Host: 发送带 timestamp 的包(IMU/Temperature)
    Host->>Host: 反序列化并调用相应回调(含 temperature)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐰
我在四分之一微秒里轻跃,
把引脚的心跳与温度的脉搏记下,
中断锚定时间,SPI 将故事送出,
小兔把时间缝进每个包裹里。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.93% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main changes: adding timestamped BMI088 telemetry and digital GPIO read support with breaking changes indicated by the exclamation mark.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/imuheat

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 6, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

✅ Actions performed

Full review triggered.

@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 6, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

✅ Actions performed

Full review triggered.

@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 12, 2026

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

✅ Actions performed

Reviews paused.

@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 12, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
firmware/c_board/app/src/gpio/gpio.hpp (1)

62-68: ⚡ Quick win

统一 ASAP/周期采样的取时顺序。

这两条路径现在都是先读电平再取时,而中断路径是先取时再读电平。既然这次改动的重点是“采样时间戳”,这里最好统一成先取时,避免把额外的 HAL 调用延迟算进时间戳里。

✏️ 建议修改
         if (data.asap) {
             const auto& hardware = channel_hardware(channel_index);
-            const bool high =
-                HAL_GPIO_ReadPin(hardware.gpio_port, hardware.gpio_pin) == GPIO_PIN_SET;
             const uint32_t timestamp_quarter_us = current_timestamp_quarter_us();
+            const bool high =
+                HAL_GPIO_ReadPin(hardware.gpio_port, hardware.gpio_pin) == GPIO_PIN_SET;
             publish_digital_input_sample(channel_index, high, timestamp_quarter_us);
         }
@@
             const auto& hardware = channel_hardware(static_cast<uint8_t>(channel_index));
-            const bool high =
-                HAL_GPIO_ReadPin(hardware.gpio_port, hardware.gpio_pin) == GPIO_PIN_SET;
             const uint32_t timestamp_quarter_us = current_timestamp_quarter_us();
+            const bool high =
+                HAL_GPIO_ReadPin(hardware.gpio_port, hardware.gpio_pin) == GPIO_PIN_SET;
             publish_digital_input_sample(
                 static_cast<uint8_t>(channel_index), high, timestamp_quarter_us);

Also applies to: 81-86

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@firmware/c_board/app/src/gpio/gpio.hpp` around lines 62 - 68, ASAP and
periodic sampling paths currently read the GPIO level before capturing the
timestamp; change both paths (the block using channel_hardware(),
HAL_GPIO_ReadPin(), current_timestamp_quarter_us(), and
publish_digital_input_sample()) to capture timestamp first by calling
current_timestamp_quarter_us() before HAL_GPIO_ReadPin(), then pass the
timestamp and the read level into publish_digital_input_sample to match the
interrupt path ordering and avoid counting HAL call latency in the sample
timestamp.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@core/include/librmcs/spec/gpio.hpp`:
- Line 35: The enum bitmask expression containing GpioCapability::kPullUp |
GpioCapability::kPullDown | GpioCapability::kTimestampedDigitalRead exceeds the
100-column limit; split this expression across multiple lines (for example break
after kPullUp and/or kPullDown so each line is <100 cols) in the file around the
GpioCapability usage to satisfy the 100-column width rule and run
clang-format-check to ensure formatting compliance.

In `@firmware/c_board/app/src/spi/bmi088/temperature.hpp`:
- Around line 47-58: 在 service_pending_read() 中把用于 SPI 启动锚点的时间戳采样移动到调用
read_async(...) 之前:在调用 read_async(RegisterAddress::kTempMsb,
kTemperatureReadSizeBytes) 之前即时采样
timer::timer->timepoint().time_since_epoch().count() 并存入
active_probe_launch_timestamp_quarter_us_,然后按当前语义用
has_active_probe_launch_timestamp_.store(..., std::memory_order_release)
标记存在;随后调用 read_async 并按原来逻辑在成功后将 probe_pending_ 置为 false。保持现有的 memory_order
顺序与逻辑不变。

In `@firmware/rmcs_board/app/src/app.cpp`:
- Around line 44-48: 将 timer::timer.init() 提前到所有 BMI088 初始化之前:在启动序列中先调用
timer::timer.init(),然后再依次调用 spi::bmi088::accelerometer.init(),
spi::bmi088::gyroscope.init(), spi::bmi088::temperature.init(),以确保 IRQ
回调中读取时间戳时定时器已就绪;同时检查 timer::timer.init() 的返回/错误处理并保留现有 IMU 初始化顺序与逻辑。

In `@firmware/rmcs_board/app/src/spi/bmi088/temperature.hpp`:
- Around line 59-69: service_pending_read() currently calls read_async(...)
before recording the SPI launch timestamp, which makes the timestamp include
read_async()'s execution delay and contradicts the comment; move the lines that
set active_probe_launch_timestamp_quarter_us_.store(...) and
has_active_probe_launch_timestamp_.store(...) to just before the
read_async(RegisterAddress::kTempMsb, kTemperatureReadSizeBytes) call (keeping
the same timer::Timer::timestamp_quarter_us() and memory orders) so the
timestamp is captured at SPI launch time while still under the
utility::InterruptLockGuard.

In `@firmware/rmcs_board/app/src/timer/timer.hpp`:
- Around line 45-47: The function timestamp_quarter_us() uses reinterpret_cast
to treat HPM_MCHTMR->MTIME as a volatile uint32_t pointer which risks
strict-aliasing and endianness issues; instead read the register as its actual
type and then static_cast/truncate to uint32_t. Update timestamp_quarter_us() to
read the volatile 64-bit MTIME (use the symbol HPM_MCHTMR->MTIME) into a
volatile uint64_t or by accessing it as its defined type, then return
static_cast<uint32_t>(value) to produce the lower 32 bits, removing the
reinterpret_cast usage.

---

Nitpick comments:
In `@firmware/c_board/app/src/gpio/gpio.hpp`:
- Around line 62-68: ASAP and periodic sampling paths currently read the GPIO
level before capturing the timestamp; change both paths (the block using
channel_hardware(), HAL_GPIO_ReadPin(), current_timestamp_quarter_us(), and
publish_digital_input_sample()) to capture timestamp first by calling
current_timestamp_quarter_us() before HAL_GPIO_ReadPin(), then pass the
timestamp and the read level into publish_digital_input_sample to match the
interrupt path ordering and avoid counting HAL call latency in the sample
timestamp.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f09c1e53-6ea9-464e-bf9e-1a5734b66bb0

📥 Commits

Reviewing files that changed from the base of the PR and between 3f5a34d and 96d3557.

📒 Files selected for processing (40)
  • core/include/librmcs/data/datas.hpp
  • core/include/librmcs/spec/gpio.hpp
  • core/src/protocol/deserializer.cpp
  • core/src/protocol/deserializer.hpp
  • core/src/protocol/protocol.hpp
  • core/src/protocol/serializer.hpp
  • firmware/c_board/app/src/app.cpp
  • firmware/c_board/app/src/gpio/gpio.cpp
  • firmware/c_board/app/src/gpio/gpio.hpp
  • firmware/c_board/app/src/spi/bmi088/accel.hpp
  • firmware/c_board/app/src/spi/bmi088/gyro.hpp
  • firmware/c_board/app/src/spi/bmi088/service.hpp
  • firmware/c_board/app/src/spi/bmi088/temperature.hpp
  • firmware/c_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/app/src/app.cpp
  • firmware/rmcs_board/app/src/gpio/gpio.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/accel.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/accel.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/gyro.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/gyro.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/service.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/temperature.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/temperature.hpp
  • firmware/rmcs_board/app/src/spi/spi.cpp
  • firmware/rmcs_board/app/src/timer/tick.cpp
  • firmware/rmcs_board/app/src/timer/tick.hpp
  • firmware/rmcs_board/app/src/timer/timer.cpp
  • firmware/rmcs_board/app/src/timer/timer.hpp
  • firmware/rmcs_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/boards/lite/app/board_app.cpp
  • firmware/rmcs_board/boards/lite/app/board_app.hpp
  • firmware/rmcs_board/boards/lite/board.c
  • firmware/rmcs_board/boards/pro/app/board_app.cpp
  • firmware/rmcs_board/boards/pro/app/board_app.hpp
  • firmware/rmcs_board/boards/pro/board.c
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
  • host/include/librmcs/protocol/handler.hpp
  • host/src/protocol/handler.cpp
💤 Files with no reviewable changes (7)
  • host/include/librmcs/protocol/handler.hpp
  • firmware/rmcs_board/app/src/timer/tick.cpp
  • firmware/rmcs_board/boards/lite/app/board_app.cpp
  • firmware/rmcs_board/boards/lite/app/board_app.hpp
  • firmware/rmcs_board/app/src/timer/tick.hpp
  • firmware/rmcs_board/boards/pro/app/board_app.hpp
  • firmware/rmcs_board/boards/pro/app/board_app.cpp

Comment thread core/include/librmcs/spec/gpio.hpp
Comment thread firmware/c_board/app/src/spi/bmi088/temperature.hpp
Comment thread firmware/rmcs_board/app/src/app.cpp Outdated
Comment thread firmware/rmcs_board/app/src/spi/bmi088/temperature.hpp
Comment thread firmware/rmcs_board/app/src/timer/timer.hpp
@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 13, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@qzhhhi qzhhhi changed the title Dev/imuheat feat(imu, gpio)!: Add Timestamped BMI088 telemetry & digital read support May 13, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@firmware/c_board/app/src/spi/bmi088/temperature.hpp`:
- Around line 74-80: The code currently only checks size != 0 and relies on
assert_debug, which doesn't prevent out-of-bounds reads from spi_.rx_buffer when
a short/invalid SPI frame arrives; before calling parse_raw_temperature or
indexing rx_buffer, add a runtime check that size >= the expected full frame
length (the number of bytes parse_raw_temperature/readers access, e.g.
kDummyBytes + 2 or whatever parse_raw_temperature requires) and return early if
the length is insufficient; replace the fragile assert_debug path with this
guard around the block that calls parse_raw_temperature and handle_uplink (same
change also applied to the analogous block around lines 88-94), referencing
parse_raw_temperature, spi_.rx_buffer, size, has_active_probe_launch_timestamp,
and handle_uplink to locate the code.
- Around line 36-45: In poll_pending_probe(), move the timestamp sample inside
the critical section so the computed now is consistent with the locked
check/update: acquire the utility::InterruptLockGuard first (i.e. construct
guard before sampling now), then call timer::timer->timepoint() and use that
value for the check timer::timer->check_reached(next_probe_deadline_) and for
setting next_probe_deadline_ = now + kProbePeriod; keep the existing
checks/assignments to probe_pending_ and next_probe_deadline_ but ensure now is
computed after the guard is taken to avoid ISR races.

In `@firmware/rmcs_board/app/src/spi/bmi088/temperature.cpp`:
- Line 28: The interrupt handler dereferences the global pointer
spi::bmi088::temperature without protection, which can HardFault if the
component isn't initialized; before calling timer_callback, copy
spi::bmi088::temperature to a local pointer, check it for null, and only then
invoke its timer_callback method (ensure the check-and-call happens atomically
from the ISR perspective to avoid TOCTOU races and that timer_callback is
ISR-safe).

In `@firmware/rmcs_board/app/src/timer/timer.hpp`:
- Line 51: timestamp64_quarter_us() reads the 64-bit MMIO HPM_MCHTMR->MTIME
directly which can tear on RV32; change it to either (A) implement a
read-compare-retry sequence that reads low32, high32, then re-reads low32 and
retries on mismatch to produce an atomic 64-bit value, or (B) remove/mark as
unsafe and have callers use timestamp_quarter_us() (which returns the safe
single 32-bit low half) instead; also ensure any SDK helper like
mchtmr_get_count() follows the same read-compare-retry pattern if a full 64-bit
count is required.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 75ccf36d-a04c-406a-ac71-32b57d89b9d7

📥 Commits

Reviewing files that changed from the base of the PR and between 96d3557 and 086c062.

📒 Files selected for processing (40)
  • core/include/librmcs/data/datas.hpp
  • core/include/librmcs/spec/gpio.hpp
  • core/src/protocol/deserializer.cpp
  • core/src/protocol/deserializer.hpp
  • core/src/protocol/protocol.hpp
  • core/src/protocol/serializer.hpp
  • firmware/c_board/app/src/app.cpp
  • firmware/c_board/app/src/gpio/gpio.cpp
  • firmware/c_board/app/src/gpio/gpio.hpp
  • firmware/c_board/app/src/spi/bmi088/accel.hpp
  • firmware/c_board/app/src/spi/bmi088/gyro.hpp
  • firmware/c_board/app/src/spi/bmi088/service.hpp
  • firmware/c_board/app/src/spi/bmi088/temperature.hpp
  • firmware/c_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/app/src/app.cpp
  • firmware/rmcs_board/app/src/gpio/gpio.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/accel.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/accel.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/gyro.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/gyro.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/service.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/temperature.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/temperature.hpp
  • firmware/rmcs_board/app/src/spi/spi.cpp
  • firmware/rmcs_board/app/src/timer/tick.cpp
  • firmware/rmcs_board/app/src/timer/tick.hpp
  • firmware/rmcs_board/app/src/timer/timer.cpp
  • firmware/rmcs_board/app/src/timer/timer.hpp
  • firmware/rmcs_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/boards/lite/app/board_app.cpp
  • firmware/rmcs_board/boards/lite/app/board_app.hpp
  • firmware/rmcs_board/boards/lite/board.c
  • firmware/rmcs_board/boards/pro/app/board_app.cpp
  • firmware/rmcs_board/boards/pro/app/board_app.hpp
  • firmware/rmcs_board/boards/pro/board.c
  • host/include/librmcs/agent/c_board.hpp
  • host/include/librmcs/agent/rmcs_board_lite.hpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
  • host/include/librmcs/protocol/handler.hpp
  • host/src/protocol/handler.cpp
💤 Files with no reviewable changes (7)
  • firmware/rmcs_board/boards/lite/app/board_app.cpp
  • firmware/rmcs_board/app/src/timer/tick.cpp
  • firmware/rmcs_board/boards/lite/app/board_app.hpp
  • host/include/librmcs/protocol/handler.hpp
  • firmware/rmcs_board/app/src/timer/tick.hpp
  • firmware/rmcs_board/boards/pro/app/board_app.hpp
  • firmware/rmcs_board/boards/pro/app/board_app.cpp
✅ Files skipped from review due to trivial changes (2)
  • firmware/c_board/app/src/usb/vendor.hpp
  • firmware/rmcs_board/boards/pro/board.c
🚧 Files skipped from review as they are similar to previous changes (22)
  • host/include/librmcs/agent/c_board.hpp
  • core/include/librmcs/spec/gpio.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/service.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/accel.cpp
  • firmware/rmcs_board/boards/lite/board.c
  • firmware/c_board/app/src/app.cpp
  • firmware/c_board/app/src/spi/bmi088/service.hpp
  • core/src/protocol/deserializer.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/accel.hpp
  • firmware/rmcs_board/app/src/usb/vendor.hpp
  • core/src/protocol/protocol.hpp
  • firmware/c_board/app/src/gpio/gpio.cpp
  • host/include/librmcs/agent/rmcs_board_pro.hpp
  • firmware/rmcs_board/app/src/gpio/gpio.hpp
  • host/src/protocol/handler.cpp
  • core/src/protocol/deserializer.cpp
  • firmware/rmcs_board/app/src/spi/bmi088/gyro.hpp
  • firmware/rmcs_board/app/src/spi/bmi088/temperature.hpp
  • core/include/librmcs/data/datas.hpp
  • core/src/protocol/serializer.hpp
  • firmware/c_board/app/src/spi/bmi088/accel.hpp
  • firmware/c_board/app/src/gpio/gpio.hpp

Comment thread firmware/c_board/app/src/spi/bmi088/temperature.hpp
Comment thread firmware/c_board/app/src/spi/bmi088/temperature.hpp
Comment thread firmware/rmcs_board/app/src/spi/bmi088/temperature.cpp
Comment thread firmware/rmcs_board/app/src/timer/timer.hpp Outdated
qzhhhi added 2 commits May 13, 2026 08:17
…s_board

- Replace the GPTMR1 tick helper with an MCHTMR-backed timer service that keeps the 1 kHz LED heartbeat while exposing quarter-microsecond timestamps with a retry-safe 64-bit MTIME read for later board events.
- Move lite and pro board clock setup to a fixed 4 MHz mchtmr time base so timestamp_quarter_us() has a stable unit contract across both rmcs_board variants.
- Remove board-specific GPTMR tick IRQ plumbing in favor of the shared machine-timer ISR path to prepare rmcs_board for timestamped sensor and GPIO reporting.
…IMU transmit APIs

- Extend the shared IMU protocol and host callback pipeline with quarter-microsecond timestamps for accelerometer and gyroscope samples, and add a dedicated temperature payload.
- Rework the c_board and rmcs_board BMI088 paths to latch capture-time timestamps, defer SPI reads through a shared pending-read service, and preserve board-side sampling time in uplink telemetry.
- Add BMI088 temperature telemetry on both firmware boards, carrying the raw temperature register value plus board-side timestamp through the typed IMU pipeline.
- Remove the host-side IMU transmit builders because IMU traffic is firmware-originated telemetry only and the existing host transmit API was both invalid and unused.

BREAKING CHANGE: IMU accelerometer and gyroscope payloads now carry timestamps, a new temperature IMU payload is emitted, host callback implementations must handle temperature_receive_callback(), and the public host IMU transmit helpers have been removed.
@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 13, 2026

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Reviews paused.

- Extend GPIO read configuration with capture_timestamp and add an optional timestamp field to digital read results so host consumers can align GPIO events with board-side IMU telemetry.
- Update the GPIO wire format to encode timestamped digital read requests and results, move pull configuration into the read payload, and widen period_ms storage to 16 bits.
- Implement timestamp capture for ASAP, periodic, and interrupt-driven digital reads in both c_board and rmcs_board while keeping analog read and write paths explicitly non-timestamped.
- GPIO periodic sampling now uses the board timer abstraction for safe 64-bit tick reads.

BREAKING CHANGE: GPIO read-config packets use a new wire layout and timestamped digital read results may include an additional 32-bit timestamp payload.
@qzhhhi
Copy link
Copy Markdown
Member Author

qzhhhi commented May 13, 2026

@coderabbitai pause

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

✅ Actions performed

Reviews paused.

@qzhhhi qzhhhi merged commit aaaface into main May 13, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in RMCS Slave SDK May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant