Skip to content
16 changes: 13 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,14 @@ 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;
}

void* HardwareTimer::getArg(uint32_t channel){
if (channel > (TIMER_CHANNELS + 1)) {
Error_Handler();
}
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,14 +126,16 @@ 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
//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 = 0);

void timerHandleDeinit(); // Timer deinitialization

// Refresh() is usefull while timer is running after some registers update
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