Implements STM32 IWDG (Independent Watchdog) driver with: - Configurable timeout (1ms - 32s range, default 2 seconds) - Prescaler/reload calculation for accurate timeout values - watchdog_kick() to reset counter from main loop - Detection of watchdog-caused resets via RCC_CSR flags - Full unit test suite (37 assertions, all passing) The watchdog timer helps detect Jetson communication stalls by forcing an MCU reset if the watchdog is not regularly kicked. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
101 lines
3.0 KiB
C
101 lines
3.0 KiB
C
#ifndef WATCHDOG_H
|
|
#define WATCHDOG_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
/*
|
|
* watchdog.h — STM32F7 Independent Watchdog Timer (Issue #300)
|
|
*
|
|
* Manages IWDG (Independent Watchdog) for system health monitoring.
|
|
* Detects communication stalls from Jetson and resets the MCU.
|
|
*
|
|
* Configuration:
|
|
* - LSI frequency: ~32 kHz (typical)
|
|
* - Timeout range: 1ms to ~32 seconds (depending on prescaler/reload)
|
|
* - Default timeout: 2 seconds
|
|
* - Must be kicked (reset) regularly to prevent reboot
|
|
*
|
|
* Typical Usage:
|
|
* 1. Call watchdog_init(2000) in system startup
|
|
* 2. Call watchdog_kick() regularly from main loop (e.g., every 100ms)
|
|
* 3. If watchdog_kick() is not called for >= timeout, MCU resets
|
|
* 4. Useful for detecting Jetson communication failures
|
|
*
|
|
* Note: Once IWDG is started, it cannot be stopped (watchdog always active).
|
|
* It can only be reset via watchdog_kick() or by MCU reset/power cycle.
|
|
*/
|
|
|
|
/* Watchdog timeout presets (in milliseconds) */
|
|
typedef enum {
|
|
WATCHDOG_TIMEOUT_1S = 1000, /* 1 second timeout */
|
|
WATCHDOG_TIMEOUT_2S = 2000, /* 2 seconds (default) */
|
|
WATCHDOG_TIMEOUT_4S = 4000, /* 4 seconds */
|
|
WATCHDOG_TIMEOUT_8S = 8000, /* 8 seconds */
|
|
WATCHDOG_TIMEOUT_16S = 16000 /* 16 seconds */
|
|
} WatchdogTimeout;
|
|
|
|
/*
|
|
* watchdog_init(timeout_ms)
|
|
*
|
|
* Initialize the Independent Watchdog Timer.
|
|
*
|
|
* - Configures IWDG with specified timeout
|
|
* - Starts the watchdog timer (cannot be stopped)
|
|
* - Must call watchdog_kick() regularly to prevent reset
|
|
*
|
|
* Arguments:
|
|
* - timeout_ms: Timeout in milliseconds (e.g., 2000 for 2 seconds)
|
|
* Typical range: 1-16000 ms
|
|
* Will clamp to valid range
|
|
*
|
|
* Returns: true if initialized, false if invalid timeout
|
|
*/
|
|
bool watchdog_init(uint32_t timeout_ms);
|
|
|
|
/*
|
|
* watchdog_kick()
|
|
*
|
|
* Reset the watchdog timer counter.
|
|
* Call this regularly from the main loop (e.g., every 100ms or faster).
|
|
* If not called within the configured timeout period, MCU resets.
|
|
*
|
|
* Note: This is typically called from a high-priority timer interrupt
|
|
* or the main application loop to ensure timing is deterministic.
|
|
*/
|
|
void watchdog_kick(void);
|
|
|
|
/*
|
|
* watchdog_get_timeout()
|
|
*
|
|
* Get the configured watchdog timeout in milliseconds.
|
|
*
|
|
* Returns: Timeout value in ms
|
|
*/
|
|
uint32_t watchdog_get_timeout(void);
|
|
|
|
/*
|
|
* watchdog_is_running()
|
|
*
|
|
* Check if watchdog timer is running.
|
|
* Once started, watchdog cannot be stopped (only reset via kick).
|
|
*
|
|
* Returns: true if watchdog is active, false if not initialized
|
|
*/
|
|
bool watchdog_is_running(void);
|
|
|
|
/*
|
|
* watchdog_was_reset_by_watchdog()
|
|
*
|
|
* Detect if the last MCU reset was caused by watchdog timeout.
|
|
* Useful for diagnosing system failures (e.g., Jetson communication loss).
|
|
*
|
|
* Call this in early startup (before watchdog_init) to check reset reason.
|
|
* Typically used to log or report watchdog resets to debugging systems.
|
|
*
|
|
* Returns: true if last reset was by watchdog, false otherwise
|
|
*/
|
|
bool watchdog_was_reset_by_watchdog(void);
|
|
|
|
#endif /* WATCHDOG_H */
|