2019-04-10 08:47 AM
In out project we are making use of EXTI for interfacing a radio (RF) ASIC with STM32F411. Whenever, the radio has some data to be sent host it interrupts the host using the I/O line (drives the line high). This I/O line stays high till data is read by STM32 over SPI.
Now, we have configured this line to be external interrupt line with EXTI. And the functionality works as expected most of the time. But, we do see some scenarios where, EXTI controller does not raise an interrupt even though the I/O line is high.
To overcome this issue, we are monitoring the state of the I/O line to check if it is high and if true, try and read the data from radio over SPI.
A quick check at the state of the EXTI registers whenever this happens shows PR (pending register) set to 0 (no interrupt pending) and IMR (interrupt mask register) set to 0x400, which mean the associated interrupt being enabled.
Is there any reason why the EXTI might fail to capture a rising edge on the I/O line? STM32F4 does not support level sensitive interrupts, otherwise we could have configured the external interrupt as level sensitive.
Please do share your inputs.
2019-04-10 09:22 AM
This typically happens if the external device can generate two edges consecutively and you clear the pending register *after* the second edge arrives.
JW
2019-04-10 10:18 AM
Thanks for your response. As far as i am know,
Am i missing anything else? Please so share your inputs.
2019-04-10 10:50 AM
> The external device we have generates an edge everytime it has some data for host.
How often that can be? Is your total interrupt latency, ie. worst-case time from the physical edge to the point where the pending register is cleared, guaranteed to be faster than the closest two edges from the external device?
How do you notify the external device that you've accepted the data? Do you notify after clearing the pending register? Will the external device generate an edge if notification comes after it has more data?
JW
2019-04-11 04:48 AM
Thanks again for your quick response. Please find some important aspects regarding how/when the external device drives the I/O line and when the I/O line is cleared.
External device will only generate a second edge only after it is driven low. As the I/O line stays high until all the data is read by host MCU. Now, if there is more data accumulated from the point I/O line goes high to MCU reading it, it is fine. As, MCU will no do a partial read.
Now, with above said external device behaviour and handling from MCU. I don't understand how the host can still miss an edge?
2019-04-11 07:27 AM
What happens if:
Does your ISR always only read 1 set of data and then exit? Or does it check to see if more data is available before exiting? Does it check the state of the I/O line before exiting (i.e. does it keep reading data as long as the I/O line is high)?
2019-04-11 08:36 AM
Thanks Bob for you response. Please find the details as below:
Now getting to your queries:
> While ISR is reading 1 set of data, device receives a 2nd set of data
> does it keep reading data as long as the I/O line is high)?
2019-04-11 09:08 AM
> No, we just read the data when the I/O line is high and exit. And do not check for the status of the I/O line. Probably a good thing to do.
It's *necessary* to do so. This is the very root of your problem. There can't be a rising edge, if the signal remains high...
JW
2019-04-12 06:14 AM
Thanks for your response. Now i have added a check to verify if the I/O line is still high. And if true, attempt reading the data from the external device. This has definitely brought improvements, but has not fully fixed the issue.
Because, till now the workaround what we had for identifying missing edge interrupts and mitigating lock-up was with an API "radio_isr_kick()". This will be called from the FreeRTOS thread. And all "radio_isr_kick()" API does is,
And with the help of some flags i still see that, ISR handler gets executed from within "radio_isr_kick()". Which means the I/O line was high and EXTI somehow did not capture the edge.
2019-04-12 07:17 AM
Can you post the code from your interrupt function? You can remove the radio-specific code and replace it with a "radio stuff here" comment. And how are you "executing" the ISR handler from your kick function - using the EXTI_SWIER register? The status/interrupt output from your radio is not really an edge sensitive interrupt signal, it is a level sensitive signal. It appears that somehow your ISR is somehow exiting with the signal still asserted.