fix(usb): MPU non-cacheable region + IWDG ordering fix (bd-3ulu) #10

Merged
seb merged 1 commits from sl-firmware/bd-3ulu-usb-dcache-fix into main 2026-02-28 14:54:43 -05:00
Collaborator

Summary

Fixes issue #9: USB CDC TX fails when ICM42688 init is added.

Root cause 1 — IWDG watchdog reset loop (primary blocker):
safety_init() was called before mpu6000_init(). IWDG starts with 50ms timeout but mpu6000_init() takes ~510ms. IWDG fires → MCU resets → infinite loop. USB enumerates during the 3s pre-IWDG delay but board resets before main loop runs.

Fix: moved safety_init() to after all peripheral inits.

Root cause 2 — DCache coherency for USB buffers:
Groups USB TX/RX buffers into 512B-aligned struct. MPU Region 0 configured TEX=1, C=0, B=0 (Normal Non-cacheable) in USBD_LL_Init() before HAL_PCD_Init(). DCache stays ON globally. Removed SCB_DisableDCache() from main.c.

Additional: fix safety.c IWDG_RELOAD macro (float in #if), add crsf.c stub.

Test plan

  • Flash firmware, USB CDC telemetry arrives at 50Hz
  • IMU SPI + USB TX coexist (no lockup after ~510ms)
  • Board does not reset-loop on power-up
## Summary Fixes issue #9: USB CDC TX fails when ICM42688 init is added. **Root cause 1 — IWDG watchdog reset loop (primary blocker):** `safety_init()` was called before `mpu6000_init()`. IWDG starts with 50ms timeout but `mpu6000_init()` takes ~510ms. IWDG fires → MCU resets → infinite loop. USB enumerates during the 3s pre-IWDG delay but board resets before main loop runs. Fix: moved `safety_init()` to after all peripheral inits. **Root cause 2 — DCache coherency for USB buffers:** Groups USB TX/RX buffers into 512B-aligned struct. MPU Region 0 configured `TEX=1, C=0, B=0` (Normal Non-cacheable) in `USBD_LL_Init()` before `HAL_PCD_Init()`. DCache stays ON globally. Removed `SCB_DisableDCache()` from `main.c`. **Additional:** fix `safety.c` `IWDG_RELOAD` macro (float in #if), add `crsf.c` stub. ## Test plan - [ ] Flash firmware, USB CDC telemetry arrives at 50Hz - [ ] IMU SPI + USB TX coexist (no lockup after ~510ms) - [ ] Board does not reset-loop on power-up
sl-firmware added 1 commit 2026-02-28 13:51:31 -05:00
Root cause 1 (IWDG reset loop): safety_init() was called before
mpu6000_init() — IWDG 50ms timeout fires during ~510ms IMU init,
causing infinite MCU reset. Moved safety_init() to after all
peripheral inits (IMU, hoverboard, balance).

Root cause 2 (DCache coherency): USB TX/RX buffers merged into a
single 512B-aligned struct in usbd_cdc_if.c. MPU Region 0 configured
non-cacheable (TEX=1, C=0, B=0) in usbd_conf.c USBD_LL_Init() before
HAL_PCD_Init(). DCache stays ON globally — MPU handles coherency.
Removed SCB_DisableDCache() from main.c (caused boot crash).

Also: fix safety.c IWDG_RELOAD macro (float literals not valid in
#if); add crsf.c stub so crsf_state links (UART not yet wired).

Fixes issue #9.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
seb approved these changes 2026-02-28 14:54:42 -05:00
seb left a comment
Owner

Tested on hardware — USB CDC streaming confirmed at 50Hz with IMU data. Both fixes verified: IWDG ordering + DCache MPU region. Merging.

Tested on hardware — USB CDC streaming confirmed at 50Hz with IMU data. Both fixes verified: IWDG ordering + DCache MPU region. Merging.
seb merged commit 257d6ccf26 into main 2026-02-28 14:54:43 -05:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

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