IRQ Startup latency
Posted: Thu Jan 10, 2019 6:26 am
I am seeing a similar issue as noted here:
https://www.esp32.com/viewtopic.php?t=1108
The use case is a legacy bus interface, where the bi-directional nature of the bus is like I2S (open collector lines with pullups), but the data size is 4 bits.
The master will pull the "nybble" line low after placing data on the databus. 9.35uS later, it brings the "nybble" line high and checks to see if it is still low.
The esp32 needs to react to the line activity, and bring a corresponding output line (that is connected via a 74ls06 OC inverter) to the "nybble" line.
By checking on my logic analyzer, I see that the first events happens at time 0, and at T=9.35uS, the master brings the line high. At 17uS, the esp32 responds to the event and sets an IO line to respond, which is too late. It also takes 26uS to process the IRQ body, though I am using QueueSendfromISR in the body and the fact that the ISR takes 26uS to finish is actually OK (I assume there is startup cost to the QueueSend API).
Subsequent invocations of the IRQ handler appear to bring the IO response within 5uS, and executes the ISR body in 1.8uS. Thus, I know my code is working OK. And, if I recover from this issue without rebooting the esp32, subsequent communications works fine.
I tried to "prime" the ISR by generating an IRQ on the line before communication starts, but that did not seem to help. I am setting the GPIO first thing in my ISR.
I can work around the issue but creating a circuit that will hardware "ack" the event, but I am new to the esp32 and thought perhaps I am missing some small thing.
For reference, I am using GPIO_NUM_23 as my ISR input, setup as an IRQ via:
// I set up GPIO_NUM_23 as input with a pullup along with some other IO pins.
//hook isr handler for pin
gpio_isr_handler_add(GPIO_NUM_23 , isr_handler, NULL);
// trigger on negedge edge of pin
gpio_set_intr_type(GPIO_NUM_23 , GPIO_PIN_INTR_POSEDGE); //inverted logic
I used the blink example as my base, and added in the code from the gpio example to get going. FreeRTOS is running with 1 task.
I hated to bother folks with what I assume is a n00b question, but aside from the initial link, I didn't seem to find any relevant forum postings.
Jim
https://www.esp32.com/viewtopic.php?t=1108
The use case is a legacy bus interface, where the bi-directional nature of the bus is like I2S (open collector lines with pullups), but the data size is 4 bits.
The master will pull the "nybble" line low after placing data on the databus. 9.35uS later, it brings the "nybble" line high and checks to see if it is still low.
The esp32 needs to react to the line activity, and bring a corresponding output line (that is connected via a 74ls06 OC inverter) to the "nybble" line.
By checking on my logic analyzer, I see that the first events happens at time 0, and at T=9.35uS, the master brings the line high. At 17uS, the esp32 responds to the event and sets an IO line to respond, which is too late. It also takes 26uS to process the IRQ body, though I am using QueueSendfromISR in the body and the fact that the ISR takes 26uS to finish is actually OK (I assume there is startup cost to the QueueSend API).
Subsequent invocations of the IRQ handler appear to bring the IO response within 5uS, and executes the ISR body in 1.8uS. Thus, I know my code is working OK. And, if I recover from this issue without rebooting the esp32, subsequent communications works fine.
I tried to "prime" the ISR by generating an IRQ on the line before communication starts, but that did not seem to help. I am setting the GPIO first thing in my ISR.
I can work around the issue but creating a circuit that will hardware "ack" the event, but I am new to the esp32 and thought perhaps I am missing some small thing.
For reference, I am using GPIO_NUM_23 as my ISR input, setup as an IRQ via:
// I set up GPIO_NUM_23 as input with a pullup along with some other IO pins.
//hook isr handler for pin
gpio_isr_handler_add(GPIO_NUM_23 , isr_handler, NULL);
// trigger on negedge edge of pin
gpio_set_intr_type(GPIO_NUM_23 , GPIO_PIN_INTR_POSEDGE); //inverted logic
I used the blink example as my base, and added in the code from the gpio example to get going. FreeRTOS is running with 1 task.
I hated to bother folks with what I assume is a n00b question, but aside from the initial link, I didn't seem to find any relevant forum postings.
Jim