/* p6_1.c using SW0 interrupt * * User Switch SW0 is used to generate interrupt through PA15. * When the switch is pressed, PA15 is shorted to ground through a * resistor. In this program, PA15 is configured as input with * internal pull-up resistor. So the pin idles at 1 and becomes 0 * when switch is pressed. * The falling-edge of PA15 (when switch is pressed) triggers an * interrupt from External Interrupt Controller (EIC). * In the interrupt handler, the user LED0 is blinked twice. * It serves as a crude way to debounce the switch. * * 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[15] |= 5; /* make PA15 EXTINT15 */ ARRAY_PORT_PMUX0[7] = 0; /* PA15 = EXTINT15 */ REG_PORT_OUTSET0 = 1 << 15; REG_GCLK_CLKCTRL = 0x4005; /* GCLK0 -> EIC */ REG_EIC_CONFIG1 |= 0xA0000000; /* EXTINT15 filtered falling-edge */ REG_EIC_INTENSET = 0x8000; /* enable EXTINT15 */ 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 & 0x8000) { 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 = 0x8000; /* 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"); }