Hello,
I am using KL82 mcu. MCU running at 72 MHz clock.
I need GPIO interrupt on rising edge event.
I set PORTB pin 0 as input and configure it for interrupt on rising edge and enable PORTB_IRQn IRQ.
In interrupt routine I clearing interrupt flag (ISFR) and set high level output on the other pin (PORTC, pin 16) to see if caught rising event.
The problem is that when a high level occurs in the PORTB pin 0, the interrupt occurs with delay because PORTC pin 16 set High with delay. Delay is about 500 ns.
Attach an image of the described event.
Hi Rysard,
To explain the delay we can think on the following:
1 GPIO clocking.
According to the device Reference manual, the Bus clock, which feeds the GPIO, can run up to 24 MHz So that limits the GPIO sampling, GPIO interrupt latency and writing to be faster.
2 GPIO rise time .
The chapter 5.3.3.2 General switching specifications
Details the switching timing for the GPIO. For example the largest rise time is close to 34 n’s, but that depends on certain conditions listed on the table.
3 Software overhead
High level functions add additional timing. To diminish overhead you can use direct registers PTOR, PSOR to set the GPIO pin and check disassembly code to see what is taking additional time.
4 Interrupt latency.
For the NVIC of the Arm Cortex M0+ , the minimum latency to enter an ISR is close to 15 clock cycles, when the flash memory is read with 0 wait states. That will sum the global delay.
5 Use Fast I/0
If you are willing to decrease the delay, you can us0 the Fast I/O.
The following post details this An experiment -- Fast GPIO vs normal GPIO and provide example codes.
Additionally, the information on this post may help you Interrupt latency time (cycles)
Unfortunately, I do not have access to an scope to follow you on this, But I hope this helps.
Regards,
Diego
Thanks for the helpful answer and information.
I tried to catch High level by polling instead of a interrupt, and latency decreased from 500 to 300 microseconds but this is not the solution to the problem.
*from 500 to 300 nanoseconds.
Hi Rysard
Using FAST IOs will allow being able to toggle outputs at 14ns (72MHz edges to achieve 36MHz frequency) but it won't have any noticeable effect on interrupts since the Cortex M0+ interrupt context overhead is fairly high and 500ns reaction times is already very good - in fact I wonder whether your measurements are accurate and your clocks are as you say because I get higher values with 72MHz CPU and 24MHz bus and flash clocks (the maximum in RUN mode). [are you sure your bus clock is in spec?]
It is possible to get faster reaction from an input port change to a port output by configuring a DMA transfer from the input's rising edge which causes an output to change, and then handling the DMA transfer's interrupt. The interrupt delay itself is not better but the output can be changed faster - in case the output change is important and not just being used to measure the times involved.
Here is the result of a DMA triggered change of PTB0 input going high until the PTC16 output goes high, with the 24MHz bus clock (output on CLKOUT) on the third line:
The delay from detecting the rising edge (triggering DMA) and the output changing varies from about 250ns to 300ns.
DMA transfer can only use GPIO space and not fast GPIO space so some of this may also be delays in the GPIO access.
Do you know what delay is the maximum that is permitted? Can the processor physically achieve this with its inherent interrupt latency?
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]