AnsweredAssumed Answered

STM32F2 Timer / Interrupt Help

Question asked by kern.chris on Mar 19, 2015
Latest reply on Mar 22, 2015 by kern.chris
STM32F2 Timer / Interrupt Help


I have an HS USB project that reads information at a high data rate from a serial bus (upwards of 4MBd) and then sends it to a server. Everything is working fine, except....


I run into some timing issues from time to time, and I *think* I have narrowed it down to an IRQ issue.


I have set my project up with NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2) because I have 3 main areas that need servicing at different levels. I have this call at the very beginning of my program, and it is only called once.


My understanding is that with NVIC_PriorityGroup_2, I have 4 groups (0-3) of IRQ priority levels, and each level has 4 sub-priorities (0-3) with each level having '0' as the highest priority. So an interrupt with 0,0 has the highest priority while an interrupt with 3,3 is the lowest.


In my project, I have to have polling intervals for different devices on the serial bus. I have set up TIM3 for a specific period (it actually changes depending on what i am expected to talk to on the serial bus, but that is immaterial at this point). I have an IRQ set up on this timer to check for TIM_IT_Update. I have set TIM3_IRQn priority to be 0,0. Once the timer hits the specified time, my IRQ handler toggles a bit (an LED), resets the counter, and away the timer goes. This works beautifully until I actually start doing USB and/or serial communications. 


From the oscilloscope, I can see the LED bit toggle perfectly at the right time (again, when nothing is happening on the communications buses). Once the comms begin, the LED bit edges are no longer on their mark (in this case, 50 ms). The period shrinks, expands, stays the same; there does not seem to be any pattern that I can ascertain. 


I have gone through the code, and verified that my highest priority IRQ is for TIM3, and it is the only IRQ set for 0,0. 


So my question is, if this is the highest priority IRQ, then there should be nothing to prevent the LED bit from toggling exactly when it should. Here is some code snippets:


int main(void)
{
    /* Configure the Priority Group */
    NVIC_PriorityGroupConfig(USB_NVIC_PriorityGroup);
.
.
.
.
.
.
.


    LCD_LED_Init();




    Initialize_Variables();
    MCU_IO_Init();
    Protocol_Line_Init();
    TIM2_Configuration(time1); 
    TIM4_Configuration(time2);
    TIM3_Configuration(poll_time); 
    TIM5_Configuration(time4); 
.
.
.
.
.
.
.
.
    RCC_Configuration();
    GPIO_Configuration();
.
.
.
.
.     
    
  /* Infinite loop */
  while (1)
  {  
.   
.
.
.
<<comms program>>
  }   
}




void MCU_IO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    FSMC_NORSRAMInitTypeDef SRAMInitS;
    FSMC_NORSRAMTimingInitTypeDef p;
  
    //UART FLOW CONTROL --> PF7
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOF, &GPIO_InitStructure);
    // Set to 'Receive'
    Enable_Receiver_Disable_Transmitter();    
}


void RCC_Configuration(void)
{
  /* --------------------------- System Clocks Configuration -----------------*/
  /* USART3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
 
  /* GPIOD clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
 
  /* DMA1 clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
}


void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  /*-------------------------- GPIO Configuration ----------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; // PC.10 USART3_TX, PC.11 USART3_RX
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  /* Connect USART pins to AF */
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_USART3);
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_USART3);
}




void TIM3_Configuration (uint16_t Time_In_Microseconds) 
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    // Enable the TIM3 Interrupt 
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
    NVIC_Init(&NVIC_InitStructure);




    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);




    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseStructure.TIM_Period = Time_In_Microseconds - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = (MCU_OSC / 1000000) - 1;
    TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure );




    TIM_Cmd( TIM3, ENABLE );
    TIM_ITConfig( TIM3, TIM_IT_Update, ENABLE );



void TIM3_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
    {    
        ready_to_poll = TRUE;
     ToggleLED(LED1);
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
    }
}


I agree that my code could use some cleanup, but that is always happening... Maybe some of my initializations are out of order??


Any help would be appreciated. As my serial data is streaming into the USART, i am pulling it out of the buffer and putting it into memory. Once the packet has ended, I pull it out of memory and then send it along to the USB port. The only thing I can think of that might be messing up my IRQ timing is the transfer to and from external memory. From the vector table, I see that "MemManage" is set to priority '0', but that it is settable. If you think that the memory I/O is affecting my TIM3 IRQ timing, then could you please inform me how to change the "MemManage" Interrupt Vector priority? 


Thank you very much for your assistance in this matter. It is driving me nuts!

Outcomes