Skip to content
31 changes: 28 additions & 3 deletions cores/arduino/HardwareTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,9 @@ void HardwareTimer::setInterruptPriority(uint32_t preemptPriority, uint32_t subP
* @param callback: interrupt callback
* @retval None
*/
void HardwareTimer::attachInterrupt(void (*callback)(HardwareTimer *))
void HardwareTimer::attachInterrupt(void (*callback)(HardwareTimer *), void *arg)
{
args[0] = arg;
if (callbacks[0] != NULL) {
// Callback previously configured : do not clear neither enable IT, it is just a change of callback
callbacks[0] = callback;
Expand All @@ -875,6 +876,7 @@ void HardwareTimer::detachInterrupt()
// Disable update interrupt and clear callback
__HAL_TIM_DISABLE_IT(&(_timerObj.handle), TIM_IT_UPDATE); // disables the interrupt call to save cpu cycles for useless context switching
callbacks[0] = NULL;
args[0] = NULL;
}

/**
Expand All @@ -883,7 +885,7 @@ void HardwareTimer::detachInterrupt()
* @param callback: interrupt callback
* @retval None
*/
void HardwareTimer::attachInterrupt(uint32_t channel, void (*callback)(HardwareTimer *))
void HardwareTimer::attachInterrupt(uint32_t channel, void (*callback)(HardwareTimer *), void *arg)
{
int interrupt = getIT(channel);
if (interrupt == -1) {
Expand All @@ -893,7 +895,7 @@ void HardwareTimer::attachInterrupt(uint32_t channel, void (*callback)(HardwareT
if ((channel == 0) || (channel > (TIMER_CHANNELS + 1))) {
Error_Handler(); // only channel 1..4 have an interrupt
}

args[channel] = arg;
if (callbacks[channel] != NULL) {
// Callback previously configured : do not clear neither enable IT, it is just a change of callback
callbacks[channel] = callback;
Expand Down Expand Up @@ -927,6 +929,29 @@ void HardwareTimer::detachInterrupt(uint32_t channel)
// Disable interrupt corresponding to channel and clear callback
__HAL_TIM_DISABLE_IT(&(_timerObj.handle), interrupt);
callbacks[channel] = NULL;
args[channel] = NULL;
}

/**
* @brief Get argument attached to (rollover) event.
* @retval Associated pointer to attached argument or NULL if not set.
*/
void *HardwareTimer::getArg()
{
return args[0];
}

/**
* @brief Get argument attached to Capture/Compare event.
* @param channel: arduino channel [1..4]
* @retval Associated pointer to attached argument or NULL if not set.
*/
void *HardwareTimer::getArg(uint32_t channel)
{
if ((channel == 0) || (channel > (TIMER_CHANNELS + 1))) {
Error_Handler(); // only channel 1..4 have an interrupt
}
return args[channel];
}

/**
Expand Down
8 changes: 6 additions & 2 deletions cores/arduino/HardwareTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ class HardwareTimer {
void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority); // set interrupt priority

//Add interrupt to period update
void attachInterrupt(void (*handler)(HardwareTimer *)); // Attach interrupt callback which will be called upon update event (timer rollover)
void attachInterrupt(void (*handler)(HardwareTimer *), void *arg = NULL); // Attach interrupt callback which will be called upon update event (timer rollover)
void detachInterrupt(); // remove interrupt callback which was attached to update event
bool hasInterrupt(); //returns true if a timer rollover interrupt has already been set
void *getArg(); // Getter for attached argument to event (timer rollover)
//Add interrupt to capture/compare channel
void attachInterrupt(uint32_t channel, void (*handler)(HardwareTimer *)); // Attach interrupt callback which will be called upon compare match event of specified channel
void attachInterrupt(uint32_t channel, void (*handler)(HardwareTimer *), void *arg = NULL); // Attach interrupt callback which will be called upon compare match event of specified channel
void detachInterrupt(uint32_t channel); // remove interrupt callback which was attached to compare match event of specified channel
bool hasInterrupt(uint32_t channel); //returns true if an interrupt has already been set on the channel compare match
void *getArg(uint32_t channel); // Getter for attached argument to compare match event of specified channel

void timerHandleDeinit(); // Timer deinitialization

Expand All @@ -152,6 +154,8 @@ class HardwareTimer {
TimerModes_t _ChannelMode[TIMER_CHANNELS];
timerObj_t _timerObj;
void (*callbacks[1 + TIMER_CHANNELS])(HardwareTimer *); //Callbacks: 0 for update, 1-4 for channels. (channel5/channel6, if any, doesn't have interrupt)
void *args[1 + TIMER_CHANNELS];

int getChannel(uint32_t channel);
int getLLChannel(uint32_t channel);
int getIT(uint32_t channel);
Expand Down