Skip to content

Commit e1a7d9b

Browse files
committed
Add examples
1 parent 331b8d7 commit e1a7d9b

File tree

6 files changed

+344
-11
lines changed

6 files changed

+344
-11
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
Author: Adam Garbo
3+
Created: July 31st, 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+
14+
On the sixth timeout event, the WDT will issue a system reset, and the
15+
program will start over from the beginning.
16+
17+
This example is based on the Ambiq SDK 2.4.2 watchdog.c example.
18+
*/
19+
20+
#include <WDT.h>
21+
22+
APM3_WDT wdt;
23+
24+
volatile bool watchdogFlag = false; // Watchdog Timer ISR flag
25+
volatile int watchdogCounter = 0; // Watchdog interrupt counter
26+
27+
unsigned long currentMillis = 0,
28+
previousMillis = 0;
29+
30+
void setup() {
31+
32+
Serial.begin(115200);
33+
34+
Serial.println("Artemis Watchdog Timer Example");
35+
36+
// Configure the watchdog
37+
wdt.configure(); // Default interrupt: 5 seconds. Default reset: 15 seconds
38+
wdt.enable(); // Enable the watchdog
39+
}
40+
41+
void loop() {
42+
43+
// Check for watchdog interrupts
44+
if (watchdogFlag) {
45+
46+
// Calculate duration between watchdog interrupts
47+
currentMillis = millis() - previousMillis;
48+
previousMillis = millis();
49+
50+
Serial.print("Interrupt: "); Serial.print(watchdogCounter);
51+
Serial.print(" Period: "); Serial.println(currentMillis); Serial.print(" ms");
52+
}
53+
54+
watchdogFlag = false; // Clear watchdog flag
55+
delay(10);
56+
}
57+
58+
// Interrupt handler for the watchdog
59+
extern "C" void am_watchdog_isr(void) {
60+
61+
// Clear the watchdog interrupt
62+
wdt.clear();
63+
64+
// Catch the first four watchdog interrupts, but let the fifth through untouched
65+
if ( watchdogCounter < 4 ) {
66+
wdt.restart(); // "Pet" the dog
67+
}
68+
else {
69+
digitalWrite(LED_BUILTIN, HIGH); // Visual indication of imminent system reset
70+
}
71+
72+
watchdogFlag = true; // Set watchdog flag
73+
watchdogCounter++; // Increment watchdog interrupt counter
74+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Author: Adam Garbo
3+
Created: July 31st, 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 code will configure the watchdog for both interrupt and reset generation,
10+
and immediately start the watchdog timer.
11+
12+
The watchdog ISR provided will 'pet' the watchdog four times. On the fifth
13+
interrupt, the watchdog will not be pet, so the 'reset' action can occur.
14+
15+
On the sixth timeout event, the WDT will issue a system reset, and the
16+
program will start over from the beginning.
17+
18+
This example is based on the Ambiq SDK 2.4.2 watchdog.c example.
19+
*/
20+
21+
#include <WDT.h>
22+
23+
APM3_WDT wdt;
24+
25+
volatile bool watchdogFlag = false; // Watchdog Timer ISR flag
26+
volatile int watchdogCounter = 0; // Watchdog interrupt counter
27+
28+
unsigned long currentMillis = 0,
29+
previousMillis = 0;
30+
31+
void setup()
32+
{
33+
Serial.begin(115200);
34+
35+
Serial.println("Artemis Watchdog Timer Example");
36+
37+
// Configure the watchdog
38+
wdt.configure(); // Default interrupt: 5 seconds. Default reset: 15 seconds
39+
wdt.start(); // Enable the watchdog
40+
}
41+
42+
void loop()
43+
{
44+
// Check for watchdog interrupts
45+
if (watchdogFlag)
46+
{
47+
// Calculate duration between watchdog interrupts
48+
currentMillis = millis() - previousMillis;
49+
previousMillis = millis();
50+
51+
Serial.print("Interrupt: "); Serial.print(watchdogCounter);
52+
Serial.print(" Period: "); Serial.print(currentMillis); Serial.println(" ms");
53+
}
54+
watchdogFlag = false; // Clear watchdog flag
55+
delay(10);
56+
}
57+
58+
// Interrupt handler for the watchdog
59+
extern "C" void am_watchdog_isr(void)
60+
{
61+
// Clear the watchdog interrupt
62+
wdt.clear();
63+
64+
// Catch the first four watchdog interrupts, but let the fifth through untouched
65+
if ( watchdogCounter < 4 )
66+
{
67+
wdt.restart(); // "Pet" the dog
68+
}
69+
else
70+
{
71+
digitalWrite(LED_BUILTIN, HIGH); // Visual indication of imminent system reset
72+
}
73+
74+
watchdogFlag = true; // Set watchdog flag
75+
watchdogCounter++; // Increment watchdog interrupt counter
76+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
/*
2+
Author: Adam Garbo
3+
Created: July 31st, 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 code is configured to trigger the RTC alarm every minute and enter
13+
deep sleep between interrupts. Alarm interupts also restart the WDT and reset
14+
the watchdog counter.
15+
16+
If the WDT is not restarted after 75 seconds, a system reset will occur.
17+
*/
18+
19+
#include <RTC.h>
20+
#include <WDT.h>
21+
22+
APM3_RTC rtc;
23+
APM3_WDT wdt;
24+
25+
volatile bool alarmFlag = false; // RTC ISR flag
26+
volatile bool watchdogFlag = false; // Watchdog Timer ISR flag
27+
volatile int watchdogCounter = 0; // Watchdog interrupt counter
28+
29+
void setup()
30+
{
31+
Serial.begin(115200);
32+
33+
Serial.println("Artemis Watchdog Low Power Example");
34+
35+
// Set the RTC's alarm
36+
rtc.setAlarm(0, 0, 0, 0, 0, 0); // Set alarm (hund, ss, mm, hh, dd, mm)
37+
rtc.setAlarmMode(6); // Set the RTC alarm to trigger every minute
38+
rtc.attachInterrupt(); // Attach RTC alarm interrupt
39+
40+
// Configure the watchdog
41+
wdt.configure(); // Default interrupt: 5 seconds. Default reset: 15 seconds
42+
43+
// Enable the watchdog
44+
wdt.enable();
45+
}
46+
47+
void loop()
48+
{
49+
// Check for alarm interrupt
50+
if (alarmFlag)
51+
{
52+
Serial.print("Alarm triggered: ");
53+
printDateTime(); // Print RTC's date and time
54+
alarmFlag = false;
55+
56+
wdt.restart(); // "Pet" the dog
57+
watchdogCounter = 0; // Reset watchdog interrupt counter
58+
}
59+
60+
// Check for watchdog interrupt
61+
if (watchdogFlag)
62+
{
63+
Serial.print("Watchdog triggered: ");
64+
printDateTime(); // Print RTC's date and time
65+
watchdogFlag = false; // Clear watchdog flag
66+
}
67+
68+
goToSleep(); // Enter deep sleep
69+
70+
}
71+
72+
// Print the RTC's current date and time
73+
void printDateTime()
74+
{
75+
rtc.getTime();
76+
Serial.printf("20%02d-%02d-%02d %02d:%02d:%02d.%02d\n",
77+
rtc.year, rtc.month, rtc.dayOfMonth,
78+
rtc.hour, rtc.minute, rtc.seconds, rtc.hundredths);
79+
}
80+
81+
// Power down gracefully
82+
void goToSleep()
83+
{
84+
// Disable UART
85+
Serial.end();
86+
87+
// Disable ADC
88+
power_adc_disable();
89+
90+
// Force the peripherals off
91+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM0);
92+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM1);
93+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM2);
94+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM3);
95+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM4);
96+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_IOM5);
97+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_ADC);
98+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART0);
99+
am_hal_pwrctrl_periph_disable(AM_HAL_PWRCTRL_PERIPH_UART1);
100+
101+
// Disable all pads
102+
for (int x = 0 ; x < 50 ; x++)
103+
am_hal_gpio_pinconfig(x, g_AM_HAL_GPIO_DISABLE);
104+
105+
//Power down Flash, SRAM, cache
106+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); // Turn off CACHE
107+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); // Turn off everything but lower 512k
108+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); // Turn off everything but lower 64k
109+
//am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)
110+
111+
// Keep the 32kHz clock running for RTC
112+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
113+
am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ);
114+
115+
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP); // Sleep forever
116+
117+
// And we're back!
118+
wakeUp();
119+
}
120+
121+
// Power up gracefully
122+
void wakeUp()
123+
{
124+
// Power up SRAM, turn on entire Flash
125+
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
126+
127+
// Go back to using the main clock
128+
am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
129+
am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
130+
131+
// Enable ADC
132+
ap3_adc_setup();
133+
134+
// Enable Serial
135+
Serial.begin(115200);
136+
}
137+
138+
// Interrupt handler for the RTC
139+
extern "C" void am_rtc_isr(void)
140+
{
141+
// Clear the RTC alarm interrupt
142+
am_hal_rtc_int_clear(AM_HAL_RTC_INT_ALM);
143+
144+
alarmFlag = true; // Set alarm flag
145+
}
146+
147+
// Interrupt handler for the watchdog.
148+
extern "C" void am_watchdog_isr(void) {
149+
150+
// Clear the watchdog interrupt
151+
wdt.clear();
152+
153+
// Perform system reset after 15 watchdog interrupts (15 * 5 seconds = 75 seconds)
154+
if ( watchdogCounter < 20 ) {
155+
wdt.restart(); // "Pet" the dog
156+
}
157+
else {
158+
digitalWrite(LED_BUILTIN, HIGH); // Visual indication of system reset
159+
}
160+
161+
watchdogFlag = true; // Set the watchdog flag
162+
watchdogCounter++; // Increment watchdog interrupt counter
163+
}

