/* p6_2.c Interrupts from two I/O pins * * PA18 is configured to generate EIC interrupt through EXTINT2, * PA19 is configured to generate EIC interrupt through EXTINT3. * The interrupt handler blinks twice for EXTINT2 and three times * for EXTINT3. * * Tested with Atmel Studio 7 v7.0.1006 and Keil MDK-ARM v5.21a */ #include "samd21.h" unsigned char* ARRAY_PORT_PINCFG0 = (unsigned char*)®_PORT_PINCFG0; unsigned char* ARRAY_PORT_PMUX0 = (unsigned char*)®_PORT_PMUX0; void delayMs(int n); int main (void) { __disable_irq(); REG_PORT_DIRSET1 = 1 << 30; /* make PB30 output for LED */ ARRAY_PORT_PINCFG0[18] |= 7; /* make PA18 EXTINT2 */ ARRAY_PORT_PINCFG0[19] |= 7; /* make PA19 EXTINT3 */ ARRAY_PORT_PMUX0[9] = 0; /* PA18 = EXTINT2, PA19 = EXTINT3 */ REG_PORT_DIRCLR0 = 0xC0000; /* PA18, PA19 input */ REG_PORT_OUTSET0 = 0xC0000; /* pull up PA18, PA19 */ REG_GCLK_CLKCTRL = 0x4005; /* GCLK0 -> EIC */ REG_EIC_CONFIG0 |= 0x0000AA00; /* EXTINT2/3 filtered falling-edge */ REG_EIC_INTENSET = 0x000C; /* enable EXTINT2/3 */ REG_EIC_CTRL = 2; /* enable EIC */ NVIC_EnableIRQ(EIC_IRQn); __enable_irq(); while(1) { } } /* in the interrupt handler, the yellow LED0 blinks twice */ void EIC_Handler(void) { if (REG_EIC_INTFLAG & 0x0004) { /* if interrupt is from EXTINT2, blink twice */ REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED */ delayMs(250); REG_PORT_OUTSET1 = 0x40000000; /* turn off LED */ delayMs(250); REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED */ delayMs(250); REG_PORT_OUTSET1 = 0x40000000; /* turn off LED */ delayMs(250); REG_EIC_INTFLAG = 0x0004; /* clear interrupt flag */ } else if (REG_EIC_INTFLAG & 0x0008) { /* if interrupt is from EXTINT3, blink three times */ REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED */ delayMs(250); REG_PORT_OUTSET1 = 0x40000000; /* turn off LED */ delayMs(250); REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED */ delayMs(250); REG_PORT_OUTSET1 = 0x40000000; /* turn off LED */ delayMs(250); REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED */ delayMs(250); REG_PORT_OUTSET1 = 0x40000000; /* turn off LED */ delayMs(250); REG_EIC_INTFLAG = 0x0008; /* clear interrupt flag */ } else { /* spurious interrupt?, clear all interrupt flags */ REG_EIC_INTFLAG = REG_EIC_INTFLAG; /* clear all EIC interrupt flags */ } } /* millisecond delay based on 1 MHz system clock */ void delayMs(int n) { int i; for (; n > 0; n--) for (i = 0; i < 199; i++) __asm("nop"); }