Atmel SAM D10  External Interrupt Controller (EIC) doesn't work - Page 1
Forum section: electronics / general

author: FrankBuss
author_rank: Unknown
timestamp: February 09, 2021, 07:38:18 pm
content: I use this code for initialize the EIC to generate interrupts and wakeup from sleep mode, when a change on 2 pins are detected:Code:void init_eic() {// enable power for the EICPM->APBAMASK.bit.EIC_ = 1;// configure clock for the EICGCLK->CLKCTRL.reg =GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_EIC;while (GCLK->STATUS.bit.SYNCBUSY);// configure extint{7] for power button (PA23)PORT->Group.PINCFG.bit.PMUXEN = 1;PORT->Group.PINCFG.bit.INEN = 1;PORT->Group.PMUX[PORT_POWER_BUTTON / 2].reg = PORT_PMUX_PMUXO_A;PORT->Group.CTRL.reg |= 1 << PORT_POWER_BUTTON;PORT->Group.DIRCLR.reg = 1 << PORT_POWER_BUTTON;// configure extint{7] for charging flag (PA9)PORT->Group.PINCFG.bit.PMUXEN = 1;PORT->Group.PINCFG.bit.INEN = 1;PORT->Group.PMUX[PORT_CHARGING / 2].reg = PORT_PMUX_PMUXO_A;PORT->Group.CTRL.reg |= 1 << PORT_CHARGING;PORT->Group.DIRCLR.reg = 1 << PORT_CHARGING;// reset EICEIC->CTRL.bit.SWRST = 1;while (EIC->STATUS.bit.SYNCBUSY == 1);// enable wakeup on EXTINTEIC->WAKEUP.reg = 1 << 7;// trigger on falling and rising edges for EXTINT and enable input filterEIC->CONFIG.reg = EIC_CONFIG_SENSE7_BOTH | EIC_CONFIG_FILTEN7;// enable interrupt for EXTINTEIC->INTENSET.reg = 1 << 7;// enable EICEIC->CTRL.bit.ENABLE = 1;while (EIC->STATUS.bit.SYNCBUSY == 1);// clear spurious interrupt flag because of the filter (see errata)EIC->INTFLAG.reg = EIC->INTFLAG.reg;// enable EIC interrupt in the interrupt controllerNVIC_EnableIRQ(EIC_IRQn);}But it doesn't generate an interrupt, and it doesn't wakeup from sleep mode.The GCLK0 configuration works, it is configured for 8 MHz and used for other peripherals, This is the setup:Code:void init_clock() {uint32_t temp_genctrl;// 3 flash wait states allows to run down to 1.8 VNVMCTRL->CTRLB.bit.RWS = 3;/* Set OSC8M prescalar to divide by 1 */SYSCTRL->OSC8M.bit.PRESC = 0;/* Configure OSC8M as source for GCLK_GEN0 */GCLK_GENCTRL_Type genctrl = {0};GCLK->GENCTRL.bit.ID = 0; /* GENERATOR_ID - GCLK_GEN_0 */while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);temp_genctrl = GCLK->GENCTRL.reg;genctrl.bit.SRC = GCLK_GENCTRL_SRC_OSC8M_Val;genctrl.bit.GENEN = true;genctrl.bit.RUNSTDBY = true;GCLK->GENCTRL.reg = (genctrl.reg | temp_genctrl);while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);}The interrupt handler looks like this:Code:void EIC_Handler() {EIC->INTFLAG.reg = EIC->INTFLAG.reg;set_yellow_led(0);}No yellow LED, and breakpoints are not hit either. The rest of the program works. Interrupts in general work, too. For example I have setup a timer interrupt with TC1 and CC0, which used the GCLK0 clock to generate an interrupt with 20 Hz from the 8 MHz by setting the CC0 register to 400000 and configure it with the TC_CTRLA_WAVEGEN_MFRQ setting.

author: ataradov
author_rank: Super Contributor
timestamp: February 09, 2021, 09:14:08 pm
content: OSC8M itself has RUNSTDBY bit, you need to set it as well.

author: FrankBuss
author_rank: Unknown
timestamp: February 09, 2021, 10:52:51 pm
content: Thanks, this will help in standby mode. But currently it doesn't even generate an interrupt. It calls the interrupt once after the NVIC_EnableIRQ. If I clear pending interrupts before with NVIC_ClearPendingIRQ(EIC_IRQn), then the interrupt is never called.I think I might have a problem with the PMUX setting. But should be right.

author: ataradov
author_rank: Super Contributor
timestamp: February 09, 2021, 10:58:39 pm
content: Wait, how are you configuring two pins for the same function? I don't even know what would happen in that case.I would start by leaving only one of the pins configured.

author: FrankBuss
author_rank: Unknown
timestamp: February 09, 2021, 11:03:42 pm
content: You are right, now it works! I assumed they would be or'ed together. Will use a different extint channel for the other pin.