fix(usb): resolve USB CDC TX failure — DCache coherency + buffer + IMU API (bd-1lo) #6

Merged
seb merged 1 commits from sl-firmware/bd-1lo-usb-cdc-fix into main 2026-02-28 12:52:43 -05:00
Collaborator

Summary

  • BUG 1 (PRIMARY): SCB_DisableDCache() was inside icm42688_init(), called ~3.5s after USB starts. STM32F7 SystemInit() enables DCache; CPU writes to TX buffers stay in cache and USB hardware reads stale SRAM → sends zeros/garbage. Fix: SCB_DisableDCache() moved to main() before HAL_Init(), before USB starts.
  • BUG 2: CDC_Transmit() passed caller stack buffer pointer to USB hardware. USB TXFE IRQ fires async; buffer could be overwritten before FIFO is loaded. Fix: always memcpy into static UserTxBuffer before transmitting.
  • BUG 3: main.c called icm42688_read() directly and passed icm42688_data_t* to balance_update() which expects IMUData* (float pitch/pitch_rate). Type mismatch produced garbage balance values. Fix: use mpu6000_init()/mpu6000_read() which wraps icm42688 + complementary filter. Bonus: fix icm42688_init() returning 0 when who==0 (false IMU success).

Test plan

  • Flash to MAMBA F722S
  • Verify USB CDC port enumerates (/dev/cu.usbmodemSALTY*)
  • Open port with terminal — confirm JSON telemetry streams at 50Hz
  • Send S command — streaming toggles off/on
  • Confirm p (pitch) and r (pitch_rate) values are plausible
  • Send R command — DFU reboot works

🤖 Generated with Claude Code

## Summary - **BUG 1 (PRIMARY)**: `SCB_DisableDCache()` was inside `icm42688_init()`, called ~3.5s after USB starts. STM32F7 `SystemInit()` enables DCache; CPU writes to TX buffers stay in cache and USB hardware reads stale SRAM → sends zeros/garbage. **Fix**: `SCB_DisableDCache()` moved to `main()` before `HAL_Init()`, before USB starts. - **BUG 2**: `CDC_Transmit()` passed caller stack buffer pointer to USB hardware. USB TXFE IRQ fires async; buffer could be overwritten before FIFO is loaded. **Fix**: always `memcpy` into static `UserTxBuffer` before transmitting. - **BUG 3**: `main.c` called `icm42688_read()` directly and passed `icm42688_data_t*` to `balance_update()` which expects `IMUData*` (float pitch/pitch_rate). Type mismatch produced garbage balance values. **Fix**: use `mpu6000_init()`/`mpu6000_read()` which wraps icm42688 + complementary filter. Bonus: fix `icm42688_init()` returning 0 when `who==0` (false IMU success). ## Test plan - [ ] Flash to MAMBA F722S - [ ] Verify USB CDC port enumerates (`/dev/cu.usbmodemSALTY*`) - [ ] Open port with terminal — confirm JSON telemetry streams at 50Hz - [ ] Send `S` command — streaming toggles off/on - [ ] Confirm `p` (pitch) and `r` (pitch_rate) values are plausible - [ ] Send `R` command — DFU reboot works 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sl-firmware added 1 commit 2026-02-28 12:38:02 -05:00
Bug 1 (PRIMARY — DCache/USB coherency):
SCB_DisableDCache() was buried inside icm42688_init(), called ~3.5s
after USB starts. STM32F7 DCache/USB coherency issue: when DCache is
on (enabled by SystemInit()), CPU writes to TX buffers stay in cache
and the USB hardware reads stale SRAM data. Moved SCB_DisableDCache()
to main() before HAL_Init(), ensuring coherency for all USB transfers.

Bug 2 (USB TX corruption):
CDC_Transmit() passed the caller's stack-allocated buf pointer directly
to the USB stack. The USB TXFE interrupt fires asynchronously; by then
the stack buffer may have been modified by the next loop iteration.
CDC_Transmit() now copies into the static UserTxBuffer before handing
off to the USB hardware, ensuring the buffer is stable for the transfer.

Bug 3 (IMU type mismatch → wrong data to balance):
main.c called icm42688_init()/icm42688_read() directly, passing
icm42688_data_t* (raw int16 ax/ay/az/gx/gy/gz) to balance_update()
which expects IMUData* (float pitch/pitch_rate from complementary
filter). Type mismatch produced garbage balance values. Fixed by using
mpu6000_init()/mpu6000_read() which wraps icm42688 + sensor fusion.
Telemetry updated to report fused pitch/rate instead of raw ADC counts.

Also fix icm42688_init() returning 0 on who==0 (no SPI response),
which falsely indicated IMU success.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
seb merged commit bfb94fc169 into main 2026-02-28 12:52:43 -05:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: seb/saltylab-firmware#6
No description provided.