From c40e5267a6f6bc962f1284ea996a1b9ab0bbe4c6 Mon Sep 17 00:00:00 2001 From: BytesGalore Date: Tue, 16 Dec 2014 15:30:57 +0100 Subject: [PATCH] board/mbed_lpc1768 changed the serial device to UART0 -> enables USB/serial communication --- boards/mbed_lpc1768/Makefile.include | 2 +- boards/mbed_lpc1768/include/periph_conf.h | 41 +++- cpu/lpc1768/periph/uart.c | 270 +++++++++++++++++----- 3 files changed, 241 insertions(+), 72 deletions(-) diff --git a/boards/mbed_lpc1768/Makefile.include b/boards/mbed_lpc1768/Makefile.include index 1c46868832..d9be1207ed 100644 --- a/boards/mbed_lpc1768/Makefile.include +++ b/boards/mbed_lpc1768/Makefile.include @@ -4,7 +4,7 @@ export CPU = lpc1768 #define the default port depending on the host OS OS := $(shell uname) ifeq ($(OS),Linux) - PORT ?= /dev/ttyUSB0 + PORT ?= /dev/ttyACM0 else ifeq ($(OS),Darwin) PORT ?= $(shell ls -1 /dev/tty.SLAB_USBtoUART* | head -n 1) else diff --git a/boards/mbed_lpc1768/include/periph_conf.h b/boards/mbed_lpc1768/include/periph_conf.h index 87d4afe083..2478f2e511 100644 --- a/boards/mbed_lpc1768/include/periph_conf.h +++ b/boards/mbed_lpc1768/include/periph_conf.h @@ -46,23 +46,40 @@ extern "C" { * @brief UART configuration * @{ */ -#define UART_NUMOF (1U) +#define UART_NUMOF (2U) #define UART_0_EN 1 -#define UART_1_EN 0 +#define UART_1_EN 1 #define UART_IRQ_PRIO 1 /* UART 0 device configuration */ -#define UART_0_DEV LPC_UART3 -#define UART_0_CLKEN() (LPC_SC->PCONP |= (1 << 25)) -#define UART_0_CLKDIS() (LPC_SC->PCONP &= ~(1 << 25)) -#define UART_0_IRQ UART3_IRQn -#define UART_0_ISR isr_uart3 +#define UART_0_DEV LPC_UART0 +#define UART_0_CLKEN() (LPC_SC->PCONP |= (1 << 3)) +#define UART_0_CLKDIS() (LPC_SC->PCONP &= ~(1 << 3)) +#define UART_0_IRQ UART0_IRQn +#define UART_0_ISR isr_uart0 /* UART 0 pin configuration */ -#define UART_0_PINSEL (LPC_PINCON->PINSEL0) -#define UART_0_PINMODE (LPC_PINCON->PINMODE0) -#define UART_0_RX_PIN (0) -#define UART_0_TX_PIN (1) -#define UART_0_AF (2) +#define UART_0_TX_PINSEL (LPC_PINCON->PINSEL0) +#define UART_0_RX_PINSEL (LPC_PINCON->PINSEL0) +#define UART_0_TX_PINMODE (LPC_PINCON->PINMODE0) +#define UART_0_RX_PINMODE (LPC_PINCON->PINMODE0) +#define UART_0_TX_PIN (3) +#define UART_0_RX_PIN (2) +#define UART_0_AF (1) + +/* UART 1 device configuration */ +#define UART_1_DEV LPC_UART3 +#define UART_1_CLKEN() (LPC_SC->PCONP |= (1 << 25)) +#define UART_1_CLKDIS() (LPC_SC->PCONP &= ~(1 << 25)) +#define UART_1_IRQ UART3_IRQn +#define UART_1_ISR isr_uart3 +/* UART 1 pin configuration */ +#define UART_1_TX_PINSEL (LPC_PINCON->PINSEL0) +#define UART_1_RX_PINSEL (LPC_PINCON->PINSEL0) +#define UART_1_TX_PINMODE (LPC_PINCON->PINMODE0) +#define UART_1_RX_PINMODE (LPC_PINCON->PINMODE0) +#define UART_1_RX_PIN (0) +#define UART_1_TX_PIN (1) +#define UART_1_AF (2) /** @} */ #ifdef __cplusplus diff --git a/cpu/lpc1768/periph/uart.c b/cpu/lpc1768/periph/uart.c index bcf71fad5f..57dbe40b4a 100644 --- a/cpu/lpc1768/periph/uart.c +++ b/cpu/lpc1768/periph/uart.c @@ -26,7 +26,7 @@ #include "periph_conf.h" /* guard the file in case no UART is defined */ -#if UART_0_EN +#if (UART_0_EN || UART_1_EN) /** * @brief Struct holding the configuration data for a UART device @@ -44,103 +44,230 @@ static uart_conf_t config[UART_NUMOF]; int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, uart_tx_cb_t tx_cb, void *arg) { - if (uart == UART_0) { - int res = uart_init_blocking(uart, baudrate); - if (res < 0) { - return res; - } - /* save callbacks */ - config[UART_0].rx_cb = rx_cb; - config[UART_0].tx_cb = tx_cb; - config[UART_0].arg = arg; + int res = uart_init_blocking(uart, baudrate); + if (res < 0) { + return res; + } + + /* save callbacks */ + config[uart].rx_cb = rx_cb; + config[uart].tx_cb = tx_cb; + config[uart].arg = arg; + + switch (uart) { +#if UART_0_EN + case UART_0: /* configure and enable global device interrupts */ NVIC_SetPriority(UART_0_IRQ, UART_IRQ_PRIO); NVIC_EnableIRQ(UART_0_IRQ); /* enable RX interrupt */ UART_0_DEV->IER |= (1 << 0); - return 0; + break; +#endif +#if UART_1_EN + case UART_1: + /* configure and enable global device interrupts */ + NVIC_SetPriority(UART_1_IRQ, UART_IRQ_PRIO); + NVIC_EnableIRQ(UART_1_IRQ); + /* enable RX interrupt */ + UART_1_DEV->IER |= (1 << 0); + break; +#endif } - return -1; + + return 0; } int uart_init_blocking(uart_t uart, uint32_t baudrate) { - if (uart == UART_0) { - /* this implementation only supports 115200 baud */ - if (baudrate != 115200) { - return -2; - } - /* power on UART device */ - UART_0_CLKEN(); - /* set peripheral clock to CCLK / 4 */ - LPC_SC->PCLKSEL1 &= (0x3 << 18); - /* set mode to 8N1 and enable access to divisor latch */ - UART_0_DEV->LCR = ((0x3 << 0) | (1 << 7)); - /* set baud rate registers (fixed for now) */ - UART_0_DEV->DLM = 0; - UART_0_DEV->DLL = 13; - /* enable FIFOs */ - UART_0_DEV->FCR = 1; - /* select and configure pins */ - UART_0_PINSEL &= ~((0x3 << (UART_0_RX_PIN * 2)) | (0x3 << (UART_0_TX_PIN * 2))); - UART_0_PINSEL |= ((UART_0_AF << (UART_0_RX_PIN * 2)) | (UART_0_AF << (UART_0_TX_PIN * 2))); - UART_0_PINMODE &= ~((0x3 << (UART_0_RX_PIN * 2)) | (0x3 << (UART_0_TX_PIN * 2))); - UART_0_PINMODE |= ((0x2 << (UART_0_RX_PIN * 2)) | (0x2 << (UART_0_TX_PIN * 2))); - /* disable access to divisor latch */ - UART_0_DEV->LCR &= ~(1 << 7); - return 0; + switch (uart) { +#if UART_0_EN + case UART_0: + /* this implementation only supports 115200 baud */ + if (baudrate != 115200) { + return -2; + } + + /* power on UART device */ + UART_0_CLKEN(); + /* set peripheral clock to CCLK / 4 */ + LPC_SC->PCLKSEL1 &= (0x3 << 18); + + /* set mode to 8N1 and enable access to divisor latch */ + UART_0_DEV->LCR = ((0x3 << 0) | (1 << 7)); + /* set baud rate registers (fixed for now) */ + UART_0_DEV->DLM = 0; + UART_0_DEV->DLL = 13; + /* enable FIFOs */ + UART_0_DEV->FCR = 1; + /* select and configure the pin for RX */ + UART_0_RX_PINSEL &= ~(0x3 << (UART_0_RX_PIN * 2)); + UART_0_RX_PINSEL |= (UART_0_AF << (UART_0_RX_PIN * 2)); + UART_0_RX_PINMODE &= ~(0x3 << (UART_0_RX_PIN * 2)); + UART_0_RX_PINMODE |= (0x2 << (UART_0_RX_PIN * 2)); + /* select and configure the pin for TX */ + UART_0_TX_PINSEL &= ~(0x3 << (UART_0_TX_PIN * 2)); + UART_0_TX_PINSEL |= (UART_0_AF << (UART_0_TX_PIN * 2)); + UART_0_TX_PINMODE &= ~(0x3 << (UART_0_TX_PIN * 2)); + UART_0_TX_PINMODE |= (0x2 << (UART_0_TX_PIN * 2)); + /* disable access to divisor latch */ + UART_0_DEV->LCR &= ~(1 << 7); + break; +#endif +#if UART_1_EN + case UART_1: + /* this implementation only supports 115200 baud */ + if (baudrate != 115200) { + return -2; + } + + /* power on UART device */ + UART_1_CLKEN(); + /* set peripheral clock to CCLK / 4 */ + LPC_SC->PCLKSEL1 &= (0x3 << 18); + /* set mode to 8N1 and enable access to divisor latch */ + UART_1_DEV->LCR = ((0x3 << 0) | (1 << 7)); + /* set baud rate registers (fixed for now) */ + UART_1_DEV->DLM = 0; + UART_1_DEV->DLL = 13; + /* enable FIFOs */ + UART_1_DEV->FCR = 1; + /* select and configure the pin for RX */ + UART_1_RX_PINSEL &= ~(0x3 << (UART_1_RX_PIN * 2)); + UART_1_RX_PINSEL |= (UART_1_AF << (UART_1_RX_PIN * 2)); + UART_1_RX_PINMODE &= ~(0x3 << (UART_1_RX_PIN * 2)); + UART_1_RX_PINMODE |= (0x2 << (UART_1_RX_PIN * 2)); + /* select and configure the pin for TX */ + UART_1_TX_PINSEL &= ~(0x3 << (UART_1_TX_PIN * 2)); + UART_1_TX_PINSEL |= (UART_1_AF << (UART_1_TX_PIN * 2)); + UART_1_TX_PINMODE &= ~(0x3 << (UART_1_TX_PIN * 2)); + UART_1_TX_PINMODE |= (0x2 << (UART_1_TX_PIN * 2)); + /* disable access to divisor latch */ + UART_1_DEV->LCR &= ~(1 << 7); + break; +#endif + default: + return -1; } - return -1; + + return 0; } void uart_tx_begin(uart_t uart) { - if (uart == UART_0) { - /* enable TX interrupt */ - UART_0_DEV->IER |= (1 << 1); + switch (uart) { +#if UART_0_EN + case UART_0: + /* enable TX interrupt */ + UART_0_DEV->IER |= (1 << 1); + break; +#endif +#if UART_1_EN + case UART_1: + /* enable TX interrupt */ + UART_1_DEV->IER |= (1 << 1); + break; +#endif } } int uart_write(uart_t uart, char data) { - if (uart == UART_0) { - UART_0_DEV->THR = (uint8_t)data; - return 1; + switch (uart) { +#if UART_0_EN + case UART_0: + UART_0_DEV->THR = (uint8_t)data;; + break; +#endif +#if UART_1_EN + case UART_1: + UART_1_DEV->THR = (uint8_t)data;; + break; +#endif + default: + return -1; } - return -1; + + return 1; } int uart_read_blocking(uart_t uart, char *data) { - if (uart == UART_0) { - while (!(UART_0_DEV->LSR & (1 << 0))); /* wait for RDR bit to be set */ - *data = (char)UART_0_DEV->RBR; - return 1; + switch (uart) { +#if UART_0_EN + case UART_0: + while (!(UART_0_DEV->LSR & (1 << 0))); /* wait for RDR bit to be set */ + + *data = (char)UART_0_DEV->RBR; + break; +#endif +#if UART_1_EN + case UART_1: + while (!(UART_1_DEV->LSR & (1 << 0))); /* wait for RDR bit to be set */ + + *data = (char)UART_1_DEV->RBR; + break; +#endif + default: + return -1; } - return -1; + + return 1; } int uart_write_blocking(uart_t uart, char data) { - if (uart == UART_0) { - while (!(UART_0_DEV->LSR & (1 << 5))); /* wait for THRE bit to be set */ - UART_0_DEV->THR = (uint8_t)data; - return 1; + switch (uart) { +#if UART_0_EN + case UART_0: + while (!(UART_0_DEV->LSR & (1 << 5))); /* wait for THRE bit to be set */ + + UART_0_DEV->THR = (uint8_t)data; + break; +#endif +#if UART_1_EN + case UART_1: + while (!(UART_1_DEV->LSR & (1 << 5))); /* wait for THRE bit to be set */ + + UART_1_DEV->THR = (uint8_t)data; + break; +#endif + default: + return -1; } - return -1; + + return 1; } void uart_poweron(uart_t uart) { - if (uart == UART_0) { - UART_0_CLKEN(); + switch (uart) { +#if UART_0_EN + case UART_0: + UART_0_CLKEN(); + break; +#endif +#if UART_1_EN + case UART_1: + UART_1_CLKEN(); + break; +#endif } } void uart_poweroff(uart_t uart) { - if (uart == UART_0) { - UART_0_CLKDIS(); + switch (uart) { +#if UART_0_EN + case UART_0: + UART_0_CLKDIS(); + break; +#endif +#if UART_1_EN + case UART_1: + UART_1_CLKDIS(); + break; +#endif } } @@ -151,6 +278,7 @@ void UART_0_ISR(void) char data = (char)UART_0_DEV->RBR; config[UART_0].rx_cb(config[UART_0].arg, data); } + if (UART_0_DEV->LSR & (1 << 5)) { /* THRE flag set? */ if (UART_0_DEV->IER & (1 << 1)) { if (config[UART_0].tx_cb(config[UART_0].arg) == 0) { @@ -159,10 +287,34 @@ void UART_0_ISR(void) } } } + if (sched_context_switch_request) { thread_yield(); } } #endif -#endif /* UART_0_EN */ +#if UART_1_EN +void UART_1_ISR(void) +{ + if (UART_1_DEV->LSR & (1 << 0)) { /* is RDR flag set? */ + char data = (char)UART_1_DEV->RBR; + config[UART_1].rx_cb(config[UART_1].arg, data); + } + + if (UART_1_DEV->LSR & (1 << 5)) { /* THRE flag set? */ + if (UART_1_DEV->IER & (1 << 1)) { + if (config[UART_1].tx_cb(config[UART_1].arg) == 0) { + /* disable TX interrupt */ + UART_1_DEV->IER &= ~(1 << 1); + } + } + } + + if (sched_context_switch_request) { + thread_yield(); + } +} +#endif + +#endif /* (UART_0_EN || UART_1_EN) */