IWDG MCAL Module
Supported STM32 families: F4 Β· H5
Not supported: G4, H7, L4, U5
This repository provides the MCAL (Microcontroller Abstraction Layer) driver for the Independent Watchdog (IWDG) used in STM32 microcontrollers.
It offers a simple and safe interface to start, configure and refresh the watchdog without dealing with prescalers, reload values or register update flags.
Each STM32 family is supported in a dedicated branch of this repository:
STM32G4STM32U5STM32L4STM32H5- and others as needed.
π Overviewβ
The IWDG MCAL driver abstracts the STM32 independent watchdog into a time-based interface.
The user configures the watchdog in milliseconds, the module does the rest:
- Prescaler (4 - 1024) and reload value calculation from the required timeout and the LSI frequency
- Optional window - refresh is allowed only within the last part of the timeout
- Optional early wakeup interrupt - user callback called before the watchdog resets the MCU
- Automatic refresh from
Iwdg_Task()or manual refresh byIwdg_Set_Refresh() - Watchdog state and achieved timeout readout
Register write access (key register), register update flags and read-back verification of every configuration write are handled internally by the module.
β The user does not need to include or use any additional modules such as RCC or NVIC drivers.
LSI frequency is read from the RCC module and the early wakeup interrupt is configured through the NVIC module internally.
β οΈ Once started, the watchdog can not be stopped (hardware limitation). It is stopped only by a system reset, unless the hardware watchdog mode is selected in the option bytes.
Iwdg_Deinit()only disables the interrupt and the automatic refresh - the application has to keep refreshing the watchdog.
π§© Architectureβ
The architecture follows the standard MCAL layering used across all STM32 MCAL repositories:
ββββββββββββββββββββββββββββββ
β Application β
ββββββββββββββ¬ββββββββββββββββ
β
ββββββββββββββΌββββββββββββββββ
β HAL β
β(Hardware Abstraction Layer)β
ββββββββββββββ¬ββββββββββββββββ
ββββββββββββββΌββββββββββββββββ
β MCAL - Iwdg β
β βββ Iwdg_Port.h β
β βββ Iwdg_Types.h β
β βββ Iwdg.c/.h β
ββββββββββββββ¬ββββββββββββββββ
β
ββββββββββββββΌββββββββββββββββ
β RAL β
β(Register Abstraction Layer)β
ββββββββββββββββββββββββββββββ
π§ Usage Guidelinesβ
The user shall only interact with the following two public headers:
| File | Purpose |
|---|---|
Iwdg_Port.h | Contains all public API functions (init, refresh, state and timeout readout, default configuration) |
Iwdg_Types.h | Contains type definitions used in the API (configuration structure, time type, callback type, request states) |
Everything else β prescaler tables, helper functions, interrupt handler β is internal and must not be accessed directly.
Public APIβ
| Function | Description |
|---|---|
Iwdg_Get_ModuleVersion() | Returns module SW version |
Iwdg_Init( config ) | Calculates the configuration, starts and configures the watchdog |
Iwdg_Deinit() | Disables early wakeup interrupt and automatic refresh (watchdog keeps running) |
Iwdg_Task() | Refreshes the watchdog automatically (only when the window is not used) |
Iwdg_Get_DefaultConfig( config ) | Fills default configuration: timeout 1 s, no window, no early wakeup interrupt |
Iwdg_Get_State( state ) | Returns IWDG_FUNCTION_ACTIVE if the watchdog is running |
Iwdg_Get_Timeout( timeout ) | Returns achieved timeout in ms calculated from the registers |
Iwdg_Set_Refresh() | Refreshes (reloads) the watchdog counter |
Configurationβ
| Item | Description |
|---|---|
Timeout | Required timeout in ms. With 32 kHz LSI the range is approx. 1 ms - 131 s. |
Window | Length of the window before timeout in ms, when refresh is allowed. IWDG_TIME_UNUSED disables the window. Must be shorter than Timeout. |
EarlyWakeup | Time before timeout in ms, when the early wakeup interrupt is triggered. IWDG_TIME_UNUSED disables the interrupt. Must be shorter than Timeout. |
EarlyWakeupIsr | User callback of the early wakeup interrupt, can be NULL |
IrqPriority | Early wakeup interrupt priority (0 - highest) |
Invalid configuration (timeout out of range, window or early wakeup not shorter than timeout) is rejected by Iwdg_Init() before any register is written.
Notesβ
- Window mode - refresh before the window resets the MCU immediately (hardware behavior), it can not be reported by software.
Iwdg_Task()does not refresh in window mode, the application has to callIwdg_Set_Refresh()inside the window. - Hardware watchdog mode - if
Iwdg_Get_State()returnsIWDG_FUNCTION_ACTIVEbeforeIwdg_Init()after reset, the watchdog was started by the option bytes. - Reset cause - IWDG reset can be detected after startup by
Rcc_Get_ResetSource( RCC_RESET_SRC_IWDG, &flag )and cleared byRcc_Set_ResetSourceClear()in the RCC module. - Timeout accuracy - LSI frequency varies with temperature and voltage (see datasheet), the real timeout differs from the calculated one accordingly.
βοΈ Typical Usage Exampleβ
#include "Iwdg_Port.h"
static void App_WatchdogWarning( void )
{
// Last chance to store diagnostic data before the watchdog reset
}
int main(void)
{
iwdg_Config_t iwdgConfig;
iwdg_Time_ms_t achievedTimeout = 0u;
iwdg_RequestState_t iwdgState = IWDG_REQUEST_ERROR;
iwdgState = Iwdg_Get_DefaultConfig( &iwdgConfig );
iwdgConfig.Timeout = 500u; // Reset after 500 ms without refresh
iwdgConfig.EarlyWakeup = 50u; // Callback 50 ms before reset
iwdgConfig.EarlyWakeupIsr = App_WatchdogWarning;
iwdgConfig.IrqPriority = 0u;
if( IWDG_REQUEST_OK == iwdgState )
{
iwdgState = Iwdg_Init( &iwdgConfig );
}
if( IWDG_REQUEST_OK == iwdgState )
{
iwdgState = Iwdg_Get_Timeout( &achievedTimeout );
}
while (1)
{
// Refreshes the watchdog automatically (no window configured)
Iwdg_Task();
}
}
π§Ύ Branching Strategyβ
Each STM32 family has its own branch:
| Branch | Description |
|---|---|
STM32G4 | MCAL driver for STM32G4 family |
STM32U5 | MCAL driver for STM32U5 family |
STM32L4 | MCAL driver for STM32L4 family |
STM32H5 | MCAL driver for STM32H5 family |
These branches contain family-specific register definitions, prescaler ranges and RCC/NVIC bindings while maintaining a common interface.
π§© Dependenciesβ
- Rcc_Lib β LSI clock frequency (
RCC_PERIPH_IWDG) - Nvic_Lib β Early wakeup interrupt handling
- RAL (Register Abstraction Layer) β Used internally to access low-level registers
All mandatory RCC and NVIC configurations are handled internally.
π§± Example Directory Structureβ
Iwdg/
βββ Iwdg_Port.h
βββ Iwdg_Types.h
βββ Iwdg.c
βββ Iwdg.h
βββ CMakeLists.txt
βββ LICENSE.md
βββ README.md
π CMake Integrationβ
- Include
Iwdg_Libin your CMake library. - Include
Iwdg_Port.hin your project. - Link against the Iwdg module implementation files.
- Configure the module as needed for your hardware.
Licenseβ
This project is licensed under the Creative Commons AttributionβNonCommercial 4.0 International (CC BY-NC 4.0).
You are free to use, modify, and share this work for non-commercial purposes, provided appropriate credit is given.
See LICENSE.md for full terms or visit creativecommons.org/licenses/by-nc/4.0.
Authorsβ
- Mr.Nobody β embedbits.com
Contributions are welcome! Please open a pull request.