libraries/WDT/keywords.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ WDT KEYWORD1
1212
# Methods and Functions (KEYWORD2)
1313
#######################################
1414

15+
configure KEYWORD2
16+
start KEYWORD2
17+
stop KEYWORD2
18+
restart KEYWORD2
19+
clear KEYWORD2
1520

1621
#######################################
1722
# Constants (LITERAL1)

libraries/WDT/src/WDT.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,27 @@ APM3_WDT::APM3_WDT()
1313

1414

1515
// Configure the watchdog
16-
void APM3_WDT::configure(clock, interrupt, reset)
16+
void APM3_WDT::configure()
1717
{
18-
18+
am_hal_wdt_init(&watchdogConfig);
1919
}
2020

2121
// Enable the watchdog
22-
void APM3_WDT::enable()
22+
void APM3_WDT::start()
2323
{
2424
// Enable the interrupt for the watchdog in the NVIC
2525
NVIC_EnableIRQ(WDT_IRQn);
2626
am_hal_wdt_start();
2727
}
2828

2929
// Disable the watchdog
30-
void APM3_WDT::disable()
30+
void APM3_WDT::stop()
3131
{
32-
// Enable the interrupt for the watchdog in the NVIC
32+
// Disable the interrupt for the watchdog in the NVIC
3333
NVIC_DisableIRQ(WDT_IRQn);
34-
am_hal_wdt_int_disable();
34+
// Disable the watchdog timer tick by clearing the 'enable' bit in the
35+
// watchdog configuration register
36+
am_hal_wdt_halt();
3537
}
3638

