MKE04 interrupt latency

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MKE04 interrupt latency

1,006 Views
davidhollinrake
Contributor I

I am using the MKE04Z8VFK4.  The interrupt latency that I measure is more than the 15 cycles that the ARM M0+ documentation specifies as the best case interrupt latency, assuming zero wait state memory.  I have simple test code that uses FTM2 channel 0 to interrupt on the rising edge of an input signal and the FTM2_Isr() toggles an output pin using single cycle FPGIOA port.  The assembly code listing for the output pin toggle shows it to be 6 clocks (4 instructions).  The interrupt latency I measure, taking into account the 6 clocks due to the output toggle, 1 clock for possible rise time error, and 15 clocks for the M0+ interrupt handling, is about 12 clocks longer that expected (or 10 clocks longer than expected if the code is running in RAM).  Does anyone know the reason for the extra clocks? 

First instruction in FTM2_Isr(): 

   FGPIO_Toggle(FGPIOA, GPIO_PTB5_MASK); /* Debug. Toggle port pin B5 when first entering interrupt */

IAR listing for FGPIO_Toggle():

   1022             FGPIO_Toggle(FGPIOA, Z_OUT_MASK);/*~ Debug. Toggle Z when first entering interrupt */

   \                     FTM2_Isr: (+1)

   \   00000000   0x2080             MOVS     R0,#+128

   \   00000002   0x0180             LSLS     R0,R0,#+6        ;; #+8192

   \   00000004   0x....                  LDR      R1,??DataTable24  ;; 0xf800000c

   \   00000006   0x6008             STR      R0,[R1, #+0]

Labels (1)
0 Kudos
4 Replies

651 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello David Hollinrake:

Are you configuring the FTM as input capture with a determined channel value? Can you share the test project to try it from my side?

And I guess you are measuring the time with an oscilloscope.

Measuring the interrupt latency is not as straightforward as just counting and subtracting the number of instructions.. In your case there are propagation times from the input pin as well as the output pin toggling. Please look at the next discussion, in particular to colleague Philip Drake's response to understand better:

Interrupt latency time (cycles)

Maybe a better way to measure interrupt latency is with a software interrupt and using SysTick timer, checking the count increment between interrupt trigger and interrupt first instruction.

Regards!

Jorge Gonzalez

0 Kudos

651 Views
davidhollinrake
Contributor I

Jorge,

I just uploaded interrupt_latency.zip which has the files I modified in KEXX_DRIVERS_V1.2.1_DEVD for project:

C:\FRDM-KE04Z\KEXX_DRIVERS_V1.2.1_DEVD\kexx_drv_lib\build\iar\ke04\FTM_DualEdgeCapture_demo

David Hollinrake

0 Kudos

651 Views
davidhollinrake
Contributor I

Hello Jorge,

I read the other post about interrupt latency, but I am using the fast GPIO port (IOPORT) at 0xF800_0000, so the peripheral bus latency due to the cross-bar architecture doesn't apply does it?

I know the interrupt latency is not easy to measure, but for my application I need to know the time from an input edge to the interrupt handling routine where I toggle an output pin.  If I was off just a couple of clocks from the 15 cycles quoted for M0+ interrupt latency, I wouldn't worry about it.  But since I measured an extra 12 clocks, I want to understand where it is coming from in case I can do something about it).  For example, is it something in my code, something in my setup, something in the FTM module, or undocumented interrupt latency clock cycles for the Freescale implementation of the M0+?

Background info:  I am using PTC0 for the input and PTB5 for the output.  I am using a function generator to drive the input pin and I am using an oscilloscope to measure from the rising edge of the input to the toggling edge of the output pin.  The core/system clock is running at 48MHz and the Bus/Flash clock is 24MHz.

To try to account for setup/measurement errors, I tried to measure the actual switching threshold of the input by adjusting the output level of the generator until the input was detected as high.  Then I added ~ 1.5V to that value for the trigger level on my scope to make sure the rise time of the function generator did not add to the delay I was trying to measure.  I also added in one extra clock to the expected interrupt latency as an additional error factor for the input signal rise time.

Here is the end of main() where the FTM gets initialized:

    /* Select capture mode for the FTM */
    FTM_InputCaptureInit(FTM2, FTM_CHANNEL_CHANNEL0, FTM_INPUTCAPTURE_RISINGEDGE);
    /* Select the clock source and PreScale factor for the FTM */
    FTM_ClockSet(FTM2, FTM_CLOCK_SYSTEMCLOCK, FTM_CLOCK_PS_DIV1);
    NVIC_EnableIRQ(FTM2_IRQn);
    /* Load and Clear Ch0 (A) interrupt flag */
    u8BME_Temp = BME_BIT_CLEAR_8b(&FTM2->CONTROLS[FTM_CHANNEL_CHANNEL0].CnSC, FTM_CnSC_CHF_SHIFT);
    /* Load and Clear Ch1 (B) interrupt flag */
    u8BME_Temp = BME_BIT_CLEAR_8b(&FTM2->CONTROLS[FTM_CHANNEL_CHANNEL1].CnSC, FTM_CnSC_CHF_SHIFT);

    /* Enable Ch0 (A) interrupt */
    u8BME_Temp = BME_BIT_SET_8b(&FTM2->CONTROLS[FTM_CHANNEL_CHANNEL0].CnSC, FTM_CnSC_CHIE_SHIFT);
     /* Enable Ch1 (B) interrupt */
//~    u8BME_Temp = BME_BIT_SET_8b(&FTM2->CONTROLS[FTM_CHANNEL_CHANNEL1].CnSC, FTM_CnSC_CHIE_SHIFT);

  while(1)
{
}
} /* endmain */

Here is the FTM2 interrupt service routine:

void FTM2_Isr(void)
{
  uint8_t u8BME_Temp; /* Temporary variable needed for BME operation */
 
  FGPIO_Toggle(FGPIOA, Z_OUT_MASK);/*~ Debug. Toggle Z when first entering interrupt */
  /* Ch0 (A) interrupt?  Load and Clear Ch0 interrupt flag in one operation. */
  u8BME_Temp = BME_BIT_CLEAR_8b(&FTM2->CONTROLS[FTM_CHANNEL_CHANNEL0].CnSC, FTM_CnSC_CHF_SHIFT);

} /* End of FTM2_Isr() */

And this is the assembly listing where I came up with 6 cycles for the fast GPIO toggle:

   1015            FGPIO_Toggle(FGPIOA, Z_OUT_MASK);/*~ Debug. Toggle Z when first entering interrupt */

   \                     FTM2_Isr: (+1)

   \   00000000   0x2080             MOVS     R0,#+128

   \   00000002   0x0180             LSLS     R0,R0,#+6        ;; #+8192

   \   00000004   0x....                 LDR      R1,??DataTable15_7  ;; 0xf800000c

   \   00000006   0x6008             STR      R0,[R1, #+0]

For the expected time delay from input edge to output edge, I used 15 + 6 + 1 = 22 clocks, but I was seeing a delay of 24 clocks.

David Hollinrake

0 Kudos

651 Views
davidhollinrake
Contributor I

I meant to say I am seeing a delay of 34 clocks (not 24 clocks)

0 Kudos