-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Open
Labels
Type: bugThe issue reports a bug / The PR fixes a bug (including spelling errors)The issue reports a bug / The PR fixes a bug (including spelling errors)
Description
Description
Erasing then write mux can generate spurious IRQ from another gpio sharing same extint
Steps to reproduce the issue
Example with PA6 and PB22 which share extint[6]:
void irq(void)
{
puts("IRQ");
}
int main(void)
{
gpio_init_int(GPIO_PIN(PA,6), GPIO_IN, GPIO_RISING, (gpio_cb_t)irq, NULL);
gpio_mux_t mux = GPIO_MUX_D;
gpio_t pin = GPIO_PIN(PB,22);
int pin_pos = _pin_pos(pin); // use _pin_pos from gpio.c
PortGroup* port = _port(pin); // use _port from gpio.c
while(1) {
xtimer_usleep(500000);
port->PMUX[pin_pos >> 1].reg &= ~(0xf << (4 * (pin_pos & 0x1)));
port->PMUX[pin_pos >> 1].reg |= (mux << (4 * (pin_pos & 0x1)));
}
return 0;
}
This code triggers some time (maybe 2sec, maybe 20sec) an IRQ on PA6!
I can confirm that the line PA6 stays to always 0 so there should not be any IRQ
I suggest to change https://github.com/RIOT-OS/RIOT/blob/2023.10-branch/cpu/sam0_common/periph/gpio.c#L147
void gpio_init_mux(gpio_t pin, gpio_mux_t mux)
{
PortGroup* port = _port(pin);
int pin_pos = _pin_pos(pin);
port->PINCFG[pin_pos].reg |= PORT_PINCFG_PMUXEN;
port->PMUX[pin_pos >> 1].reg &= ~(0xf << (4 * (pin_pos & 0x1)));
port->PMUX[pin_pos >> 1].reg |= (mux << (4 * (pin_pos & 0x1)));
}
by
void gpio_init_mux(gpio_t pin, gpio_mux_t mux)
{
PortGroup* port = _port(pin);
int pin_pos = _pin_pos(pin);
port->PINCFG[pin_pos].reg |= PORT_PINCFG_PMUXEN;
if (pin_pos & 1) {
port->PMUX[pin_pos >> 1].bit.PMUXO = mux;
} else {
port->PMUX[pin_pos >> 1].bit.PMUXE = mux;
}
}
Expected results
Set the mux without trigger an interrupt
Actual results
Trigger non desired interrupt
Versions
RIOT 2023-07
Metadata
Metadata
Labels
Type: bugThe issue reports a bug / The PR fixes a bug (including spelling errors)The issue reports a bug / The PR fixes a bug (including spelling errors)