Skip to content

Commit 1b8de22

Browse files
author
Owen
authored
Merge pull request #242 from adamgarbo/wdt
2 parents 0dd0342 + 38a241b commit 1b8de22

File tree

7 files changed

+536
-0
lines changed

7 files changed

+536
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
Author: Adam Garbo
3+
Created: August 1st, 2020
4+
License: MIT. See SparkFun Arduino Apollo3 Project for more information
5+
6+
This example demonstrates a simple configuration of the Artemis Watchdog Timer.
7+
8+
The code will configure the watchdog for both interrupt and reset generation,
9+
and immediately start the watchdog timer.
10+
11+
The watchdog ISR provided will 'pet' the watchdog four times. On the fifth
12+
interrupt, the watchdog will not be pet, so the 'reset' action can occur.
13+
On the sixth timeout event, the WDT will issue a system reset, and the
14+
program will start over from the beginning.
15+
16+
The watchdogCounter will show the number of ticks before the watchdog
17+
reset occurs.
18+
19+
This example is based on the Ambiq SDK 2.4.2 watchdog.c example.
20+
21+
Tested with SparkFun Artemis Redboard.
22+
*/
23+
24+
#include "WDT.h"
25+
26+
APM3_WDT wdt;
27+
28+
volatile bool watchdogFlag = false; // Watchdog Timer ISR flag
29+
volatile int watchdogInterrupt = 0; // Watchdog interrupt counter
30+
unsigned long currentMillis = 0,
31+
previousMillis = 0;
32+
33+
void setup() {
34+
35+
Serial.begin(115200);
36+
37+
Serial.println("Artemis Watchdog Timer Example");
38+
39+
// Start the watchdog
40+
wdt.start();
41+
}
42+
43+
void loop()
44+
{
45+
// Check for watchdog interrupts
46+
if (watchdogFlag)
47+
{
48+
// Calculate duration between watchdog interrupts
49+
currentMillis = millis() - previousMillis;
50+
previousMillis = millis();
51+
52+
Serial.print("Interrupt: "); Serial.print(watchdogInterrupt);
53+
Serial.print(" Period: "); Serial.print(currentMillis); Serial.println(" ms ");
54+
55+
if (watchdogInterrupt == 5)
56+
{
57+
Serial.println("Warning: Watchdog has triggered a system reset");
58+
}
59+
}
60+
watchdogFlag = false; // Clear watchdog flag
61+
delay(1);
62+
}
63+
64+
// Interrupt handler for the watchdog
65+
extern "C" void am_watchdog_isr(void)
66+
{
67+
// Clear the watchdog interrupt
68+
wdt.clear();
69+
70+
// Catch the first four watchdog interrupts, but let the fifth through untouched
71+
if ( watchdogInterrupt < 4 )
72+
{
73+
wdt.restart(); // "Pet" the dog
74+
}
75+
else {
76+
digitalWrite(LED_BUILTIN, HIGH); // Visual indication of system reset trigger
77+
}
78+
79+
watchdogFlag = true; // Set watchdog flag
80+
watchdogInterrupt++; // Increment watchdog interrupt counter
81+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
Author: Adam Garbo
3+
Created: August 1st, 2020
4+
License: MIT. See SparkFun Arduino Apollo3 Project for more information
5+
6+
This example demonstrates how to modify the configuration of the Artemis
7+
Watchdog Timer (WDT).
8+
9+
The watchdog timer is controlled by a clock divider, interrupt ticks and
10+
reset ticks. To achieve desired watchdog timing, a simple calculation can be made:
11+
12+
period = # ticks / clock divider frequency
13+
14+
Examples:
15+
128 interrupt ticks / 128 Hz clock = 1 second
16+
64 interrupt ticks / 16 Hz clock = 4 seconds
17+
32 interrupt ticks / 1 Hz clock = 32 seconds
18+
16 interrupt ticks / 1/16 Hz clock = 256 seconds
19+
20+
The following code will configure the watchdog for both interrupt and reset
21+
generation, and immediately start the watchdog timer.
22+
The watchdog ISR provided will 'pet' the watchdog four times. On the fifth
23+
interrupt, the watchdog will not be pet, so the 'reset' action can occur.
24+
On the sixth timeout event, the WDT will issue a system reset, and the
25+
program will start over from the beginning.
26+
27+
This example is based on the Ambiq SDK 2.4.2 watchdog.c example.
28+
29+
Tested with SparkFun Artemis Redboard.
30+
*/
31+
32+
#include "WDT.h"
33+
34+
APM3_WDT wdt;
35+
36+
volatile bool watchdogFlag = false; // Watchdog Timer ISR flag
37+
volatile int watchdogInterrupt = 0; // Watchdog interrupt counter
38+
39+
unsigned long currentMillis = 0,
40+
previousMillis = 0;
41+
42+
void setup()
43+
{
44+
Serial.begin(115200);
45+
46+
Serial.println("Artemis Watchdog Timer Example");
47+
48+
// Configure the watchdog
49+
/*
50+
Available watchdog timer clock dividers.
51+
Users can choose either the clock definition (i.e. WDT_128HZ) or Apoll3 core enumeration (i.e. 1)
52+
WDT_OFF = 0 = Low Power Mode. This setting disables the watch dog timer
53+
WDT_128HZ = 1 = 128 Hz
54+
WDT_16HZ = 2 = 16 Hz
55+
WDT_1HZ = 3 = 1 Hz
56+
WDT1_16HZ = 4 = 1/16th Hz
57+
*/
58+
// Set watchdog timer clock to 128 Hz
59+
// Set watchdog interrupt to 1 seconds (128 ticks / 128 Hz = 1 second)
60+
// Set watchdog reset ~2 seconds (255 ticks / 128 Hz = 1.99 seconds)
61+
// Note: Ticks are limited to 255 (8-bit)
62+
wdt.configure(WDT_128HZ, 128, 255); // Equivalent to: wdt.configure(1, 128, 255);
63+
wdt.start(); // Start the watchdog
64+
}
65+
66+
void loop()
67+
{
68+
// Check for watchdog interrupts
69+
if (watchdogFlag)
70+
{
71+
// Calculate duration between watchdog interrupts
72+
currentMillis = millis() - previousMillis;
73+
previousMillis = millis();
74+
75+
Serial.print("Interrupt: "); Serial.print(watchdogInterrupt);
76+
Serial.print(" Period: "); Serial.print(currentMillis); Serial.println(" ms");
77+
78+
// The watchdog configurations can also be set individually
79+
wdt.setClock(WDT_16HZ); // Set watchdog timer clock to 16 Hz
80+
wdt.setInterrupt(64); // Set watchdog interrupt to 4 second (64 ticks / 16 Hz = 4 seconds)
81+
wdt.setReset(96); // Set watchdog reset to 8 seconds (96 ticks / 16 Hz = 8 seconds)
82+
83+
if (watchdogInterrupt == 9)
84+
{
85+
Serial.println("Warning: Watchdog has triggered a system reset");
86+
}
87+
}
88+
watchdogFlag = false; // Clear watchdog flag
89+
delay(1);
90+
}
91+
92+
// Interrupt handler for the watchdog
93+
extern "C" void am_watchdog_isr(void)
94+
{
95+
// Clear the watchdog interrupt
96+
wdt.clear();
97+
98+
// Catch the first eight watchdog interrupts, but let the ninth through untouched
99+
if ( watchdogInterrupt < 8 )
100+
{
101+
wdt.restart(); // "Pet" the dog
102+
}
103+
else
104+
{
105+
digitalWrite(LED_BUILTIN, HIGH); // Visual indication of system reset trigger
106+
}
107+
108+
watchdogFlag = true; // Set watchdog flag
109+
watchdogInterrupt++; // Increment watchdog interrupt counter
110+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
Author: Adam Garbo
3+
Created: August 1st, 2020
4+
License: MIT. See SparkFun Arduino Apollo3 Project for more information
5+
6+
This example demonstrates the combined use of the Artemis Watchdog Timer (WDT)
7+
and real-time clock (RTC).
8+
9+
Both RTC and WDT interrupts will wake the system, print the date and time,
10+
and then re-enter deep sleep.
11+
12+
The WDT is configured to trigger every 10 seconds. If the WDT is not "pet"
13+
after 100 seconds, a system reset will be triggered.
14+
15+
The RTC alarm is configured to trigger every minute and enter deep sleep
16+
between interrupts. Alarm interuptswill also restart the WDT and reset
17+
the watchdog interrput counter.
18+
*/
19+
20+
#include "RTC.h"
21+
#include "WDT.h"
22+
23+
APM3_RTC rtc;
24+
APM3_WDT wdt;
25+
26+
volatile bool alarmFlag = false; // RTC ISR flag
27+
volatile bool watchdogFlag = false; // Watchdog Timer ISR flag
28+
volatile int watchdogInterrupt = 0; // Watchdog interrupt counter
29+
30+
void setup()
31+
{
32+
Serial.begin(115200);
33+
34+
Serial.println("Artemis Watchdog Low Power Example");
35+
36+
// Set the RTC time using UNIX Epoch time
37+
rtc.setEpoch(1596240000); // Saturday, August 1, 2020 00:00:00
38+
39+
// Set the RTC's alarm
40+
rtc.setAlarm(0, 0, 0, 0, 0, 0); // Set alarm (hund, ss, mm, hh, dd, mm)
41+
rtc.setAlarmMode(6); // Set the RTC alarm to trigger every minute
42+
rtc.attachInterrupt(); // Attach RTC alarm interrupt
43+
44+
// Configure the watchdog timer
45+
// See Example2_WDT_Config for more information on how to configure the watchdog
46+
wdt.configure(WDT_16HZ, 160, 240); // 16 Hz clock, 10-second interrupt period, 15-second reset period
47+
48+
// Start the watchdog
49+
wdt.start();
50+
}
51+
52+
void loop()
53+
{
54+
// Check for alarm interrupt
55+
if (alarmFlag)
56+
{
57+
Serial.print("Alarm interrupt: ");
58+
printDateTime(); // Print RTC's date and time
59+
alarmFlag = false;
60+
61+
wdt.restart(); // "Pet" the dog
62+
watchdogInterrupt = 0; // Reset watchdog interrupt counter
63+
}
64+
65+
// Check for watchdog interrupt
66+
if (watchdogFlag)
67+
{
68+
Serial.print("Watchdog interrupt: ");
69+
printDateTime(); // Print RTC's date and time
70+
watchdogFlag = false; // Clear watchdog flag
71+
}
72+
73+
goToSleep(); // Enter deep sleep
74+
}
75+
76+
// Print the RTC's current date and time
77+
void printDateTime()
78+
{
79+
rtc.getTime();
80+
Serial.printf("20%02d-%02d-%02d %02d:%02d:%02d.%02d\n",
81+
rtc.year, rtc.month, rtc.dayOfMonth,
82+
rtc.hour, rtc.minute, rtc.seconds, rtc.hundredths);
83+
}
84+
85+
// Power down gracefully
86+
void goToSleep()
87+
{
88+
// Disable UART
89+
Serial.end();
90+
91+
// Disable ADC
92+
power_adc_disable();
93+
94+
// Force the peripherals off
95+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
96+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
97+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
98+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
99+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
100+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
101+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
102+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
103+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);
104+
105+
// Disable all pads
106+
for (int x = 0 ; x < 50 ; x++)
107+
am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
108+
109+
//Power down Flash, SRAM, cache
110+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); // Turn off CACHE
111+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); // Turn off everything but lower 512k
112+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); // Turn off everything but lower 64k
113+
//am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)
114+
115+
// Keep the 32kHz clock running for RTC
116+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
117+
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
118+
119+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); // Sleep forever
120+
121+
// And we're back!
122+
wakeUp();
123+
}
124+
125+
// Power up gracefully
126+
void wakeUp()
127+
{
128+
// Power up SRAM, turn on entire Flash
129+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
130+
131+
// Go back to using the main clock
132+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
133+
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
134+
135+
// Enable ADC
136+
ap3_adc_setup();
137+
138+
// Enable Serial
139+
Serial.begin(115200);
140+
}
141+
142+
// Interrupt handler for the RTC
143+
extern "C" void am_rtc_isr(void)
144+
{
145+
// Clear the RTC alarm interrupt
146+
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
147+
148+
alarmFlag = true; // Set alarm flag
149+
}
150+
151+
// Interrupt handler for the watchdog.
152+
extern "C" void am_watchdog_isr(void)
153+
{
154+
// Clear the watchdog interrupt
155+
wdt.clear();
156+
157+
// Perform system reset after 10 watchdog interrupts (should not occur)
158+
if ( watchdogInterrupt < 10 )
159+
{
160+
wdt.restart(); // "Pet" the dog
161+
}
162+
else {
163+
digitalWrite(LED_BUILTIN, HIGH); // Visual indication of system reset trigger
164+
}
165+
166+
watchdogFlag = true; // Set the watchdog flag
167+
watchdogInterrupt++; // Increment watchdog interrupt counter
168+
}

Diff for: libraries/WDT/keywords.txt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#######################################
2+
# Syntax Coloring Map
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
WDT KEYWORD1
10+
11+
#######################################
12+
# Methods and Functions (KEYWORD2)
13+
#######################################
14+
15+
configure KEYWORD2
16+
start KEYWORD2
17+
stop KEYWORD2
18+
restart KEYWORD2
19+
clear KEYWORD2
20+
getCounter KEYWORD2
21+
configure KEYWORD2
22+
setClock KEYWORD2
23+
setInterrupt KEYWORD2
24+
setReset KEYWORD2
25+
WDT_OFF KEYWORD2
26+
WDT_128HZ KEYWORD2
27+
WDT_16 KEYWORD2
28+
WDT_1HZ KEYWORD2
29+
WDT1_16HZ KEYWORD2
30+
31+
#######################################
32+
# Constants (LITERAL1)
33+
#######################################

0 commit comments

Comments
 (0)