Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added functionality to pass custom parameter to HardwareTimer callback #892

Merged
merged 9 commits into from
Mar 11, 2020
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
fpistm marked this conversation as resolved.
Show resolved Hide resolved
fpistm marked this conversation as resolved.
Show resolved Hide resolved
*/
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
fpistm marked this conversation as resolved.
Show resolved Hide resolved
fpistm marked this conversation as resolved.
Show resolved Hide resolved
*/
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