STM32 maximum interrupt handling frequency

0

I am trying to implement my own SPI communication from FPGA to STM in which my FPGA serve as MASTER and generate Chip enable and clock for communication. FPGA transmit data at its rising edge and receive data at its falling edge my FPGA code works properly.

In STM side i capture this master clock on interrupts and receive data at its rising edge and transmit at its falling edge but communication not work properly if i increase clock speed from 250khz

According to my understand STM work at 168 Mega hz i set clock setting according to 168Mhz and handling of 1mhz interrupt is not a big problem so can you any guide how i handle this high speed clock in STM

My code is written below

        /*
* Project name:
  EXTI_interrupt (EXTI interrupt test)
* Copyright:
  (c) Mikroelektronika, 2011.
* Revision History:
  20111226:
   - Initial release;
* Description:
 This code demonstrates how to use External Interrupt on PD10.
 PD10 is external interrupt pin for click1 socket.
 receive data from mosi line in each rising edge.
* Test configuration:
 MCU:             STM32F407VG
                  http://www.st.com/st-web- 

 ui/static/active/en/resource/technical/document/datasheet/DM00037051.pdf
 dev.board:       EasyMX PRO for STM32
                  http://www.mikroe.com/easymx-pro/stm32/
 Oscillator:      HSI-PLL, 140.000MHz
 Ext. Modules:    -
 SW:              mikroC PRO for ARM
                  http://www.mikroe.com/mikroc/arm/
* NOTES:
  receive 32 bit data from mosi line in each rising edge
*/
          //D10 clk
          //D2 ss
          //C0 MOSI
          //C1 FLAG



   int read=0;
 int flag_int=0;
int val=0;
int rec_data[32];
 int index_rec=0;
 int display_index=0;
 int flag_dint=0;



void ExtInt() iv IVT_INT_EXTI15_10 ics ICS_AUTO {
EXTI_PR.B10 = 1;                     // clear flag
flag_int=1; //Flag on interrupt

}

TFT_Init_ILI9340();

void main() {


GPIO_Digital_Input(&GPIOD_BASE, _GPIO_PINMASK_10);
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_13); // Set PORTD as 
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_12); // Set PORTD as 
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_14); // Set PORTD as 
digital output
GPIO_Digital_Output(&GPIOD_BASE, _GPIO_PINMASK_15); // Set PORTD as    
digital output


  GPIO_Digital_Input(&GPIOA_IDR, _GPIO_PINMASK_0);         // Set PA0 as 
  digital input
  GPIO_Digital_Input(&GPIOC_IDR, _GPIO_PINMASK_0);         // Set PA0 as 
  digital input
  GPIO_Digital_Input(&GPIOC_IDR, _GPIO_PINMASK_2);         // Set PA0 as 
 digital input
  GPIO_Digital_Output(&GPIOC_IDR, _GPIO_PINMASK_1);         // Set PA0 as 
 digital input

 //interupt register
SYSCFGEN_bit = 1;                    // Enable clock for alternate pin 
functions
SYSCFG_EXTICR3 = 0x00000300;         // Map external interrupt on PD10
EXTI_RTSR = 0x00000000;              // Set interrupt on Rising edge 
(none)
EXTI_FTSR = 0x00000400;              // Set Interrupt on Falling edge 
(PD10)
EXTI_IMR |= 0x00000400;              // Set mask
//NVIC_IntEnable(IVT_INT_EXTI15_10);   // Enable External interrupt

while(1)
{


        //interrupt is not enable until i push the button
                     if((GPIOD_ODR.B2==0)&&(flag_dint==0))

             {                            if (Button(&GPIOA_IDR, 0, 1, 1))
                                  {
                                       Delay_ms(100);
                                       GPIOC_ODR.B1=1;     //Status for FPGA
                                           NVIC_IntEnable(IVT_INT_EXTI15_10);   // Enable External interrupt
                                   }


              }

            if(flag_int==1)
             {
    //functionality on rising edge
                          flag_int=0;

                      if(index_rec<31)
                      {

                //display data on led
                                   GPIOD_ODR.B13=    GPIOC_IDR.B0;
//save data in an array                     
 rec_data[index_rec]=  GPIOC_IDR.B0;
   //read data

                              index_rec=index_rec+1;
                      }
                      else
                      {
                             flag_dint=1;
                               NVIC_IntDisable(IVT_INT_EXTI15_10);
                      }





}                           // Infinite loop

       }
}
arm
microcontroller
spi
interrupt-handling
mikroc
asked on Stack Overflow Apr 9, 2018 by Atif Javed

1 Answer

1

Without getting into your code specific, see PeterJ_01's comment, the clock rate problem can be explained by a misunderstanding of throughput in your assumtions.

You assume that given that your STM device has a clock of 168Mhz it can sustain the same throughput of interrupts, which you seem to have conservatively relaxed to 1Mhz.

However the throughput of interrupts it will be able to support is given by the inverse of the time it takes the device to process each interrupt. This time includes both the time the processor takes to enter the service routing (ie detect the interrupt, interrupt the current code and resolve from the vector table where to jump to) plus the time taken to execute the service routine.

Lets be super optimistic and say that entering the routine takes 1 cycle and the routing itself takes 3 (2 for the flags you set and 1 for the jump out of the routine). This gives 4 cycles at 168Mhz is 23.81ns, taking the inverse 42Mhz. This can also be computed by dividing the maximum frequency you would achieve (168Mhz) by the number of cycles spent processing.

Hence our really optimistic bound is 42Mhz, but realistically will be lower. For a more accurate estimate you should test your implementation timings and dig into your device's documentation to see interrupt response times.

answered on Stack Overflow Apr 10, 2018 by gorilon

User contributions licensed under CC BY-SA 3.0