/* p6_4.c UART on SERCOM3 Receive at 115,200 Baud (the 9600 was an error) * * Receive key strokes from terminal emulator (TeraTerm) of the * host PC to the UART on SERCOM3 of SAMD21 Xplained board. * The UART3 is connected to EDBG virtual connection to the host PC COM port. * Launch TeraTerm on a PC and hit any key. * The LED program from P3_5 of Chapter 3 is used to blink the yellow LED0 * according to the key received. * You need to wait till the blinking stops before hitting another key. * Received key is not echoed back to the terminal, so you will not set * the character displayed. * * By default, the clock is running at 1 MHz. * * Tested with Atmel Studio 7 v7.0.1006 and Keil MDK-ARM v5.21a */ #include "samd21.h" void UART3_init(void); void LED_blink(int value); void delayMs(int n); unsigned char* ARRAY_PORT_PINCFG0 = (unsigned char*)®_PORT_PINCFG0; unsigned char* ARRAY_PORT_PMUX0 = (unsigned char*)®_PORT_PMUX0; int main(void) { __disable_irq(); UART3_init(); /* initialize PB30 for LED0 */ REG_PORT_DIRSET1 = 0x40000000; /* initialize PB30 for LED0 */ REG_PORT_OUTSET1 = 0x40000000; /* turn off LED0 */ NVIC_EnableIRQ(SERCOM3_IRQn); /* enable interrupt at NVIC */ __enable_irq(); while (1) { } } void SERCOM3_Handler(void){ char c; if (REG_SERCOM3_USART_INTFLAG & 4) { c = REG_SERCOM3_USART_DATA; /* read the receive char and return it */ LED_blink(c); /* blink the LED0 */ REG_SERCOM3_USART_INTFLAG = 4; /* clear interrupt flag */ } } /* initialize UART3 to receive at 9600 Baud */ void UART3_init(void) { REG_GCLK_CLKCTRL = 0x4017; /* GCLK0 to SERCOM3 */ REG_PM_APBCMASK |= 0x00000020; /* enable bus clock for SERCOM3 */ REG_SERCOM3_USART_CTRLA |= 1; /* reset SERCOM3 */ while (REG_SERCOM3_USART_SYNCBUSY & 1) {} /* wait for reset to complete */ REG_SERCOM3_USART_CTRLA = 0x40104004; /* LSB first, async, no parity, PAD[1]-Rx, BAUD uses no fraction, 8x oversampling, internal clock */ REG_SERCOM3_USART_CTRLB = 0x00020000; /* enable Rx, one stop bit, 8 bit */ REG_SERCOM3_USART_BAUD = 5138; /* use arithmetic baud rate generation */ REG_SERCOM3_USART_CTRLA |= 2; /* enable SERCOM3 */ while (REG_SERCOM3_USART_SYNCBUSY & 2) {} /* wait for enable to complete */ ARRAY_PORT_PINCFG0[23] |= 1; /* allow pmux to set PA23 pin configuration */ ARRAY_PORT_PMUX0[11] = 0x20; /* PA23 = RxD */ REG_SERCOM3_USART_INTENSET = 4; /* enable receive complete interrupt */ } /* turn on or off the LEDs according to the value */ void LED_blink(int value) { value %= 16; /* cap the max count at 15 */ for (; value > 0; value--) { REG_PORT_OUTCLR1 = 0x40000000; /* turn on LED0 */ delayMs(200); REG_PORT_OUTSET1 = 0x40000000; /* turn off LED0 */ delayMs(200); } delayMs(800); } /* 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"); }