# Creating timer-based interrupts

**URL:** <https://community.particle.io/t/creating-timer-based-interrupts/771>\
**Category:** Firmware\
**Created:** [December 16, 2013, 8:48am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771 "2013-12-16T08:48:14Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![deltahat](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/deltahat/32/2192_2.png) [@deltahat](https://community.particle.io/u/deltahat)\
**Post date:** [December 16, 2013, 8:48am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/1 "2013-12-16T08:48:15Z")

</div>

I’d like to interface with the TLC5940 LED driver chip. The chip lacks an internal clock so it relies on an external blanking signal from the microcontroller every couple hundred picoseconds. I’d like to issue the blanking signal via a periodic interrupt handler. What is the best way to configure the hardware timers of the Spark Core to trigger an interrupt handler? Additionally, does the Spark Core base firmware depend on the hardware timers for any of its functionality?

---

<div class="post-metadata">

**Author:** ![satishgn](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/satishgn/32/20740_2.png) [@satishgn](https://community.particle.io/u/satishgn)\
**Post date:** [December 17, 2013, 9:26am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/2 "2013-12-17T09:26:28Z")

</div>

The Spark Core firmware indeed uses Hardware Timers to generate PWM outputs via the following Wiring APIs:  
1)analogWrite(pin, value) [Refer spark\_wiring.c] This produces a fixed frequency of 500Hz with configurable duty cycle[0-100%]  
2)Servo::writeMicroseconds(pulseWidth) [Refer spark\_wiring\_servo.c] This produces a fixed frequency of 50Hz

Apart from above, We also use the hardware timer to control the RGB LED and Button debouncing but those channels are not accessible via external pins.

There are 10 pins on Core mapped to hardware timer channels: D0, D1, A0, A1, A4, A5, A6, A7, RX, TX

We believe in your case, you can use any of the above pins to generate the necessary PWM signal for the LED driver IC.  
We can also have a Timer interrupt handler implemented but I don’t think that would be necessary (not sure, we need to check the LED driver management)

For driving other than the default frequency of 500Hz, What we suggest is you can use the analogWrite() function as follows:  
Assuming D0 is used, call the following function as one time setup call to configure and enable the Timers mapped to this pin. Do this in setup() call

analogWrite(D0, 0); //value is 0 since we don’t need the default 500Hz PWM output

Now vary the Timer’s Prescaler, Auto Reload register and Channel Compare register to produce the desired PWM ouput as follows:  
So suppose on D0, you want a 10KHz PWM with 50% duty cycle, call the below code:  
Note: D0 is mapped to Timer 4 =\> Channel 2

//Set the Prescaler value  
TIM4-\>PSC = 71;  
//Load prescaler immediately  
TIM4-\>EGR = 1;  
//Set the Autoreload Register value  
TIM4-\>ARR = 99;  
//Set the Capture Compare2 Register value  
TIM4-\>CCR2 = 50;//CCR2 is for Channel 2

Hope this answers your query 🙂

---

<div class="post-metadata">

**Author:** ![deltahat](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/deltahat/32/2192_2.png) [@deltahat](https://community.particle.io/u/deltahat)\
**Post date:** [December 17, 2013, 10:26pm UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/3 "2013-12-17T22:26:19Z")

</div>

Thanks for the follow up. I still need to trigger an interrupt on a timer to periodically copy a the frame buffer into the TLC5940 over the SPI bus. I can send the blanking signal to the chip after the copy is complete. This way I don’t have to use any PWM and can instead reuse TIM4 to triger the interrupt.

Do you have a recommendation for how to bind an interrupt handler to TIM4?

---

<div class="post-metadata">

**Author:** ![satishgn](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/satishgn/32/20740_2.png) [@satishgn](https://community.particle.io/u/satishgn)\
**Post date:** [December 18, 2013, 5:20am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/4 "2013-12-18T05:20:51Z")

</div>

Ok to bind an interrupt handler for TIM4,

Please follow these steps:  
1)You need to override the TIM4\_IRQHandler which is defined as weak in startup code. For this in your application, define a function:  
void TIM4\_IRQHandler(void)  
{  
//Your interrupt handler code should look something like this.  
if (TIM\_GetITStatus(TIM4, TIM\_IT\_Update) != RESET)  
{  
TIM\_ClearITPendingBit(TIM4, TIM\_IT\_Update); //Clear the interrupt bit  
//Your code goes here…  
}

if (TIM\_GetITStatus(TIM4, TIM\_IT\_CC2) != RESET)  
{  
TIM\_ClearITPendingBit(TIM4, TIM\_IT\_CC2); //Clear the interrupt bit  
//Your code goes here…  
}  
}

2)Configure NVIC for TIM4  
NVIC\_InitTypeDef NVIC\_InitStructure;  
//Enable the TIM4 global Interrupt  
NVIC\_InitStructure.NVIC\_IRQChannel = TIM4\_IRQn;  
NVIC\_InitStructure.NVIC\_IRQChannelPreemptionPriority = 0;//Highest priority - depends on you application  
NVIC\_InitStructure.NVIC\_IRQChannelSubPriority = 0;  
NVIC\_InitStructure.NVIC\_IRQChannelCmd = ENABLE;  
NVIC\_Init(&NVIC\_InitStructure);

