feat(safety): IWDG watchdog, arm hold interlock, tilt alert (bd-3qh) #4

Merged
sl-jetson merged 1 commits from sl-controls/bd-3qh-safety-systems into main 2026-02-28 13:12:18 -05:00
Collaborator

Summary

  • IWDG hardware watchdog (50ms) — MCU resets if main loop hangs; cannot be disabled once started
  • Arm hold interlock (3s) — motors only enable after ARMING_HOLD_MS of continuous arm request; prevents accidental arm
  • Tilt fault buzzer — one-shot beep when TILT_FAULT triggers (edge-detected, one alarm per event)
  • RC timeout infrastructuresafety_rc_alive() ready; disarm guard removed when CRSF is wired

New files

  • include/safety.h — API
  • src/safety.c — IWDG + arm interlock + fault alert

Notes

  • Branch includes bd-2dv (IMU fusion) + bd-18i (PID tuning) commits — merge in order
  • IWDG starts after 3s USB delay; watchdog_timeout_ms tunable in config.h
  • RC disarm wired but guarded pending CRSF implementation

Closes bd-3qh

## Summary - **IWDG hardware watchdog** (50ms) — MCU resets if main loop hangs; cannot be disabled once started - **Arm hold interlock** (3s) — motors only enable after ARMING_HOLD_MS of continuous arm request; prevents accidental arm - **Tilt fault buzzer** — one-shot beep when TILT_FAULT triggers (edge-detected, one alarm per event) - **RC timeout infrastructure** — `safety_rc_alive()` ready; disarm guard removed when CRSF is wired ## New files - `include/safety.h` — API - `src/safety.c` — IWDG + arm interlock + fault alert ## Notes - Branch includes bd-2dv (IMU fusion) + bd-18i (PID tuning) commits — merge in order - IWDG starts after 3s USB delay; watchdog_timeout_ms tunable in config.h - RC disarm wired but guarded pending CRSF implementation Closes bd-3qh
sl-controls added 3 commits 2026-02-28 12:33:34 -05:00
Add src/mpu6000.c implementing a complementary filter (α=0.98) on top of
the existing icm42688 SPI driver. Fixes wrong scale factors in balance.c
(was ±250°/s / ±2g; hardware is configured ±2000°/s / ±16g). Fusion now
lives in the IMU driver layer; balance_update() consumes IMUData directly.

- mpu6000_init(): calls icm42688_init(), seeds filter state
- mpu6000_read(): reads raw SPI, applies complementary filter, returns
  fused pitch (degrees) + pitch_rate (°/s) + accel_x/z (g)
- balance.c: removes duplicated fusion code, uses IMUData.pitch
- main.c: switches to mpu6000_init()/mpu6000_read(), updates telemetry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add USB command interface for live PID gain adjustment without reflashing:
  P<kp>  I<ki>  D<kd>  T<setpoint_deg>  M<max_speed>  ?

Command parsing runs in main loop (sscanf-safe), not in USB IRQ.
USB IRQ copies command to shared volatile buffer (cdc_cmd_buf), sets flag.
Acknowledgement echoes current gains: {"kp":...,"ki":...,"kd":...}

Bounds checking: kp 0-500, ki/kd 0-50, setpoint ±20°, max_speed 0-1000.
Gains validated before write — silently ignored if out of range.

Telemetry updated from raw counts to physical tuning signals:
  pitch (°x10), pitch_rate (°/s x10), error (°x10),
  integral (x10 for windup monitoring), motor_cmd, state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Safety systems implementation:

IWDG Hardware Watchdog (50ms timeout, config.h WATCHDOG_TIMEOUT_MS):
- safety_init() configures IWDG at PSC/32 (0.8ms tick), reload=62
- safety_refresh() must be called every loop iteration
- Cannot be disabled once started — MCU resets if loop hangs
- Started after 3s USB init delay (avoids spurious startup reset)

Arm Hold Interlock (3s, config.h ARMING_HOLD_MS):
- Arm command starts a hold timer, not immediate motor enable
- Motors only enable after ARMING_HOLD_MS consecutive hold
- Disarm or tilt > 10° cancels pending arm
- Prevents accidental arm from single keypress

Tilt Fault Alert:
- safety_alert_tilt_fault() fires one-shot buzzer on TILT_FAULT edge
- Rider hears alarm when tilt cutoff triggers
- Edge-detected (buzzer only fires once per fault event)

RC Timeout (infrastructure):
- safety_rc_alive() checks crsf_state.last_rx_ms vs RC_TIMEOUT_MS
- RC disarm wired but guarded (no CRSF yet) — remove guard when wired
- Compatible with future CRSF implementation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sl-controls force-pushed sl-controls/bd-3qh-safety-systems from e181dcc786 to 4dd52b47dc 2026-02-28 13:11:51 -05:00 Compare
sl-jetson merged commit 909763494f into main 2026-02-28 13:12:18 -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#4
No description provided.