3739
// Restart the watchdog

libraries/WDT/src/WDT.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,24 @@ class APM3_WDT
88
public:
99
APM3_WDT();
1010

11-
void configure(uint32_t clock, uint16_t interrupt, uint16_t reset); // Configure watchdog
12-
void enable(); // Enable the watchdog
13-
void disable(); // Disable the watchdog
14-
void restart(); // Restart the watchdog
15-
void clear() // Clear the watchdog interrupt
11+
// Watchdog timer configuration structure
12+
am_hal_wdt_config_t watchdogConfig = {
13+
14+
// Configuration values for generated watchdog timer event.
15+
.ui32Config = AM_HAL_WDT_LFRC_CLK_16HZ | AM_HAL_WDT_ENABLE_RESET | AM_HAL_WDT_ENABLE_INTERRUPT,
16+
17+
// Number of watchdog timer ticks allowed before a watchdog interrupt event is generated
18+
.ui16InterruptCount = 16 * 5, // Set WDT interrupt timeout for 5 seconds (16 * 5) / 16 = 5
19+
20+
// Number of watchdog timer ticks allowed before the watchdog will issue a system reset
21+
.ui16ResetCount = 16 * 10 // Set WDT reset timeout for 15 seconds (16 * 10 ) / 16 = 10
22+
};
23+
24+
void configure(); // Configure watchdog
25+
void start(); // Starts the watchdog timer
26+
void stop(); // Disables the watchdog timer
27+
void restart(); // Restarts the watchdog timer ("Pets" the dog)
28+
void clear(); // Clears the watchdog interrupt
1629

1730
};
1831
#endif //WDT_H

0 commit comments

Comments
 (0)