diff --git a/boards/arduino-mkr-common/include/periph_conf.h b/boards/arduino-mkr-common/include/periph_conf.h index 6fc69bec0d..a538729ad6 100644 --- a/boards/arduino-mkr-common/include/periph_conf.h +++ b/boards/arduino-mkr-common/include/periph_conf.h @@ -104,12 +104,14 @@ extern "C" { */ static const uart_conf_t uart_config[] = { { - .dev = &SERCOM5->USART, - .rx_pin = GPIO_PIN(PB,23), /* ARDUINO_PIN_13, RX Pin */ - .tx_pin = GPIO_PIN(PB,22), /* ARDUINO_PIN_14, TX Pin */ - .mux = GPIO_MUX_D, - .rx_pad = UART_PAD_RX_3, - .tx_pad = UART_PAD_TX_2 + .dev = &SERCOM5->USART, + .rx_pin = GPIO_PIN(PB,23), /* ARDUINO_PIN_13, RX Pin */ + .tx_pin = GPIO_PIN(PB,22), /* ARDUINO_PIN_14, TX Pin */ + .mux = GPIO_MUX_D, + .rx_pad = UART_PAD_RX_3, + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 } }; diff --git a/boards/arduino-zero/include/periph_conf.h b/boards/arduino-zero/include/periph_conf.h index 773ada0dd2..a34cd81e83 100644 --- a/boards/arduino-zero/include/periph_conf.h +++ b/boards/arduino-zero/include/periph_conf.h @@ -107,20 +107,24 @@ extern "C" { */ static const uart_conf_t uart_config[] = { { - .dev = &SERCOM5->USART, - .rx_pin = GPIO_PIN(PB,23), - .tx_pin = GPIO_PIN(PB,22), - .mux = GPIO_MUX_D, - .rx_pad = UART_PAD_RX_3, - .tx_pad = UART_PAD_TX_2 + .dev = &SERCOM5->USART, + .rx_pin = GPIO_PIN(PB,23), + .tx_pin = GPIO_PIN(PB,22), + .mux = GPIO_MUX_D, + .rx_pad = UART_PAD_RX_3, + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { - .dev = &SERCOM0->USART, - .rx_pin = GPIO_PIN(PA,11), - .tx_pin = GPIO_PIN(PA,10), - .mux = GPIO_MUX_C, - .rx_pad = UART_PAD_RX_3, - .tx_pad = UART_PAD_TX_2 + .dev = &SERCOM0->USART, + .rx_pin = GPIO_PIN(PA,11), + .tx_pin = GPIO_PIN(PA,10), + .mux = GPIO_MUX_C, + .rx_pad = UART_PAD_RX_3, + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 } }; diff --git a/boards/samd21-xpro/include/periph_conf.h b/boards/samd21-xpro/include/periph_conf.h index 33a080b404..02e138ae64 100644 --- a/boards/samd21-xpro/include/periph_conf.h +++ b/boards/samd21-xpro/include/periph_conf.h @@ -112,12 +112,14 @@ extern "C" { */ static const uart_conf_t uart_config[] = { { /* Virtual COM Port */ - .dev = &SERCOM3->USART, - .rx_pin = GPIO_PIN(PA,23), - .tx_pin = GPIO_PIN(PA,22), - .mux = GPIO_MUX_C, - .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_0 + .dev = &SERCOM3->USART, + .rx_pin = GPIO_PIN(PA,23), + .tx_pin = GPIO_PIN(PA,22), + .mux = GPIO_MUX_C, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_0, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { /* EXT1 */ .dev = &SERCOM4->USART, @@ -125,7 +127,9 @@ static const uart_conf_t uart_config[] = { .tx_pin = GPIO_PIN(PB,8), .mux = GPIO_MUX_D, .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_0 + .tx_pad = UART_PAD_TX_0, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { /* EXT2/3 */ .dev = &SERCOM4->USART, @@ -133,7 +137,9 @@ static const uart_conf_t uart_config[] = { .tx_pin = GPIO_PIN(PB,10), .mux = GPIO_MUX_D, .rx_pad = UART_PAD_RX_3, - .tx_pad = UART_PAD_TX_2 + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 } }; diff --git a/boards/saml21-xpro/include/periph_conf.h b/boards/saml21-xpro/include/periph_conf.h index 2a06a98398..d3b77a23b0 100644 --- a/boards/saml21-xpro/include/periph_conf.h +++ b/boards/saml21-xpro/include/periph_conf.h @@ -52,22 +52,34 @@ extern "C" { * @name UART configuration * @{ */ -#define UART_NUMOF (1U) -#define UART_0_EN 1 -#define UART_IRQ_PRIO 1 +static const uart_conf_t uart_config[] = { + { /* Virtual COM Port */ + .dev = &SERCOM3->USART, + .rx_pin = GPIO_PIN(PA,23), + .tx_pin = GPIO_PIN(PA,22), + .mux = GPIO_MUX_C, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_0, + .runstdby = 0, + .gclk_src = GCLK_PCHCTRL_GEN_GCLK0 + }, + { /* EXT1 header */ + .dev = &SERCOM4->USART, + .rx_pin = GPIO_PIN(PB, 9), + .tx_pin = GPIO_PIN(PB, 8), + .mux = GPIO_MUX_D, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_0, + .runstdby = 0, + .gclk_src = GCLK_PCHCTRL_GEN_GCLK0 + } +}; -/* UART 0 device configuration */ -#define UART_0_DEV SERCOM3->USART -#define UART_0_IRQ SERCOM3_IRQn +/* interrupt function name mapping */ #define UART_0_ISR isr_sercom3 -#define UART_0_REF_F (16000000UL) -#define UART_0_RUNSTDBY 1 +#define UART_1_ISR isr_sercom4 -/* UART 0 pin configuration */ -#define UART_0_PORT (PORT->Group[0]) -#define UART_0_TX_PIN (22) -#define UART_0_RX_PIN (23) -#define UART_0_PINS (((PORT_PA22 | PORT_PA23) >> 16) | PORT_WRCONFIG_HWSEL) +#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0])) /** @} */ /** diff --git a/boards/samr21-xpro/include/periph_conf.h b/boards/samr21-xpro/include/periph_conf.h index aae2a47786..18881a5b85 100644 --- a/boards/samr21-xpro/include/periph_conf.h +++ b/boards/samr21-xpro/include/periph_conf.h @@ -117,7 +117,9 @@ static const uart_conf_t uart_config[] = { .tx_pin = GPIO_PIN(PA,4), .mux = GPIO_MUX_D, .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_0 + .tx_pad = UART_PAD_TX_0, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { .dev = &SERCOM5->USART, @@ -125,7 +127,9 @@ static const uart_conf_t uart_config[] = { .tx_pin = GPIO_PIN(PA,22), .mux = GPIO_MUX_D, .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_0 + .tx_pad = UART_PAD_TX_0, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 } }; diff --git a/boards/sodaq-autonomo/include/periph_conf.h b/boards/sodaq-autonomo/include/periph_conf.h index c4a272ef52..e8e77dbcaf 100644 --- a/boards/sodaq-autonomo/include/periph_conf.h +++ b/boards/sodaq-autonomo/include/periph_conf.h @@ -103,36 +103,44 @@ extern "C" { */ static const uart_conf_t uart_config[] = { { - .dev = &SERCOM0->USART, - .rx_pin = GPIO_PIN(PA,9), - .tx_pin = GPIO_PIN(PA,10), - .mux = GPIO_MUX_C, - .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_2, + .dev = &SERCOM0->USART, + .rx_pin = GPIO_PIN(PA,9), + .tx_pin = GPIO_PIN(PA,10), + .mux = GPIO_MUX_C, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { - .dev = &SERCOM5->USART, - .rx_pin = GPIO_PIN(PB,31), - .tx_pin = GPIO_PIN(PB,30), - .mux = GPIO_MUX_D, - .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_0_RTS_2_CTS_3, + .dev = &SERCOM5->USART, + .rx_pin = GPIO_PIN(PB,31), + .tx_pin = GPIO_PIN(PB,30), + .mux = GPIO_MUX_D, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_0_RTS_2_CTS_3, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { - .dev = &SERCOM4->USART, - .rx_pin = GPIO_PIN(PB,13), - .tx_pin = GPIO_PIN(PA,14), - .mux = GPIO_MUX_C, - .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_2, + .dev = &SERCOM4->USART, + .rx_pin = GPIO_PIN(PB,13), + .tx_pin = GPIO_PIN(PA,14), + .mux = GPIO_MUX_C, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 }, { - .dev = &SERCOM1->USART, - .rx_pin = GPIO_PIN(PA,17), - .tx_pin = GPIO_PIN(PA,18), - .mux = GPIO_MUX_C, - .rx_pad = UART_PAD_RX_1, - .tx_pad = UART_PAD_TX_2, + .dev = &SERCOM1->USART, + .rx_pin = GPIO_PIN(PA,17), + .tx_pin = GPIO_PIN(PA,18), + .mux = GPIO_MUX_C, + .rx_pad = UART_PAD_RX_1, + .tx_pad = UART_PAD_TX_2, + .runstdby = 0, + .gclk_src = GCLK_CLKCTRL_GEN_GCLK0 } }; diff --git a/cpu/sam0_common/periph/uart.c b/cpu/sam0_common/periph/uart.c index fafe2cac9d..6e1c9fc219 100644 --- a/cpu/sam0_common/periph/uart.c +++ b/cpu/sam0_common/periph/uart.c @@ -51,44 +51,17 @@ static inline SercomUsart *_uart(uart_t dev) static uint64_t _long_division(uint64_t n, uint64_t d); -/** - * @brief Get the sercom gclk id of the given UART device - * - * @param[in] dev UART device identifier - * - * @return sercom gclk id - */ +static uint8_t sercom_gclk_id[] = + { + SERCOM0_GCLK_ID_CORE, + SERCOM1_GCLK_ID_CORE, + SERCOM2_GCLK_ID_CORE, + SERCOM3_GCLK_ID_CORE, + SERCOM4_GCLK_ID_CORE, + SERCOM5_GCLK_ID_CORE + }; -static int _get_sercom_gclk_id(SercomUsart *dev) -{ - int id; - switch(sercom_id(dev)) { - case 0: - id = SERCOM0_GCLK_ID_CORE; - break; - case 1: - id = SERCOM1_GCLK_ID_CORE; - break; - case 2: - id = SERCOM2_GCLK_ID_CORE; - break; - case 3: - id = SERCOM3_GCLK_ID_CORE; - break; - case 4: - id = SERCOM4_GCLK_ID_CORE; - break; - case 5: - id = SERCOM5_GCLK_ID_CORE; - break; - default: - id = -1; - DEBUG("[UART]: wrong SERCOM ID\n"); - break; - } - return id; -} #endif static int init_base(uart_t uart, uint32_t baudrate); @@ -130,7 +103,7 @@ static int init_base(uart_t uart, uint32_t baudrate) #ifdef CPU_FAM_SAMD21 /* calculate baudrate */ - uint32_t baud = ((((uint32_t)CLOCK_CORECLOCK * 10) / baudrate) / 16); + uint32_t baud = ((((uint32_t)CLOCK_CORECLOCK * 10) / baudrate) / 16); /* enable sync and async clocks */ uart_poweron(uart); /* reset the UART device */ @@ -210,11 +183,12 @@ void uart_poweron(uart_t uart) while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} #elif CPU_FAM_SAML21 /* Enable the peripheral channel */ - GCLK->PCHCTRL[_get_sercom_gclk_id(dev)].reg |= GCLK_PCHCTRL_CHEN | - GCLK_PCHCTRL_GEN(uart_config[uart].gclk_src); + GCLK->PCHCTRL[sercom_gclk_id[sercom_id(dev)]].reg |= + GCLK_PCHCTRL_CHEN | GCLK_PCHCTRL_GEN(uart_config[uart].gclk_src); - while (!(GCLK->PCHCTRL[_get_sercom_gclk_id(dev)].reg & GCLK_PCHCTRL_CHEN)) {} - if(_get_sercom_gclk_id(dev) < 5) { + while (!(GCLK->PCHCTRL[sercom_gclk_id[sercom_id(dev)]].reg & + GCLK_PCHCTRL_CHEN)) {} + if(sercom_gclk_id[sercom_id(dev)] < 5) { MCLK->APBCMASK.reg |= MCLK_APBCMASK_SERCOM0 << sercom_id(dev); } else { @@ -240,9 +214,9 @@ void uart_poweroff(uart_t uart) while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {} #elif CPU_FAM_SAML21 /* Enable the peripheral channel */ - GCLK->PCHCTRL[_get_sercom_gclk_id(dev)].reg &= ~GCLK_PCHCTRL_CHEN; + GCLK->PCHCTRL[sercom_gclk_id[sercom_id(dev)]].reg &= ~GCLK_PCHCTRL_CHEN; - if(_get_sercom_gclk_id(dev) < 5) { + if(sercom_gclk_id[sercom_id(dev)] < 5) { MCLK->APBCMASK.reg &= ~(MCLK_APBCMASK_SERCOM0 << sercom_id(dev)); } else { @@ -259,7 +233,8 @@ static inline void irq_handler(uint8_t uartnum) #ifdef CPU_FAM_SAMD21 if (uart->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) { /* interrupt flag is cleared by reading the data register */ - uart_ctx[uartnum].rx_cb(uart_ctx[uartnum].arg, (uint8_t)(uart->DATA.reg)); + uart_ctx[uartnum].rx_cb(uart_ctx[uartnum].arg, + (uint8_t)(uart->DATA.reg)); } else if (uart->INTFLAG.reg & SERCOM_USART_INTFLAG_ERROR) { /* clear error flag */