Strange behavior on EXTINT ASF Driver for SAM D

1 post / 0 new
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i've encounterd a realy strange behavior when using the EXTINT ASF Driver for SAM D20. 
Below a short Code example running on a SAMD20 XplainedPro: 

struct usart_module usart;

void extint_handler1(void) { printf("1"); }
void extint_handler2(void) { printf("2"); }

int main (void)
	struct usart_config cfg_usart;
	cfg_usart.baudrate = 9600;
	cfg_usart.mux_setting = EDBG_CDC_SERCOM_MUX_SETTING;
	cfg_usart.pinmux_pad0 = EDBG_CDC_SERCOM_PINMUX_PAD0;
	cfg_usart.pinmux_pad1 = EDBG_CDC_SERCOM_PINMUX_PAD1;
	cfg_usart.pinmux_pad2 = EDBG_CDC_SERCOM_PINMUX_PAD2;
	cfg_usart.pinmux_pad3 = EDBG_CDC_SERCOM_PINMUX_PAD3;
	stdio_serial_init(&usart, EDBG_CDC_MODULE, &cfg_usart);

	struct extint_chan_conf cfg1, cfg2;
	cfg1.gpio_pin = PIN_PA10;
	cfg1.gpio_pin_mux = PINMUX_PA10A_EIC_EXTINT10;
	extint_chan_set_config(10, &cfg1);
	extint_register_callback(extint_handler1, 10, EXTINT_CALLBACK_TYPE_DETECT);
	extint_chan_enable_callback(10, EXTINT_CALLBACK_TYPE_DETECT);

	// Setup PIN_PA20 but don't enable the Callback yet
	cfg2.gpio_pin = PIN_PA20;
	cfg2.gpio_pin_mux = PINMUX_PA20A_EIC_EXTINT4;
	extint_chan_set_config(4, &cfg2);
	extint_register_callback(extint_handler2, 4, EXTINT_CALLBACK_TYPE_DETECT);
	extint_chan_disable_callback(4, EXTINT_CALLBACK_TYPE_DETECT); // Explicitly Disable Callback
	while (1)

Test Procedure:

1. Pull down PA10 - a Interrupt occurs and extint_handler1 is invoked (as expected)
2. Pull down PA20 - doesn't no interrupt occurs and the extint_handler2 is NOT invoked (expected also)
3. Pull down PA10 again - a Interrupt occurs, extint_handler1 and extint_handler2 are executed in sequence (NOT EXPECTED!!!)


From my understanding the INTFLAG Register of the EIC Module gets updated with detected events as soon as the channel is configured.
The INTENCLR / INTENSET Registers for the EIC controls only the Interrupt generation to the NVIC. 


After a look into the AFS Sources for the EXTINT / EIC iv'e seen that there's no check for a specific EIC Channel if the interrupt is enabled or not. 
If the NVIC fires the EIC_Handler, all callbacks for EIC Channels that has a 1 in the INTFLAG register get executed, regardless if the callbacks enabled or not. 


Does anybody noticed that before?


I can't belive that it should behave like this.





P.S.: And Yes, I know it's not the best idea to do printf's in an Interrupt handler. Just for Testing wink