title: Minimizing Interrupt Time, Maximizing Compiler Processing Speed, Reaching STM32F3 Operator Speed
body: <p>I am currently working on STM32F3 Discovery Board. I wrote a basic program in C to see if it works at 72 MHz which is about 14 ns in time. Hopefully it worked at this frequency, but when I want to toggle just one random pin on the device, turning it ON or OFF takes 660 ns in an infinite while loop. Then I checked with an oscilloscope, how much each command takes. Values might not be exact, Here is what I found;
  a while loop(only for checking) = 120 ns, a "for" loop(only for checking) = 160 ns
  One turn of a while loop = 280 ns, one turn of a for loop = 320 ns, which means each turn takes 160 ns.
  asm("NOP") = 14 ns(which must be equal to operator frequency(72 MHz, as expected), an empty function call = 225 ns
  I don't think these values are same for other compilers, or other computers, but I am not even close to 72 MHz. Minimum interrupt I got was 2 microsecond. Is there any way to minimize these values? Is there anyway to increase the gcc compiler speed? </p>
  
  <pre><code>#include "stm32f30x.h"
  #include &lt;common.h&gt;
  
  void InitializeTimer(void) ;
  void EnableTimerInterrupt(void);
  void TIM2_IRQHandler(void);
  GPIO_InitTypeDef configuration;
  void dly(int dly_nmbr);
  int main(void)
  {
  
    GPIO_InitTypeDef GPIO_InitStructure;
  //NVIC_InitTypeDef NVIC_InitStructure;
    RCC_ClocksTypeDef RCC_ClockFreq;
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  
    /* Configure PA10 in output pushpull mode */
    /*****I called init_pin function from common.c because it was easier
    but I guess it takes some time too*********/
    init_pin(GPIOA,GPIO_Pin_10,GPIO_Mode_OUT,GPIO_Speed_50MHz,GPIO_OType_PP,GPIO_PuPd_NOPULL);
  
  /****I tried usual way to configure the pins too****/
  //configuration.GPIO_Pin = GPIO_Pin_10;
  //configuration.GPIO_Mode = GPIO_Mode_OUT;
  //configuration.GPIO_OType = GPIO_OType_PP;
  //configuration.GPIO_Speed = GPIO_Speed_50MHz;
  //configuration.GPIO_PuPd = GPIO_PuPd_NOPULL;
  //GPIO_Init(GPIOA, &amp;configuration);
  //InitializeTimer();
  /*** This function fills the RCC_ClockFreq structure with the current
    frequencies of different on chip clocks (for debug purpose) **************/
    RCC_GetClocksFreq(&amp;RCC_ClockFreq);
  
    /* Enable Clock Security System(CSS): this will generate an NMI exception
    when HSE clock fails *****************************************************/
    RCC_ClockSecuritySystemCmd(ENABLE);
  
    /* Enable and configure RCC global IRQ channel, will be used to manage HSE ready 
       and PLL ready interrupts. 
       These interrupts are enabled in stm32f0xx_it.c file **********************/
    /* I disabled the interrupts for the purpose of maximizing the program speed*/
  //   NVIC_InitStructure.NVIC_IRQChannel = RCC_IRQn;
  //   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  //   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  //   NVIC_Init(&amp;NVIC_InitStructure);
  
  
    /************* Output HSE clock on MCO1 pin(PA8) ************/
    /****************** Enable the GPIOA Clock ******************/
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  
    /* MCO pin configuration: PA8 */
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
    GPIO_Init(GPIOA, &amp;GPIO_InitStructure);
  
    /* Output System Clock on MCO pin */
    RCC_MCOConfig(RCC_MCOSource_SYSCLK);
  
    /************** This is the toggling part. I tried each command here ***************/
  
    while(1)
    {
  //     volatile int i = 0;
  //     dly(0); 
         /*I called an empty function called dly before and after the toggle 
         to see function call time*/
         GPIO_Toggle(GPIOA,GPIO_Pin_10);
  //     dly(0);
  //       while(i&lt;=0)
  //     {
  //       i++;
  //     }
  //     for(i=0;i&lt;=0;i++);
  
    }
  }
  /*Empty Function*/
  void dly(int dly_nmbr)
  {
  }
  
  /************** Interrupt Functions  **************/
  // void TIM2_IRQHandler()
  //  {
  //      if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  //      {
  //          TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  //      }
  //  }
  
  //  void InitializeTimer()
  //  {
  //      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  //  
  //      TIM_TimeBaseInitTypeDef timerInitStructure;
  //      timerInitStructure.TIM_Prescaler = 0;
  //      timerInitStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned2;
  //      timerInitStructure.TIM_Period = 2;
  //      timerInitStructure.TIM_ClockDivision = 0x0000;                                
  //      timerInitStructure.TIM_RepetitionCounter = 100;
  //      TIM_TimeBaseInit(TIM2, &amp;timerInitStructure);
  //      
  //      TIM_Cmd(TIM2, ENABLE);
  //      TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
  //      EnableTimerInterrupt();
  //  }
  
  //  void EnableTimerInterrupt()
  //  {
  //      NVIC_InitTypeDef nvicStructure;
  //      nvicStructure.NVIC_IRQChannel = TIM2_IRQn;
  //      nvicStructure.NVIC_IRQChannelCmd = ENABLE;
  // //      TIM2-&gt;ARR = 1;
  // //      TIM2-&gt;PSC = 1;
  //      NVIC_Init(&amp;nvicStructure);
  //      
  //  }
  /****************** EOF ********************/
  </code></pre>