Skip to content

gpio_acknowledge_irq() causes latency #2543

@romain145

Description

@romain145

I'm trying to quickly react to a GPIO change on a RP2040.
The GPIO interrupt is setup as follow:

    gpio_set_irq_enabled(FPL_I_FAULT_IN, GPIO_IRQ_EDGE_FALL, true);
    gpio_add_raw_irq_handler(FPL_I_FAULT_IN, &gpio_isr);
    irq_set_enabled(IO_IRQ_BANK0, true); // Enable the IO IRQ for GPIO

The content of the ISR:

void __not_in_flash_func(gpio_isr)(void) {
    if (gpio_get_irq_event_mask(FPL_I_FAULT_IN) & GPIO_IRQ_EDGE_FALL) {
        gpio_acknowledge_irq(FPL_I_FAULT_IN, GPIO_IRQ_EDGE_FALL);
        gpio_put(CPU_D_DISABLE_OUT, 1);
    }
}

Calling gpio_acknowledge_irq() before setting the pin to 1 causes a latency of 2.4us:

Image

The obvious solution is to call it after.
Calling gpio_acknowledge_irq() after setting the pin to 1 causes a latency of only 525ns:

Image

I was looking at the code to understand why clearing a bit was taking so long whe it struck me: the Flash!

I changed the definition of gpio_acknowledge_irq() to run from RAM as follows:

void __not_in_flash_func(gpio_acknowledge_irq)(uint gpio, uint32_t events) {
    check_gpio_param(gpio);
    io_bank0_hw->intr[gpio / 8] = events << (4 * (gpio % 8));
}

And this is the result I got: 637ns:
Image

I know this will up for debate, but should this function that is almost-exclusively called from ISR, be run from RAM anyway?
Or what should the fix be in my case? (even calling gpio_acknowledge_irq() after setting the bit causes an unnecessary delay before the ISR returns).
RFC 😄

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions