Revert "latest :)"

This reverts commit 288a1ccd09.
This commit is contained in:
2024-01-20 15:04:46 +01:00
parent 4b9e47433f
commit 8f2516faff
4218 changed files with 1345255 additions and 209 deletions
@@ -0,0 +1,512 @@
#ifndef PIN_H
#define PIN_H
// this class doesn't outperform fastgpio but is works with AtmelMega
#include <Arduino.h>
#define DDR_HIGH (*_DDR |= _offset) ///< Set the DDR register to HIGH for the pin
#define DDR_TOGGLE (*_DDR ^= _offset) ///< Set the DDR register to the inverse for the pin
#define DDR_LOW (*_DDR &= _ioffset) ///< Set the DDR register to LOW for the pin
#define PORT_HIGH (*_PORT |= _offset) ///< Set the PORT register to HIGH for the pin
#define PORT_TOGGLE (*_PORT ^= _offset) ///< Set the PORT register to the inverse for the pin
#define PORT_LOW (*_PORT &= _ioffset) ///< Set the PORT register to LOW for the pin
#define DDR_ON (*_DDR & _offset) ///< Get the DDR register for the pin (HIGH, LOW) with other pins forced to 0
#define DDR_OFF (*_DDR | _ioffset) ///< Get the DDR register for the pin (HIGH, LOW) with other pins forced to 1
#define PORT_ON (*_PORT & _offset) ///< Get the PORT register for the pin (HIGH, LOW) with other pins forced to 0
#define PORT_OFF (*_PORT | _ioffset) ///< Get the PORT register for the pin (HIGH, LOW) with other pins forced to 1
#define PIN_ON (*_PIN & _offset) ///< Get the PIN register for the pin (HIGH, LOW) with other pins forced to 0
#define PIN_OFF (*_PIN | _ioffset) ///< Get the PIN register for the pin (HIGH, LOW) with other pins forced to 1
class Pin
{
public:
Pin(uint8_t number)
{
_number = number;
_offset = digitalPinToBitMask(_number);
_ioffset = ~_offset;
_timer = digitalPinToTimer(_number);
_PIN = portInputRegister(digitalPinToPort(_number));
_PORT = portOutputRegister(digitalPinToPort(_number));
_DDR = portModeRegister(digitalPinToPort(_number));
}
/**
Custom board constructor
getAnalogValue() and setDutyCycle(int value) not supported
@param number pin number written on board
@param offset bit mask used to access pin in registers
@param timer timer for pin
@param PIN input register for pin
@param PORT data register for pin
@param DDR data direction register for pin
*/
Pin(uint8_t number, uint8_t offset, uint8_t timer, volatile uint8_t *PIN, volatile uint8_t *PORT, volatile uint8_t *DDR)
{
_number = number;
_offset = offset;
_ioffset = ~_offset;
_timer = timer;
_PIN = PIN;
_PORT = PORT;
_DDR = DDR;
}
// ################################# Operators #################################
/**
Get the value of the pin from the PIN register
@return true if the value of the pin is HIGH, false otherwise
*/
operator bool() const
{
return bool(PIN_ON);
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
Pin &operator=(uint8_t state)
{
uint8_t oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
return *this;
}
// ################################# Getters #################################
/**
Get the pin number
@return pin number
*/
uint8_t getNumber()
{
return _number;
}
/**
Get the pin offset
@return pin offset
*/
uint8_t getOffset()
{
return _offset;
}
/**
Get the inverse pin offset
@return inverse pin offset
*/
uint8_t getInverseOffset()
{
return _ioffset;
}
/**
Get the pin timer
@return pin timer
*/
uint8_t getTimer()
{
return _timer;
}
/**
Get a pointer to the PIN register
@return pointer to the PIN register
*/
volatile uint8_t *getPIN()
{
return _PIN;
}
/**
Get a pointer to the PORT register
@return pointer to the PORT register
*/
volatile uint8_t *getPORT()
{
return _PORT;
}
/**
Get a pointer to the DDR register
@return pointer to the DDR register
*/
volatile uint8_t *getDDR()
{
return _DDR;
}
/**
Get the mode of the pin from the DDR register
@return mode of the pin (OUTPUT, INPUT)
*/
uint8_t getMode()
{
if (DDR_ON)
{
return OUTPUT;
}
else
{
return INPUT;
}
}
/**
Get the state of the pin from the PORT register
@return state of the pin (HIGH, LOW)
*/
uint8_t getState()
{
if (PORT_ON)
{
return HIGH;
}
else
{
return LOW;
}
}
/**
Get the value of the pin from the PIN register
@return value of the pin (HIGH, LOW)
*/
uint8_t getValue()
{
if (PIN_ON)
{
return HIGH;
}
else
{
return LOW;
}
}
/**
Get the analog value of the pin
@return analog value of the pin (0-1023)
*/
uint16_t getAnalogValue()
{
return analogRead(_number);
}
/**
Set the pin mode and pin state
@param mode the mode of the pin (OUTPUT, INPUT)
@param state the state of the pin (HIGH, LOW)
*/
void set(uint8_t mode, uint8_t state)
{
uint8_t oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin mode
@param mode the mode of the pin (OUTPUT, INPUT)
*/
void setMode(uint8_t mode)
{
uint8_t oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
void setState(uint8_t state)
{
uint8_t oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
// #################### Input ####################
void setInput()
{
uint8_t oldSREG = SREG;
cli();
DDR_LOW;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to on
*/
void setPullupOn()
{
uint8_t oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to off
*/
void setPullupOff()
{
uint8_t oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to on
*/
void setInputPullupOn()
{
uint8_t oldSREG = SREG;
cli();
DDR_LOW;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to off
*/
void setInputPullupOff()
{
uint8_t oldSREG = SREG;
cli();
DDR_LOW;
PORT_LOW;
SREG = oldSREG;
}
// #################### Output ####################
/**
Set the pin mode to output
*/
void setOutput()
{
uint8_t oldSREG = SREG;
cli();
DDR_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to HIGH
*/
void setHigh()
{
uint8_t oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to LOW
*/
void setLow()
{
uint8_t oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to HIGH
*/
void setOutputHigh()
{
uint8_t oldSREG = SREG;
cli();
DDR_HIGH;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to LOW
*/
void setOutputLow()
{
uint8_t oldSREG = SREG;
cli();
DDR_HIGH;
PORT_LOW;
SREG = oldSREG;
}
/**
Set the PWM duty cycle
@param value the duty cycle (0-255)
*/
void setDutyCycle(int value)
{
analogWrite(_number, value);
}
// ################################# Utilities #################################
/**
Toggle the pin mode (OUTPUT -> INPUT, INPUT -> OUTPUT)
*/
void toggleMode()
{
uint8_t oldSREG = SREG;
cli();
DDR_TOGGLE;
SREG = oldSREG;
}
/**
Toggle the pin state (HIGH -> LOW, LOW -> HIGH)
*/
void toggleState()
{
uint8_t oldSREG = SREG;
cli();
PORT_TOGGLE;
SREG = oldSREG;
}
// #################### RC Timer ####################
/**
Set the pin mode to input and decrement a counter until the pin goes HIGH or the counter reaches 0 then set the pin mode to output and return the counter value
@param count the initial value for the counter to start at (0-65535)
@return the value remaining on the counter when the pin state went to HIGH or 0 if the counter reached 0
*/
volatile unsigned int rcTimer(volatile unsigned int count)
{
uint8_t status;
asm volatile(
// Save interupt status and disable interupts
"in %[status], __SREG__ \n\t" // Store current interupt status in variable 's'
"cli \n\t" // Disable interupts
// Set Pin to input mode to start charging capacitor
"ld __tmp_reg__, %a[_DDR] \n\t" // Load the DDR register into r0 (__tmp_reg__)
"and __tmp_reg__, %[_ioffset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
"st %a[_DDR], __tmp_reg__ \n\t" // Store r0 (__tmp_reg__) in the DDR register
// Count time before Pin becomes high
"loop%=: \n\t" // Label for looping
//"ld __tmp_reg__,%a[_PIN] \n\t" // Load the PIN register into r0 (__tmp_reg__)
"and __tmp_reg__, %[_offset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
"brne end%= \n\t" // End the loop if r0 (__tmp_reg__) is not equal to zero by branching to label 'end'
"dec %[count] \n\t" // Decrement the value of 'count' by one
"brne loop%= \n\t" // If the value of 'count' is not equal to zero continue the loop by branching to label 'loop'
// Done counting
"end%=: \n\t" // Label for ending loop
// Set Pin to output mode to start discharging capacitor
"ld __tmp_reg__, %a[_DDR] \n\t" // Load the DDR register into r0 (__tmp_reg__)
"or __tmp_reg__, %[_offset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
"st %a[_DDR], __tmp_reg__ \n\t" // Store r0 (__tmp_reg__) in the PORT register
// Restore interupt status
"out __SREG__, %[status] \n\t" // Load interupt status from variable 's'
// Outputs
:
[ count ] "+r"(count), // The value the counter was at when the pin went high
[ status ] "=&r"(status) // The interupt status
// Inputs
:
[ _DDR ] "e"(_DDR), // The address of the DDR register for the pin
[ _PIN ] "e"(_PIN), // The address of the PIN register for the pin
[ _offset ] "r"(_offset), // The bit mask used to access pin in registers
[ _ioffset ] "r"(_ioffset) // The inverse bit mask used to access pin in registers
);
return count;
}
private:
uint8_t _number;
uint8_t _offset;
uint8_t _ioffset;
uint8_t _timer;
volatile uint8_t *_PIN;
volatile uint8_t *_PORT;
volatile uint8_t *_DDR;
};
#endif
@@ -0,0 +1,469 @@
#ifndef PIN_GROUP_H
#define PIN_GROUP_H
#include "Pin.h"
/**
Class for simultaneous operations on Arduino I/O pins
*/
class PinGroup
{
public:
template <size_t N>
PinGroup(Pin (&pins)[N])
{
_offset = pins[0].getOffset();
_PIN = pins[0].getPIN();
_PORT = pins[0].getPORT();
_DDR = pins[0].getDDR();
_numbers[0] = pins[0].getNumber();
_valid = true;
for (int i = 1; i < N; i++)
{
if (_DDR != pins[i].getDDR())
{
_valid = false;
}
_offset |= pins[i].getOffset();
_numbers[i] = pins[i].getNumber();
}
_ioffset = ~_offset;
}
// ################################# Operators #################################
/**
Compare the value of the pin
@param value the state of the pin (HIGH, LOW)
@return true if the value of all of the pins are equal to the value passed in, false otherwise
*/
bool operator==(uint8_t value)
{
uint8_t status = *_PIN;
if ((status & _offset) == _offset)
{
return (value == HIGH);
}
else if ((status | _ioffset) == _ioffset)
{
return (value == LOW);
}
else
{
return false;
}
}
/**
Compare the value of the pin
@param value the state of the pin (HIGH, LOW)
@return true if the value of all of the pins are not equal to the value passed in, false otherwise
*/
bool operator!=(uint8_t value)
{
uint8_t status = *_PIN;
if ((status & _offset) == _offset)
{
return (value == LOW);
}
else if ((status | _ioffset) == _ioffset)
{
return (value == HIGH);
}
else
{
return false;
}
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
PinGroup &operator=(uint8_t state)
{
oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
return *this;
}
// ################################# Getters #################################
/**
Get the pin numbers
@return array of pin numbers
*/
uint8_t *getNumbers()
{
return _numbers;
}
/**
Get the pin offset
@return pin offset
*/
uint8_t getOffset()
{
return _offset;
}
/**
Get the inverse pin offset
@return inverse pin offset
*/
uint8_t getInverseOffset()
{
return _ioffset;
}
/**
Get a pointer to the PIN register
@return pointer to the PIN register
*/
volatile uint8_t *getPIN()
{
return _PIN;
}
/**
Get a pointer to the PORT register
@return pointer to the PORT register
*/
volatile uint8_t *getPORT()
{
return _PORT;
}
/**
Get a pointer to the DDR register
@return pointer to the DDR register
*/
volatile uint8_t *getDDR()
{
return _DDR;
}
/**
Get the mode of the pin from the DDR register
@return mode of the pin (OUTPUT, INPUT, -1)
*/
uint8_t getMode()
{
uint8_t status = *_DDR;
if ((status & _offset) == _offset)
{
return OUTPUT;
}
else if ((status | _ioffset) == _ioffset)
{
return INPUT;
}
else
{
return -1;
}
}
/**
Get the state of the pin from the PORT register
@return state of the pin (HIGH, LOW, -1)
*/
uint8_t getState()
{
uint8_t status = *_PORT;
if ((status & _offset) == _offset)
{
return HIGH;
}
else if ((status | _ioffset) == _ioffset)
{
return LOW;
}
else
{
return -1;
}
}
/**
Get the value of the pin from the PIN register
@return value of the pin (HIGH, LOW, -1)
*/
uint8_t getValue()
{
uint8_t status = *_PIN;
if ((status & _offset) == _offset)
{
return HIGH;
}
else if ((status | _ioffset) == _ioffset)
{
return LOW;
}
else
{
return -1;
}
}
/**
Check the group to ensure all pins use the same registers
@return true if the pins in the group all use the same registers, false otherwise
*/
bool isValid()
{
return _valid;
}
// ################################# Setters #################################
// #################### Generic ####################
/**
Set the pin mode and pin state
@param mode the mode of the pin (OUTPUT, INPUT)
@param state the state of the pin (HIGH, LOW)
*/
void set(uint8_t mode, uint8_t state)
{
oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin mode
@param mode the mode of the pin (OUTPUT, INPUT)
*/
void setMode(uint8_t mode)
{
oldSREG = SREG;
cli();
if (mode == INPUT)
{
DDR_LOW;
}
else
{
DDR_HIGH;
}
SREG = oldSREG;
}
/**
Set the pin state
@param state the state of the pin (HIGH, LOW)
*/
void setState(uint8_t state)
{
oldSREG = SREG;
cli();
if (state == LOW)
{
PORT_LOW;
}
else
{
PORT_HIGH;
}
SREG = oldSREG;
}
// #################### Input ####################
/**
Set the pin mode to input
*/
void setInput()
{
oldSREG = SREG;
cli();
DDR_LOW;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to on
*/
void setPullupOn()
{
oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin pullup resistor to off
*/
void setPullupOff()
{
oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to on
*/
void setInputPullupOn()
{
oldSREG = SREG;
cli();
DDR_LOW;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to input and the pin pullup resistor to off
*/
void setInputPullupOff()
{
oldSREG = SREG;
cli();
DDR_LOW;
PORT_LOW;
SREG = oldSREG;
}
// #################### Output ####################
/**
Set the pin mode to output
*/
void setOutput()
{
oldSREG = SREG;
cli();
DDR_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to HIGH
*/
void setHigh()
{
oldSREG = SREG;
cli();
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin output to LOW
*/
void setLow()
{
oldSREG = SREG;
cli();
PORT_LOW;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to HIGH
*/
void setOutputHigh()
{
oldSREG = SREG;
cli();
DDR_HIGH;
PORT_HIGH;
SREG = oldSREG;
}
/**
Set the pin mode to output and the pin output to LOW
*/
void setOutputLow()
{
oldSREG = SREG;
cli();
DDR_HIGH;
PORT_LOW;
SREG = oldSREG;
}
// ################################# Utilities #################################
// #################### Toggle ####################
/**
Toggle the pin mode (OUTPUT -> INPUT, INPUT -> OUTPUT)
*/
void toggleMode()
{
oldSREG = SREG;
cli();
DDR_TOGGLE;
SREG = oldSREG;
}
/**
Toggle the pin state (HIGH -> LOW, LOW -> HIGH)
*/
void toggleState()
{
oldSREG = SREG;
cli();
PORT_TOGGLE;
SREG = oldSREG;
}
private:
uint8_t _numbers[8];
uint8_t _offset;
uint8_t _ioffset;
bool _valid;
uint8_t oldSREG;
volatile uint8_t *_PIN;
volatile uint8_t *_PORT;
volatile uint8_t *_DDR;
};
@@ -0,0 +1,98 @@
#ifndef MACROS_H
#define MACROS_H
#include "../types.h"
// Macros for adding
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INCREMENT_(n) INC_ ##n
#define INCREMENT(n) INCREMENT_(n)
// Macros for subtracting
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DECREMENT_(n) DEC_ ##n
#define DECREMENT(n) DECREMENT_(n)
// compiler - & C quirks
#define FORCE_INLINE __attribute__((always_inline)) inline
#define _UNUSED __attribute__((unused))
// fallback noop
#define NOOP do{} while(0)
//Option testing
#define _CAT(a, ...) a ## __VA_ARGS__
#define SWITCH_ENABLED_ 1
#define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
// time
#define PENDING(NOW,SOON) ((long)(NOW-(SOON))<0)
#define ELAPSED(NOW,SOON) (!PENDING(NOW,SOON))
#define MMM_TO_MMS(MM_M) ((MM_M)/60.0f)
#define MMS_TO_MMM(MM_S) ((MM_S)*60.0f)
#define HOUR_MS ((millis_t)1000 * (millis_t)(60 * 60))
#define MIN_MS ((millis_t)1000 * (millis_t)(60))
#define SECS ((millis_t)1000)
// bit masks
#undef _BV
#define _BV(b) (1 << (b))
#define TEST(n,b) !!((n)&_BV(b))
#define SBI(n,b) (n |= _BV(b))
#define CBI(n,b) (n &= ~_BV(b))
#define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0)
#define _BV32(b) (1UL << (b))
#define TEST32(n,b) !!((n)&_BV32(b))
#define SBI32(n,b) (n |= _BV32(b))
#define CBI32(n,b) (n &= ~_BV32(b))
#define SIGN(a) ((a>0)-(a<0))
// math basics
#define WITHIN(V,L,H) ((V) >= (L) && (V) <= (H))
#define NUMERIC(a) WITHIN(a, '0', '9')
#define DECIMAL(a) (NUMERIC(a) || a == '.')
#define NUMERIC_SIGNED(a) (NUMERIC(a) || (a) == '-' || (a) == '+')
#define DECIMAL_SIGNED(a) (DECIMAL(a) || (a) == '-' || (a) == '+')
#define COUNT(a) (sizeof(a)/sizeof(*a))
#define ZERO(a) memset(a,0,sizeof(a))
#define COPY(a,b) memcpy(a,b,MIN(sizeof(a),sizeof(b)))
// #define M_PI 3.14159265358979323846f
#define RADIANS(d) ((d)*M_PI/180.0f)
#define DEGREES(r) ((r)*180.0f/M_PI)
#define CEILING(x,y) (((x) + (y) - 1) / (y))
// Macros for initializing arrays
#define ARRAY_6(v1, v2, v3, v4, v5, v6, ...) { v1, v2, v3, v4, v5, v6 }
#define ARRAY_5(v1, v2, v3, v4, v5, ...) { v1, v2, v3, v4, v5 }
#define ARRAY_4(v1, v2, v3, v4, ...) { v1, v2, v3, v4 }
#define ARRAY_3(v1, v2, v3, ...) { v1, v2, v3 }
#define ARRAY_2(v1, v2, ...) { v1, v2 }
#define ARRAY_1(v1, ...) { v1 }
#define _ARRAY_N(N, ...) ARRAY_ ##N(__VA_ARGS__)
#define ARRAY_N(N, ...) _ARRAY_N(N, __VA_ARGS__)
#define SPACE(A) " " << A << " "
#endif
@@ -0,0 +1,14 @@
#ifndef PPMATH_H
#define PPMATH_H
template <typename T>
T clamp(const T &value, const T &low, const T &high)
{
return value < low ? low : (value > high ? high : value);
}
#define RANGE(i, min, max) ((i > min) && (i < max)) ? true : false
#define NCLAMP(x, min, max) (x - min) / (max - min)
#endif
@@ -0,0 +1,136 @@
#ifndef TIMER_H
#define TIMER_H
#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif
#include "macros.h"
#ifndef TIMER_MAX_TASKS
#define TIMER_MAX_TASKS 0x10
#endif
template <
size_t max_tasks = TIMER_MAX_TASKS, /* max allocated tasks */
unsigned long (*time_func)() = millis /* time function for timer */
>
class Timer
{
public:
typedef bool (*handler_t)(void *opaque); /* task handler func signature */
/* Calls handler with opaque as argument in delay units of time */
bool
in(unsigned long delay, handler_t h, void *opaque = NULL)
{
return add_task(time_func(), delay, h, opaque);
}
/* Calls handler with opaque as argument at time */
bool
at(unsigned long time, handler_t h, void *opaque = NULL)
{
const unsigned long now = time_func();
return add_task(now, time - now, h, opaque);
}
/* Calls handler with opaque as argument every interval units of time */
bool
every(unsigned long interval, handler_t h, void *opaque = NULL)
{
return add_task(time_func(), interval, h, opaque, interval);
}
/* Ticks the timer forward - call this function in loop() */
void
tick()
{
tick(time_func());
}
/* Ticks the timer forward - call this function in loop() */
inline void
tick(unsigned long t)
{
for (size_t i = 0; i < max_tasks; ++i)
{
struct task *const task = &tasks[i];
const unsigned long duration = t - task->start;
if (task->handler && duration >= task->expires)
{
task->repeat = task->handler(task->opaque) && task->repeat;
if (task->repeat)
task->start = t;
else
remove(task);
}else{
}
}
}
private:
struct task
{
handler_t handler; /* task handler callback func */
void *opaque; /* argument given to the callback handler */
unsigned long start,
expires, /* when the task expires */
repeat; /* repeat task */
} tasks[max_tasks];
inline void
remove(struct task *task)
{
task->handler = NULL;
task->opaque = NULL;
task->start = 0;
task->expires = 0;
task->repeat = 0;
}
inline struct task *
next_task_slot()
{
for (size_t i = 0; i < max_tasks; ++i)
{
struct task *const slot = &tasks[i];
if (slot->handler == NULL)
return slot;
}
return NULL;
}
inline struct task *
add_task(unsigned long start, unsigned long expires,
handler_t h, void *opaque, bool repeat = 0)
{
struct task *const slot = next_task_slot();
if (!slot){
return NULL;
}
slot->handler = h;
slot->opaque = opaque;
slot->start = start;
slot->expires = expires;
slot->repeat = repeat;
return slot;
}
};
/* create a timer with the default settings */
inline Timer<>
timer_create_default()
{
return Timer<>();
}
#endif