Skip to content

Add built-in IWatchdog library to expose the IWDG component. #292

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions libraries/IWatchdog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
## IWatchdog Library V1.0.0 for stm32 Arduino core

**Written by:** _Venelin Efremov_ and _Frederic Pillon_

### Requirement
* [Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_STM32) version > 1.3.0

### What is the IWatchdog library.

Th IWatchdog library provides an interface to the independent watchdog module (IWDG) inside STM32 chips.
The IWDG module is used in production systems to generate a reset signal to the CPU in case some
catastrophic event causes the software to become "stuck" or unresponsive.

The IWDG module contains a count-down timer. The module would generate a reset condition when the timer
reaches zero. In normal operation mode the software running on the CPU would reload the timer periodically to
prevent the reset condition from happening. However if a software bug or other error causes the CPU to
execute a different code path for too long, the reload would not happen and the IWDG module would reset the CPU.

### How to use it
The IWatchdog is a built-in library included with the STM32 core package. To add its functionality to your sketch
you will need to reference the library header file. It is done by adding: `#include <IWatchdog.h>`

```Arduino
#include <IWatchdog.h>

void setup() {
...
// Initialize the IWDG with 4 seconds timeout.
// This would cause a CPU reset if the IWDG timer
// is not reloaded in approximately 4 seconds.
IWatchdog.begin(4000000);
}

void loop() {
...your code here...
// make sure the code in this loop is executed in
// less than 2 seconds to leave 50% headroom for
// the timer reload.
IWatchdog.reload();
}

```

### Library functions

#### Preinstantiate Object

A default instance is available: `IWatchdog`

```Arduino
IWatchdogClass IWatchdog = IWatchdogClass();
```

#### Predefined values

* Minimal timeout in microseconds: `IWDG_TIMEOUT_MIN`
* Maximal timeout in microseconds: `IWDG_TIMEOUT_MAX`

#### `void begin(uint32_t timeout, uint32_t window = IWDG_TIMEOUT_MAX)`

The `begin()` function would initialize the IWDG hardware block.

The `timeout` parameter is in microseconds and set the timer reset timeout.
When the timer reaches zero the hardware block would generate a reset signal
for the CPU.

When specifying timeout value plan to refresh the timer at least twice
as often. The `reload()` operation is not expensive.

The downside of selecting a very large timeout value is that your system
may be left in a "stuck" state for too long, before the reset is
generated.

Valid timeout values depends of the LSI clock. Typically, it is 32kH value are between
125µs and 32,768ms (~32.8 seconds). The precision depends of the timeout values:

| timeout value range | timeout value precision |
| ------------------- |:-----------------------:|
| 125µs - 512ms | 125µs
| 513ms - 1024ms | 250µs
| 1025ms - 2048ms | 500µs
| 2049ms - 4096ms | 1ms
| 4097ms - 8192ms | 2ms
| 8193ms - 16384ms | 4ms
| 16385ms - 32768ms | 8ms

The optional `window` parameter is in microseconds and must be less than `timeout`.
If the window option is enabled, the counter must be refreshed inside the window;
otherwise, a system reset is generated.

**Note:**
Window feature is not available for all STM32 series.

Calling the `begin()` method with value outside of the valid range
would return without initializing the watchdog timer.

**WARNING:**
*Once started the IWDG timer can not be stopped. If you are
planning to debug the live system, the watchdog timer may cause the
system to be reset while you are stopped in the debugger. Also consider
the iwatchdog timer implications if you are designing a system which puts
the CPU in sleep mode.*

#### `void reload()`

The `reload()` method reloads the counter value.

Once you have initialized the IWDG you **HAVE** to call `reload()`
periodically to prevent the CPU being reset.

#### `void set(uint32_t timeout, uint32_t window = IWDG_TIMEOUT_MAX)`

The `set()` method allows to set the timeout and window values.

The `timeout` and optional `window` parameters are the same than `begin()` method.

#### `void get(uint32_t* timeout, uint32_t* window = NULL)`

The `get()` method allows to get the current timeout and window values
currently set.

The `timeout` and optional `window` pointers to get values are in microseconds.

#### `bool isEnabled()`

The `isEnabled()` method returns status of the IWDG block. If enabled or not.

#### `bool isReset(bool clear)`

The `isReset()` method checks if the system has resumed from IWDG reset.

The optional `clear` parameter allow to clear IWDG reset flag if true. Default: false.

#### `void clearReset()`

The `clearReset()` method clears IWDG reset flag.
85 changes: 85 additions & 0 deletions libraries/IWatchdog/examples/IWDG_Button/IWDG_Button.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
IWatchdog + Button

This example code is in the public domain.

The code demonstrates the use of a independent watchdog timer.
The watchdog timer is initialized with timeout of 10 seconds.
Every time the button is pressed, the watchdog timer is reset.
If left unattended the system would reset itself about every 10 seconds.

You would have to keep pressing the button frequently (< 10 seconds apart)
to prevent the system from reseting itself.

You would recognize the reset condition when the LED blinks few times quickly.

This is not a practical example, in real code you would reset the watchdog
timer in the main loop without requiring user input.

The code is modified version of the code from:
http://www.arduino.cc/en/Tutorial/Button
*/

#include <IWatchdog.h>

#ifdef USER_BTN
const int buttonPin = USER_BTN;
#else
const int buttonPin = 2;
#endif

#ifdef LED_BUILTIN
const int ledPin = LED_BUILTIN;
#else
const int ledPin = 13;
#endif

static int default_buttonState = LOW;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);

if (IWatchdog.isReset(true)) {
// LED blinks to indicate reset
for (uint8_t idx = 0; idx < 5; idx++) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
}

// Read default state of the pushbutton
default_buttonState = digitalRead(buttonPin);

// Init the watchdog timer with 10 seconds timeout
IWatchdog.begin(10000000);
// or with a 2 seconds window
// IWatchdog.begin(10000000, 2000000);

if (!IWatchdog.isEnabled()) {
// LED blinks indefinitely
while (1) {
digitalWrite(ledPin, HIGH);
delay(500);
digitalWrite(ledPin, LOW);
delay(500);
}
}
}

void loop() {
// Compare current button state of the pushbutton value:
if (digitalRead(buttonPin) == default_buttonState) {
digitalWrite(ledPin, LOW);
} else {
digitalWrite(ledPin, HIGH);

// Uncomment to change timeout value to 6 seconds
//IWatchdog.set(6000000);

// Reload the watchdog only when the button is pressed
IWatchdog.reload();
}
}
29 changes: 29 additions & 0 deletions libraries/IWatchdog/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map For IWatchdog
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

IWatchdog KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2
set KEYWORD2
get KEYWORD2
reload KEYWORD2
isEnabled KEYWORD2
isReset KEYWORD2
clearReset KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

IWDG_TIMEOUT_MIN LITERAL1
IWDG_TIMEOUT_MAX LITERAL1
IS_IWDG_TIMEOUT LITERAL1
9 changes: 9 additions & 0 deletions libraries/IWatchdog/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=IWatchdog
version=1.0.0
author=Venelin Efremov, Frederic Pillon
maintainer=stm32duino
sentence=Enables support for independent watchdog (IWDG) hardware on STM32 processors.
paragraph=Independent watchdog (IWDG) is a hardware timer on the chip which would generate a reset condition if the time is not reloaded withing the specified time. It is generally used in production systems to reset the system if the CPU becomes "stuck".
category=Timing
url=
architectures=stm32
Loading