STM32F4 multi-channel input capture interrupt confusion  - Page 1
Forum section: electronics / general

author: techy101
author_rank: Unknown
timestamp: October 09, 2016, 08:27:47 pm
content: I was hoping to get some clarification on a topic that has me confused with the STM32F4. I'm wanting to use all four channels of Timer2 for measuring period and the number of events for four different incoming signals. For the most part I’ve got my head wrapped around this; calculating deltas for both the captured times and number of timer overflows for each channel. The goal is to avoid having to use four different timers for the four signals.In my application I need to both capture the value of the timer at the rising edge of an incoming signal and count the number of these events that have happened. Because of this the input capture will need to trigger an interrupt. As I understand it the STM32 only has one interrupt for everything related to a timer, and that interrupt handler will need to sort out what caused the interrupt (overflow, input capture/channel) and respond accordingly. So, if enabled, the setting of any of these bits will trigger the single timer 2 interrupt handler: TIM_SR.UIF (overflow), TIM2_SR.CC1IF (capture on channel 1) … TIM2_SR.CC4IF (capture on channel 4). Am I correct in my understanding of this?My real confusion is with how the chip will handle multiple concurrent events, or events that happen in very quick succession. Since, as I understand it, the single timer interrupt is needed to handle all of these situations there is no prioritization. As an example, say the interrupt handler is executing due to a channel 1 input capture event. While this is still going on the timer overflows. Since the two events are both part of the same interrupt, what will happen? Currently I’m using a series of if statements in the handler which should work if things came in order. But if they come in out of order will the interrupt interrupt itself, will it put the new event into a queue and handle them as a FIFO, will the second event just be lost, or will something altogether different happen?Here is a version of the interrupt handler I wrote that only deals with one capture channel and the timer overflow. This is not exactly representative of the question I asked. It resets the overflow counter, but for the multi-channel approach the overflow counter will continue running and a delta will be calculated instead. But it should give an idea of the approach I’m trying to take. (Formatting of the comments turned into a mess when I pasted it into here)Code:// Interrupt handler for Timer 2void timer2_ISR() iv IVT_INT_TIM2 {// NVIC_IntDisable(IVT_INT_TIM2);// ** UNUSED** Disable timer 2 interrupts// Timer 2 Overflowif(TIM2_SR.UIF == 1) {TIM2_SR.UIF = 0; // Clear timer 2 interrupt bitoverflowCount++; // Increment overflow counter}// Input Capture Eventif (TIM2_SR.CC1IF == 1) {TIM2_SR.CC1IF = 0; // Clear input capture event bitendTime = TIM2_CCR1; // Read stored input capture timeoverflowCountTemp = overflowCount; // Store overflow count for use in mainoverflowCount = 0; // Reset the overflow counter to 0inputEventCounter++; // Increment total input capture event counter}NVIC_IntEnable(IVT_INT_TIM2); // **UNUSED** Re-enable timer 2 interrupt}I hope this question isn’t too scatterbrained; I’m having a difficult time phrasing it.Thank you,Matthew

author: newbrain
author_rank: Super Contributor
timestamp: October 11, 2016, 09:47:21 pm
content: Quote from: techy101 on October 09, 2016, 08:27:47 pmYes, you guessed it. Something slightly different from all the options you enumerated.Let's check your (more than reasonable!) guesses one by one:As the new interrupt has the same exact priority and sub-priority as the one being handled, there's no reason for the current interrupt routine to be preempted.The FIFO idea could be good, but there's a major problem: how deep should the (hardware) FIFO to be sure we do not to lose interrupts?Losing interrupts is definitely a simple solution. But it's not a very helpful one, as you can imagine.What will happen is simply that as long as there are active event flags (e.g. the CCxIF ones), with the matching interrupt enable flag set (e.g. the CCxIE ones), the interrupt will continue to be pending.So the interrupt routine will be entered again as soon as it returns and the process will repeat as long as there are pending flags.Moreover, there won't even be a real return from interrupt: the stacked registers won't be popped and pushed again, the control will pass directly to the beginning of the pending ISR (good for latency); from the F4 programming guide, chapter 2.3.7:QuoteIf an higher priority request comes, the ISR will be preempted, as expected.If sub-priorities are defined, a request with higher sub-priority but same priority group will be served at the end of the current one (no preemption).Edited to add:Your approach in the code is then the correct one: check and act on each flag sequentially, without "else if"s.Also, if you read the TIMn_CCRx register the corresponding CCxIF will automatically be cleared, so no need to do that in your code.

author: techy101
author_rank: Unknown
timestamp: October 12, 2016, 02:30:39 am
content: Thank you very much! This helps out greatly.