feat: Integrate IWDG watchdog timer driver (Issue #300)
- Replace safety.c's direct IWDG initialization with watchdog module API - Use watchdog_init(2000) for ~2s timeout in safety_init() - Use watchdog_kick() in safety_refresh() to feed the watchdog - Remove unused watchdog_get_divider() helper function - Watchdog now configured with automatic prescaler selection The watchdog module provides a clean, flexible IWDG interface that: - Automatically calculates prescaler and reload values - Detects watchdog-triggered resets via watchdog_was_reset_by_watchdog() - Supports timeout range of ~1ms to ~32 seconds - Integrates seamlessly with existing safety system Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e2587b60fb
commit
5cec6779e5
23
src/safety.c
23
src/safety.c
@ -12,20 +12,9 @@
|
|||||||
#include "safety.h"
|
#include "safety.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "crsf.h"
|
#include "crsf.h"
|
||||||
|
#include "watchdog.h"
|
||||||
#include "stm32f7xx_hal.h"
|
#include "stm32f7xx_hal.h"
|
||||||
|
|
||||||
/* IWDG prescaler 32 → LSI(40kHz)/32 = 1250 ticks/sec → 0.8ms/tick */
|
|
||||||
#define IWDG_PRESCALER IWDG_PRESCALER_32
|
|
||||||
/* Integer formula: timeout_ms * LSI_HZ / (prescaler * 1000)
|
|
||||||
* = WATCHDOG_TIMEOUT_MS * 40000 / (32 * 1000) = WATCHDOG_TIMEOUT_MS * 40 / 32 */
|
|
||||||
#define IWDG_RELOAD (WATCHDOG_TIMEOUT_MS * 40UL / 32UL)
|
|
||||||
|
|
||||||
#if IWDG_RELOAD > 4095
|
|
||||||
# error "WATCHDOG_TIMEOUT_MS too large for IWDG_PRESCALER_32 — increase prescaler"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static IWDG_HandleTypeDef hiwdg;
|
|
||||||
|
|
||||||
/* Arm interlock */
|
/* Arm interlock */
|
||||||
static uint32_t s_arm_start_ms = 0;
|
static uint32_t s_arm_start_ms = 0;
|
||||||
static bool s_arm_pending = false;
|
static bool s_arm_pending = false;
|
||||||
@ -36,15 +25,13 @@ static bool s_was_faulted = false;
|
|||||||
static EstopSource s_estop_source = ESTOP_CLEAR;
|
static EstopSource s_estop_source = ESTOP_CLEAR;
|
||||||
|
|
||||||
void safety_init(void) {
|
void safety_init(void) {
|
||||||
hiwdg.Instance = IWDG;
|
/* Initialize IWDG via watchdog module (Issue #300) with ~2s timeout */
|
||||||
hiwdg.Init.Prescaler = IWDG_PRESCALER;
|
watchdog_init(2000);
|
||||||
hiwdg.Init.Reload = IWDG_RELOAD;
|
|
||||||
hiwdg.Init.Window = IWDG_WINDOW_DISABLE;
|
|
||||||
HAL_IWDG_Init(&hiwdg); /* Starts watchdog immediately */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void safety_refresh(void) {
|
void safety_refresh(void) {
|
||||||
if (hiwdg.Instance) HAL_IWDG_Refresh(&hiwdg);
|
/* Feed the watchdog timer */
|
||||||
|
watchdog_kick();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool safety_rc_alive(uint32_t now) {
|
bool safety_rc_alive(uint32_t now) {
|
||||||
|
|||||||
@ -76,16 +76,6 @@ static bool watchdog_calculate_config(uint32_t timeout_ms,
|
|||||||
return false; /* No suitable prescaler found */
|
return false; /* No suitable prescaler found */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get prescaler divider from prescaler value */
|
|
||||||
static uint16_t watchdog_get_divider(uint8_t prescaler)
|
|
||||||
{
|
|
||||||
const uint16_t dividers[] = {4, 8, 16, 32, 64, 128, 256};
|
|
||||||
if (prescaler < 7) {
|
|
||||||
return dividers[prescaler];
|
|
||||||
}
|
|
||||||
return 256;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* Public API
|
* Public API
|
||||||
* ================================================================ */
|
* ================================================================ */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user