Files
khoih-prog_RPI_PICO_TimerIn…/src_cpp/RPi_Pico_ISR_Timer.h
T
Khoi Hoang 5e6d0251b3 Releases v1.0.0 to support RP2040-based boards
### Initial Releases v1.0.0

1. Initial coding to support RP2040-based boards such as RASPBERRY_PI_PICO. etc. using [Earle Philhower's arduino-pico core](https://github.com/earlephilhower/arduino-pico)
2021-05-11 20:58:08 -04:00

190 lines
6.8 KiB
C++

/****************************************************************************************************************************
RPi_Pico_ISR_Timer.h
For RP2040-based boards such as RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040 and GENERIC_RP2040.
Written by Khoi Hoang
Built by Khoi Hoang https://github.com/khoih-prog/RPI_PICO_TimerInterrupt
Licensed under MIT license
The RPI_PICO system timer peripheral provides a global microsecond timebase for the system, and generates
interrupts based on this timebase. It supports the following features:
• A single 64-bit counter, incrementing once per microsecond
• This counter can be read from a pair of latching registers, for race-free reads over a 32-bit bus.
• Four alarms: match on the lower 32 bits of counter, IRQ on match: TIMER_IRQ_0-TIMER_IRQ_3
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
unsigned long miliseconds), you just consume only one RPI_PICO timer and avoid conflicting with other cores' tasks.
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
Based on SimpleTimer - A timer library for Arduino.
Author: mromani@ottotecnica.com
Copyright (c) 2010 OTTOTECNICA Italy
Based on BlynkTimer.h
Author: Volodymyr Shymanskyy
Version: 1.0.0
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 11/05/2021 Initial coding to support RP2040-based boards such as RASPBERRY_PI_PICO. etc.
*****************************************************************************************************************************/
#pragma once
#ifndef ISR_TIMER_GENERIC_H
#define ISR_TIMER_GENERIC_H
#if !( defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || defined(ARDUINO_GENERIC_RP2040) )
#error This code is intended to run on the RASPBERRY_PI_PICO platform! Please check your Tools->Board setting.
#endif
#ifndef RPI_PICO_TIMER_INTERRUPT_VERSION
#define RPI_PICO_TIMER_INTERRUPT_VERSION "RPi_Pico_TimerInterrupt v1.0.0"
#endif
#include "TimerInterrupt_Generic_Debug.h"
#include <stddef.h>
#include <inttypes.h>
#include "pico/multicore.h"
#if defined(ARDUINO)
#if ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#endif
#define FLAG_VALUE 0xDEADBEEF
#define RPI_PICO_ISR_Timer RPI_PICO_ISRTimer
typedef void (*timer_callback)();
typedef void (*timer_callback_p)(void *);
class RPI_PICO_ISR_Timer
{
public:
// maximum number of timers
#define RPI_PICO_MAX_TIMERS 16
#define RPI_PICO_RUN_FOREVER 0
#define RPI_PICO_RUN_ONCE 1
// constructor
RPI_PICO_ISR_Timer();
void init();
// this function must be called inside loop()
void run();
// Timer will call function 'f' every 'd' milliseconds forever
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setInterval(unsigned long d, timer_callback f);
// Timer will call function 'f' with parameter 'p' every 'd' milliseconds forever
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setInterval(unsigned long d, timer_callback_p f, void* p);
// Timer will call function 'f' after 'd' milliseconds one time
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setTimeout(unsigned long d, timer_callback f);
// Timer will call function 'f' with parameter 'p' after 'd' milliseconds one time
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setTimeout(unsigned long d, timer_callback_p f, void* p);
// Timer will call function 'f' every 'd' milliseconds 'n' times
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setTimer(unsigned long d, timer_callback f, unsigned n);
// Timer will call function 'f' with parameter 'p' every 'd' milliseconds 'n' times
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n);
// updates interval of the specified timer
bool changeInterval(unsigned numTimer, unsigned long d);
// destroy the specified timer
void deleteTimer(unsigned numTimer);
// restart the specified timer
void restartTimer(unsigned numTimer);
// returns true if the specified timer is enabled
bool isEnabled(unsigned numTimer);
// enables the specified timer
void enable(unsigned numTimer);
// disables the specified timer
void disable(unsigned numTimer);
// enables all timers
void enableAll();
// disables all timers
void disableAll();
// enables the specified timer if it's currently disabled, and vice-versa
void toggle(unsigned numTimer);
// returns the number of used timers
unsigned getNumTimers();
// returns the number of available timers
unsigned getNumAvailableTimers()
{
return RPI_PICO_MAX_TIMERS - numTimers;
};
private:
// deferred call constants
#define RPI_PICO_DEFCALL_DONTRUN 0 // don't call the callback function
#define RPI_PICO_DEFCALL_RUNONLY 1 // call the callback function but don't delete the timer
#define RPI_PICO_DEFCALL_RUNANDDEL 2 // call the callback function and delete the timer
// low level function to initialize and enable a new timer
// returns the timer number (numTimer) on success or
// -1 on failure (f == NULL) or no free timers
int setupTimer(unsigned long d, void* f, void* p, bool h, unsigned n);
// find the first available slot
int findFirstFreeSlot();
typedef struct
{
unsigned long prev_millis; // value returned by the millis() function in the previous run() call
void* callback; // pointer to the callback function
void* param; // function parameter
bool hasParam; // true if callback takes a parameter
unsigned long delay; // delay value
unsigned maxNumRuns; // number of runs to be executed
unsigned numRuns; // number of executed runs
bool enabled; // true if enabled
unsigned toBeCalled; // deferred function call (sort of) - N.B.: only used in run()
} timer_t;
volatile timer_t timer[RPI_PICO_MAX_TIMERS];
// actual number of timers in use (-1 means uninitialized)
volatile int numTimers;
};
#endif // ISR_TIMER_GENERIC_H