3)Enable the TIM4 needed interrupt Flags.  
TIM\_ITConfig(TIM4, TIM\_IT\_Update, ENABLE); //TIM Update IT enable  
//TIM\_ITConfig(TIM4, TIM\_IT\_CC2, ENABLE); //TIM CCR2 IT enable

The above is just an idea how to get the interrupt thingy working. Provided high level API usage to make the code readable.

Hope this helps.  
Thanks.  
Satish Nair

---

<div class="post-metadata">

**Author:** ![mb3](https://avatars.discourse-cdn.com/v4/letter/m/a8b319/32.png) [@mb3](https://community.particle.io/u/mb3)\
**Post date:** [January 16, 2014, 3:47am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/5 "2014-01-16T03:47:25Z")

</div>

I seem to be having some issues when enabling timer-based interrupts. I have been looking at your example, and the tutorial [Controlling STM32 Hardware Timers with Interrupts – VisualGDB Tutorials](http://visualgdb.com/tutorials/arm/stm32/timers/), and I can't seem to get the interrupt handler working.

After initializing the timer, I have the following in loop():

> ```
> if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
> {
> TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
> if (state == 1){
> digitalWrite(LED, HIGH);
> state = 0;
> }
> else{
> digitalWrite(LED, LOW);
> state = 1;
> }
> }
> 
> ```

This works, and will periodically toggle the LED. However, if I move the same code to `TIM2_IRQHandler`and enable the interrupt with:

> ```
> NVIC_InitTypeDef nvicStructure;
> nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
> nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
> nvicStructure.NVIC_IRQChannelSubPriority = 1;
> nvicStructure.NVIC_IRQChannelCmd = ENABLE;
> NVIC_Init(&nvicStructure);
> 
> ```

it does not work. I also tried keeping the LED toggle code in loop() as well as in the interrupt handler, and enabling the interrupt. However, as soon as the interrupt is enabled, the LED stops toggling. Are you able to provide any insight to my issues?

_ **UPDATE** _

Defining the `TIM2_IRQHandler` with `extern "C"` fixes the problem. This gives the interrupt handler C linkage so the linker can properly link the interrupt handler. For example, define:

```
extern "C" void TIM2_IRQHandler(void){
 if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET){
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    }
}

```

**NOTE:** The online IDE will not compile properly with the extern 'C' linkage. As of this writing (1/18/2014), you must compile locally in order for this to work.

---

<div class="post-metadata">

**Author:** ![satishgn](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/satishgn/32/20740_2.png) [@satishgn](https://community.particle.io/u/satishgn)\
**Post date:** [January 16, 2014, 5:08am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/6 "2014-01-16T05:08:30Z")

</div>

So you are using TIM2. Did you change the default priority grouping since I see this in your code.  
nvicStructure.NVIC\_IRQChannelSubPriority = 1;

Do you have this statement in your code: TIM\_ITConfig(TIM2, TIM\_IT\_Update, ENABLE);

Try adding this declaration in your stm32\_it.h file:  
void TIM2\_IRQHandler(void);

Let me know if the above works?

---

<div class="post-metadata">

**Author:** ![mb3](https://avatars.discourse-cdn.com/v4/letter/m/a8b319/32.png) [@mb3](https://community.particle.io/u/mb3)\
**Post date:** [January 16, 2014, 5:55am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/7 "2014-01-16T05:55:35Z")

</div>

I was experimenting with changing the priority grouping, although I changed it back to 0 so we are both on the same page. And yes, I have `TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);` in my code.

I just tried adding `void TIM2_IRQHandler(void);` to `stm32_it.h`, but unfortunately it did not seem to fix the issue.

It seems like it could be an issue with enabling the timer interrupt. Just for testing purposes, I defined `TIM2_IRQHandler()` as an empty function in my code and enabled the timer interrupt with:

> ```
> NVIC_InitTypeDef nvicStructure;
> nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
> nvicStructure.NVIC_IRQChannelPreemptionPriority = 0;
> nvicStructure.NVIC_IRQChannelSubPriority = 0;
> nvicStructure.NVIC_IRQChannelCmd = ENABLE;
> NVIC_Init(&nvicStructure);
> 
> ```

In my main loop, I have the LED toggling code mentioned in my previous post. When I compile and load this onto the device, the LED will not toggle. However, if I comment out `nvicStructure.NVIC_IRQChannelCmd = ENABLE; ` in my interrupt enable function, the LED will toggle (obviously the interrupt will not be properly initialized).

---

<div class="post-metadata">

**Author:** ![satishgn](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/satishgn/32/20740_2.png) [@satishgn](https://community.particle.io/u/satishgn)\
**Post date:** [January 16, 2014, 6:51am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/8 "2014-01-16T06:51:06Z")

</div>

Can you send me the complete code related to TIM2 usage?  
Thanks

---

<div class="post-metadata">

**Author:** ![satishgn](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/satishgn/32/20740_2.png) [@satishgn](https://community.particle.io/u/satishgn)\
**Post date:** [January 16, 2014, 9:38am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/9 "2014-01-16T09:38:23Z")

</div>

Ok. Resolved.

This was a linking issue.  
Since application is .cpp file, you require extern “C” before your Interrupt handler definition.

So your TIM2 interrupt handler code should look like:

extern “C” void TIM2\_IRQHandler(void)  
{  
…  
}

---

<div class="post-metadata">

**Author:** ![gooswa](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/gooswa/32/2055_2.png) [@gooswa](https://community.particle.io/u/gooswa)\
**Post date:** [March 16, 2014, 6:20am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/10 "2014-03-16T06:20:16Z")

</div>

Would love to see the full source for this. I want to control my own TLC5940. Plus I want a better understanding of SPI to understand other SPI chips.

---

<div class="post-metadata">

**Author:** ![kmarsh](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/kmarsh/32/3913_2.png) [@kmarsh](https://community.particle.io/u/kmarsh)\
**Post date:** [March 29, 2014, 3:40am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/11 "2014-03-29T03:40:44Z")

</div>

I’m having the same problem that @mb3 was – The interrupt handler is not binding. I can call it directly from loop, but if I try to do all the NVIC stuff it’ll compile but the timer update event won’t actually trigger the handler.

I see that @mb3’s solution was to compile with `extern "C"`, but he notes that it won’t compile in the IDE at that point. Is there any way, currently, to make this work from the IDE?

Thanks!

---

<div class="post-metadata">

**Author:** ![bko](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/bko/32/20704_2.png) [@bko](https://community.particle.io/u/bko)\
**Post date:** [March 29, 2014, 3:49am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/12 "2014-03-29T03:49:48Z")

</div>

Hi @kmarsh

Did you see this link:

> **[Previous declaration of 'void TIM2\_IRQHandler()' with 'C++' linkage /...](https://community.particle.io/t/previous-declaration-of-void-tim2-irqhandler-with-c-linkage-interrupt-isr-based-timer/3096/5)**
>
> Hey @gruvin - this works now! In order to get this to compile, you need to add it to a library file; it can’t be part of your main .ino file. Then you need to #include "application.h" in that file. If you do that, it should compile as expected!

And this nice new library from @peekay123

> **[IntervalTimer library](https://community.particle.io/t/intervaltimer-library/3004/8)**
>
> OK folks, it is DONE!! The SparkIntervalTimer library is now available for all your grubby little hands. I consider this a start but right now, you can grab an interval timer from a pool of three (TIM2, TIM3 or TIM4), pass it a callback and give...

---

<div class="post-metadata">

**Author:** ![kmarsh](https://sea2.discourse-cdn.com/flex026/user_avatar/community.particle.io/kmarsh/32/3913_2.png) [@kmarsh](https://community.particle.io/u/kmarsh)\
**Post date:** [March 29, 2014, 4:03am UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/13 "2014-03-29T04:03:57Z")

</div>

I had not yet seen either of those! Looking now. They seem very promising. Thanks a bundle!

---

<div class="post-metadata">

**Author:** ![Drewr53](https://avatars.discourse-cdn.com/v4/letter/d/e495f1/32.png) [@Drewr53](https://community.particle.io/u/Drewr53)\
**Post date:** [February 16, 2016, 7:55pm UTC](https://community.particle.io/t/creating-timer-based-interrupts/771/14 "2016-02-16T19:55:06Z")

</div>

@deltahat You talked about using a TLC5940, did you get this working with the core or the photon? I am looking for library to use with a Photon that would control a TLC5940. I have all my code working on an Arduino but want to move into the Photons.
