Atmel ATSAMC21 interrupt callback flag not cleared - Page 1
Forum section: electronics / general

author: urosg
author_rank: Unknown
timestamp: May 17, 2021, 11:24:03 am
content: Hi,I am fairly new to the ATSAM Cortex-M family and have started a new project with Atmel Start where I configured all the needed pins etc. and also set four input pins to have interrupts when a low signal is detected.So far all good, project compiles, starts and the interrupt callback is called when I press the button (signal to low)BUT the problem is that the last interrupt callback is then constantly called.I created a global "count" array for that I increment each time the callback is called, and the counter increases for the last interrupt callback that was called.What am I doing wrong? Reading ASF4 documentation I do not see any reference that a callback should be "closed" with any specific call to function (i.e. clearing interrupt flag manually).Any help/reference towards possible solution would be greatly appreciated.

author: ataradov
author_rank: Super Contributor
timestamp: May 17, 2021, 04:18:51 pm
content: Did you configure it for a falling edge detection, or the low level? If later, then callback will be called for the duration of the button press.You do need to acknowledge all interrupts. I have no idea if ASF does that for you, you will have to check that yourself.

author: urosg
author_rank: Unknown
timestamp: May 18, 2021, 07:28:26 am
content: I configured as "low level" but the button is a normal SPDT switch (non-latching) and also the bit in EIC.INTFLAG is cleared, but the callback is still firing - since I am also running FreeRTOS it stops processing tasks as the MCU stays in interrupt routine.I noticed that the INTFLAG is set to 0x81 and the interrupt routine checks only for the first 4 bits - i.e. when cleared INTFLAG remains at 0x80, which shows interrupt at position 7 as active, but looking through code I could not find anything that would enable this interrupt.

author: MadScientist
author_rank: Frequent Contributor
timestamp: May 18, 2021, 07:41:01 am
content: In the C21 you generally must clear the interrupt flags manually. If you do this too soon you can potentially Re trigger an interrupt when using the EIC

author: ataradov
author_rank: Super Contributor
timestamp: May 18, 2021, 04:03:39 pm
content: INTFLAG value should not be relevant for the interrupt firing. It is also masked by the value of INTENCLR/INTENSET. But looking at the code generated by start, it actually loops waiting for all flags to clear. And it will get confused by the extra bit set.Can you share your whole project?

author: urosg
author_rank: Unknown
timestamp: May 20, 2021, 02:25:53 pm
content: Yes, i modified the code a little bit to process only the defined interrupts and to break out of the routine.Also "detected" PIN for interrupt is not cleared on next loop after a "pin" was found.Modified routine in "hpl_eic.c":Code:/*** \brief Inter EIC interrupt handler*/static void _ext_irq_handler(void){volatile uint32_t flags = hri_eic_read_INTFLAG_reg(EIC);int8_t pos;int8_t intcnt = EXT_IRQ_AMOUNT; /* max. loops - as interrupt map is filled from index 0 to EXT_IRQ_AMOUNT */hri_eic_clear_INTFLAG_reg(EIC, flags);ASSERT(callback);while (flags && intcnt-- > 0) {pos = ffs(flags) - 1;while (-1 != pos) {uint8_t lower = 0, middle, upper = EXT_IRQ_AMOUNT;uint32_t pin = INVALID_PIN_NUMBER; /* set PIN to INVALID to force detection again */while (upper >= lower) {middle = (upper + lower) >> 1;if (_map.extint == pos) {pin = _map.pin;break;}if (_map.extint < pos) {lower = middle + 1;} else {upper = middle - 1;}}if (INVALID_PIN_NUMBER != pin) {callback(pin);break; /* stop processing this interrupt */}flags &= ~(1ul << pos);pos = ffs(flags) - 1;}flags = hri_eic_read_INTFLAG_reg(EIC);hri_eic_clear_INTFLAG_reg(EIC, flags);}}

author: ataradov
author_rank: Super Contributor
timestamp: May 20, 2021, 06:13:24 pm
content: This is not a complete project.There should be no flags set that correspond to the unconfigured pins. So if some extra flags are set, you must be configuring them. You need to figure out why this happens instead of trying to apply workarounds.

author: PlainName
author_rank: Super Contributor
timestamp: May 20, 2021, 06:59:30 pm
content: Nothing to do with the flag, sorry, but this caught my eye:Code:ASSERT(callback);...if (INVALID_PIN_NUMBER != pin) {callback(pin);break; /* stop processing this interrupt */}ASSERT() is generally there to force a crash on some unexpected situation during development, but you would normally disable them for production. If you do that here and callback is not defined, the ISR will crash. But if you leave the assert enabled, the ISR will crash anyway.I think that it would be better to check for callback being defined before you call it regardless (i.e. if (callback) callback(pin), which makes it safe. The assert can then be left in for development to tell you it's screwed, but disabling it won't cause an issue for production.