Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.

Commit 792fc4f

Browse files
authored
Add example 50ms_HWTimer
1 parent 05d7a5a commit 792fc4f

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/****************************************************************************************************************************
2+
50ms_HWTimer.ino
3+
For MBED RP2040-based boards such as Nano_RP2040_Connect, RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040 and GENERIC_RP2040.
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/RPI_PICO_TimerInterrupt
7+
Licensed under MIT license
8+
9+
The RPI_PICO system timer peripheral provides a global microsecond timebase for the system, and generates
10+
interrupts based on this timebase. It supports the following features:
11+
• A single 64-bit counter, incrementing once per microsecond
12+
• This counter can be read from a pair of latching registers, for race-free reads over a 32-bit bus.
13+
• Four alarms: match on the lower 32 bits of counter, IRQ on match: TIMER_IRQ_0-TIMER_IRQ_3
14+
15+
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
16+
unsigned long miliseconds), you just consume only one RPI_PICO timer and avoid conflicting with other cores' tasks.
17+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
18+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
19+
This important feature is absolutely necessary for mission-critical tasks.
20+
21+
Based on SimpleTimer - A timer library for Arduino.
22+
23+
Copyright (c) 2010 OTTOTECNICA Italy
24+
25+
Based on BlynkTimer.h
26+
Author: Volodymyr Shymanskyy
27+
28+
Version: 1.0.0
29+
30+
Version Modified By Date Comments
31+
------- ----------- ---------- -----------
32+
1.0.0 K Hoang 07/06/2021 Initial coding to support MBED RP2040-based boards such as RASPBERRY_PI_PICO. etc.
33+
*****************************************************************************************************************************/
34+
35+
/*
36+
Notes:
37+
Special design is necessary to share data between interrupt code and the rest of your program.
38+
Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
39+
variable can not spontaneously change. Because your function may change variables while your program is using them,
40+
the compiler needs this hint. But volatile alone is often not enough.
41+
When accessing shared variables, usually interrupts must be disabled. Even with volatile,
42+
if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
43+
If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
44+
or the entire sequence of your code which accesses the data.
45+
*/
46+
47+
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
48+
defined(ARDUINO_GENERIC_RP2040) ) && defined(ARDUINO_ARCH_MBED)
49+
#define USING_MBED_RPI_PICO_TIMER_INTERRUPT true
50+
#else
51+
#error This code is intended to run on the MBED RASPBERRY_PI_PICO platform! Please check your Tools->Board setting.
52+
#endif
53+
54+
// These define's must be placed at the beginning before #include "TimerInterrupt_Generic.h"
55+
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
56+
#define _TIMERINTERRUPT_LOGLEVEL_ 4
57+
58+
#include "MBED_RPi_Pico_TimerInterrupt.h"
59+
60+
#ifndef LED_BUILTIN
61+
#define LED_BUILTIN 25 // Pin LED_BUILTIN mapped to pin GPIO25 of RPI_PICO, control on-board LED
62+
#endif
63+
64+
#define PIN_D1 1 // Pin D1 mapped to pin GPIO1 of RPI_PICO
65+
66+
volatile uint32_t Timer0Count = 0;
67+
68+
uint32_t startTime;
69+
70+
// Never use Serial.print inside this mbed ISR. Will hang the system
71+
void TimerHandler0(uint alarm_num)
72+
{
73+
static bool toggle0 = false;
74+
75+
///////////////////////////////////////////////////////////
76+
// Always call this for MBED RP2040 before processing ISR
77+
TIMER_ISR_START(alarm_num);
78+
///////////////////////////////////////////////////////////
79+
80+
// Flag for checking to be sure ISR is working as Serial.print is not OK here in ISR
81+
Timer0Count++;
82+
83+
//timer interrupt toggles pin LED_BUILTIN
84+
digitalWrite(LED_BUILTIN, toggle0);
85+
toggle0 = !toggle0;
86+
87+
////////////////////////////////////////////////////////////
88+
// Always call this for MBED RP2040 after processing ISR
89+
TIMER_ISR_END(alarm_num);
90+
////////////////////////////////////////////////////////////
91+
}
92+
93+
94+
void printResult(uint32_t currTime)
95+
{
96+
static uint32_t lastCount = 0;
97+
98+
Serial.print(F("Time = ")); Serial.print(currTime);
99+
Serial.print(F(", Timer0Count = ")); Serial.print(Timer0Count);
100+
Serial.print(F(", Timer Duration (ms) = ")); Serial.println( (currTime - startTime) / (Timer0Count - lastCount) );
101+
102+
lastCount = Timer0Count;
103+
}
104+
105+
#define TIMER0_INTERVAL_MS 50
106+
107+
// Init ESP32 timer 0
108+
MBED_RPI_PICO_Timer ITimer0(0);
109+
110+
void setup()
111+
{
112+
pinMode(LED_BUILTIN, OUTPUT);
113+
pinMode(PIN_D1, OUTPUT);
114+
115+
Serial.begin(115200);
116+
while (!Serial);
117+
118+
delay(100);
119+
120+
Serial.print(F("\nStarting 50ms_HWTimer on ")); Serial.println(BOARD_NAME);
121+
Serial.println(MBED_RPI_PICO_TIMER_INTERRUPT_VERSION);
122+
123+
// Interval in microsecs
124+
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0))
125+
{
126+
Serial.print(F("Starting ITimer0 OK, millis() = ")); Serial.println(millis());
127+
}
128+
else
129+
Serial.println(F("Can't set ITimer0. Select another freq. or timer"));
130+
131+
startTime = millis();
132+
}
133+
134+
#define CHECK_INTERVAL_MS 10000L
135+
136+
void loop()
137+
{
138+
static uint32_t currTime;
139+
140+
currTime = millis();
141+
142+
if (currTime - startTime > CHECK_INTERVAL_MS)
143+
{
144+
printResult(currTime);
145+
startTime = currTime;
146+
}
147+
}

0 commit comments

Comments
 (0)