Skip to content
This repository was archived by the owner on Jun 28, 2025. It is now read-only.

Commit 09a7bea

Browse files
authored
Watchdog init in the constructor (#59)
Refactor to Watchdog Driver
1 parent 711c857 commit 09a7bea

File tree

4 files changed

+127
-15
lines changed

4 files changed

+127
-15
lines changed

Boardfiles/nucleol552zeq/Core/Src/main.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ int main(void)
129129
MX_TIM5_Init();
130130
MX_ADC1_Init();
131131
MX_ICACHE_Init();
132-
MX_IWDG_Init();
133132
MX_TIM3_Init();
134133
MX_SDMMC1_SD_Init();
135134
if (MX_FATFS_Init() != APP_OK) {

Drivers/iwdg_driver/inc/independent_watchdog.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,29 @@
55
#include "watchdog.h"
66
#include "iwdg.h"
77

8+
/* Reminder for the correct usage of this driver:
9+
Don't initialize more than one instance of iwdg.
10+
There is only one iwdg in more STM, so it won't work.
11+
12+
Also, don't call MX_IWDG_Init() in main!
13+
*/
814
class IndependentWatchdog : public Watchdog {
915
private:
10-
IWDG_HandleTypeDef* watchdog;
16+
IWDG_HandleTypeDef* watchdog_;
17+
uint32_t prescaler_;
18+
uint32_t window_;
19+
uint32_t reload_;
1120

21+
bool counterCalculation(uint32_t timeout, uint32_t &prescaler, uint32_t &counter);
22+
bool windowCalculation(uint32_t timeout, uint32_t prescaler, uint32_t &window);
1223
public:
13-
IndependentWatchdog(IWDG_HandleTypeDef* watchdog);
24+
/* Time out in ms */
25+
IndependentWatchdog(uint32_t timeout);
26+
27+
/* This is very similiar to a Window Watchdog */
28+
IndependentWatchdog(uint32_t counter_timeout, uint32_t window_timeout);
29+
30+
/* Feed the dog and makes it happy */
1431
bool refreshWatchdog() override ;
1532
};
1633

Lines changed: 103 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,71 @@
11
#include "independent_watchdog.h"
22

3-
/**
4-
* @brief Borrow the configuration of an already existing watchdog and set it
5-
* to the prescaler and Reload values.
6-
*
7-
*/
8-
IndependentWatchdog::IndependentWatchdog(IWDG_HandleTypeDef *watchdog) {
9-
this->watchdog = watchdog;
3+
#define MAX_PR 6
4+
#define RELOAD_LENGTH 12
5+
#define WINDOW_LENGTH 12
6+
#define LSI_SPEED 32000
7+
#define PR_OFFSET 2
8+
#define MAX_TIMEOUT_MS (((1 << RELOAD_LENGTH)*4*(1 << MAX_PR)*1000) / LSI_SPEED) // should be about 32768
9+
10+
/* A general watchdog, the window feature is not used
11+
If it fails, no one could notice it, which is not really desired
12+
@param: timeout - timeout in ms
13+
*/
14+
IndependentWatchdog::IndependentWatchdog(uint32_t timeout){
15+
if (timeout >= MAX_TIMEOUT_MS) {
16+
return;
17+
}
18+
19+
if (counterCalculation(timeout, this->prescaler_, this->reload_) == false){
20+
// Error_Handler();
21+
return;
22+
}
23+
this->window_ = this->reload_;
24+
this->watchdog_ = &hiwdg;
25+
26+
hiwdg.Instance = IWDG;
27+
hiwdg.Init.Prescaler = this->prescaler_;
28+
hiwdg.Init.Window = this->window_;
29+
hiwdg.Init.Reload = this->reload_;
30+
if (HAL_IWDG_Init(this->watchdog_) != HAL_OK)
31+
{
32+
Error_Handler();
33+
}
34+
}
35+
36+
/* I don't know why STM added this feature, but you turn IWDG into a WWDG which is confusing
37+
Now the watchdog triggers the reset when refresh comes too early or when downcounter reaches zero
38+
39+
|------- Refresh triggers reset -------- | ------- Refresh Allowed -------- |--- reset ---|
40+
^ ^ ^
41+
counter value: reload window 0
42+
43+
@param: counter_timeout - in ms
44+
@param: window_timeout - in ms
45+
*/
46+
IndependentWatchdog::IndependentWatchdog(uint32_t counter_timeout, uint32_t window_timeout){
47+
if (counter_timeout >= MAX_TIMEOUT_MS || window_timeout >= MAX_TIMEOUT_MS) {
48+
return;
49+
}
50+
51+
if (counterCalculation(counter_timeout, this->prescaler_, this->reload_) == false){
52+
// Error_Handler();
53+
return;
54+
}
55+
if (windowCalculation(window_timeout, this->prescaler_, this->window_) == false){
56+
// Error_Handler();
57+
return;
58+
}
59+
this->watchdog_ = &hiwdg;
60+
61+
hiwdg.Instance = IWDG;
62+
hiwdg.Init.Prescaler = this->prescaler_;
63+
hiwdg.Init.Window = this->window_;
64+
hiwdg.Init.Reload = this->reload_;
65+
if (HAL_IWDG_Init(this->watchdog_) != HAL_OK)
66+
{
67+
Error_Handler();
68+
}
1069
}
1170

1271

@@ -15,10 +74,44 @@ IndependentWatchdog::IndependentWatchdog(IWDG_HandleTypeDef *watchdog) {
1574
* @brief Refreshes the watchdog that is a member variable of the class
1675
* @returns true on success, false on failure
1776
*/
18-
1977
bool IndependentWatchdog::refreshWatchdog() {
20-
if (this->watchdog == nullptr) {
78+
if (this->watchdog_ == nullptr) {
2179
return false;
2280
}
23-
return (HAL_IWDG_Refresh(watchdog) == HAL_OK);
81+
return (HAL_IWDG_Refresh(this->watchdog_) == HAL_OK);
82+
}
83+
84+
85+
/* Helper function
86+
Updates the prescaler and reload depending on the timeout
87+
*/
88+
bool IndependentWatchdog::counterCalculation(uint32_t timeout, uint32_t &prescaler, uint32_t &counter){
89+
int prescalerPR = 0; // start prescaler = 4
90+
const uint32_t MAX_COUNTER = (1 << RELOAD_LENGTH);
91+
92+
for (; prescalerPR <= MAX_PR; prescalerPR++){
93+
prescaler = prescalerPR;
94+
uint32_t prescalerValue = 1 << (prescalerPR + PR_OFFSET);
95+
counter = ((timeout * LSI_SPEED) / (prescalerValue * 1000)) - 1;
96+
if (counter <= MAX_COUNTER) {
97+
return true;
98+
}
99+
}
100+
101+
return false;
102+
}
103+
104+
/* Helper function
105+
Only update the window depending on the timeout
106+
*/
107+
bool IndependentWatchdog::windowCalculation(uint32_t timeout, uint32_t prescaler, uint32_t &window){
108+
const uint32_t MAX_WINDOW = (1 << WINDOW_LENGTH);
109+
110+
uint32_t prescalerValue = 1 << (prescaler + PR_OFFSET);
111+
window = ((timeout * LSI_SPEED) / (prescalerValue * 1000)) - 1;
112+
if (window <= MAX_WINDOW) {
113+
return true;
114+
}
115+
116+
return false;
24117
}

SystemManager/Src/SystemManager.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
#include "sbus_receiver.hpp"
1313
#include "tim.h"
1414

15-
#define TIMEOUT_CYCLES 250000 // 25k = 1 sec fro testing 10/14/2023 => 250k = 10 sec
15+
16+
#define TIMEOUT_CYCLES 250000 // 25k = 1 sec fro testing 10/14/2023 => 250k = 10 sec
17+
#define TIMOUT_MS 10000 // 10 sec
1618

1719
static uint32_t DisconnectionCount = 0;
1820
float prevthrottle;
@@ -27,7 +29,7 @@ SystemManager::SystemManager()
2729
rollMotorChannel_(&htim2, TIM_CHANNEL_3),
2830
pitchMotorChannel_(&htim2, TIM_CHANNEL_4),
2931
invertedRollMotorChannel_(&htim3, TIM_CHANNEL_1),
30-
watchdog_(&hiwdg) {
32+
watchdog_(TIMOUT_MS) {
3133
// VARIABLES FOR TELEMETRY MANAGER TO HAVE AS REFERENCES THEY OBV SHOULD BE PUT SOMEWHERE ELSE,
3234
// BUT I FEEL LIKE SM PM WOULD KNOW WHERE. MAYBE IN THE HPP FILE? IDK HOW YOU ARE PLANNING ON
3335
// GATHERING THE DATA. I JUST PUT THEM HERE FOR NOW
@@ -57,6 +59,7 @@ SystemManager::SystemManager()
5759
// REGULAR INTERVAL AS IT DEALS WITH MESSAGE DECODING AND LOW PRIORITY DATA TRANSMISSION
5860
}
5961

62+
6063
SystemManager::~SystemManager() {}
6164

6265
void SystemManager::flyManually() {

0 commit comments

Comments
 (0)