diff --git a/boards/mbed_lpc1768/include/periph_conf.h b/boards/mbed_lpc1768/include/periph_conf.h index aa755232ee..fa0791b967 100644 --- a/boards/mbed_lpc1768/include/periph_conf.h +++ b/boards/mbed_lpc1768/include/periph_conf.h @@ -53,6 +53,7 @@ static const uart_conf_t uart_config[] = { { .dev = (LPC_UART_TypeDef*)LPC_UART0, .irq_rx = UART0_IRQn, + .clk_offset = 3, .pinsel = 0, .pinsel_shift = 2, .pinsel_af = 1, @@ -60,8 +61,9 @@ static const uart_conf_t uart_config[] = { { .dev = (LPC_UART_TypeDef*)LPC_UART2, .irq_rx = UART2_IRQn, + .clk_offset = 24, .pinsel = 0, - .pinsel_shift = 20, + .pinsel_shift = 10, .pinsel_af = 1, } }; diff --git a/boards/seeeduino_arch-pro/include/periph_conf.h b/boards/seeeduino_arch-pro/include/periph_conf.h index c5c0d2ce24..6ba66558bd 100644 --- a/boards/seeeduino_arch-pro/include/periph_conf.h +++ b/boards/seeeduino_arch-pro/include/periph_conf.h @@ -54,6 +54,7 @@ static const uart_conf_t uart_config[] = { { .dev = (LPC_UART_TypeDef*)LPC_UART0, .irq_rx = UART0_IRQn, + .clk_offset = 3, .pinsel = 0, .pinsel_shift = 2, .pinsel_af = 1, @@ -61,6 +62,7 @@ static const uart_conf_t uart_config[] = { { .dev = (LPC_UART_TypeDef*)LPC_UART3, .irq_rx = UART3_IRQn, + .clk_offset = 25, .pinsel = 0, .pinsel_shift = 0, .pinsel_af = 2 diff --git a/cpu/lpc1768/include/periph_cpu.h b/cpu/lpc1768/include/periph_cpu.h index 7cc587ad21..e528037c82 100644 --- a/cpu/lpc1768/include/periph_cpu.h +++ b/cpu/lpc1768/include/periph_cpu.h @@ -81,6 +81,7 @@ typedef enum { typedef struct { LPC_UART_TypeDef *dev; /**< pointer to the UART device */ uint8_t irq_rx; /**< RX IRQ number */ + uint8_t clk_offset; /**< The offset of the periph in the clk sel */ uint8_t pinsel; /**< PINSEL# of the RX and TX pin */ uint8_t pinsel_shift; /**< TX/RX bitshift of the PINSEL# register */ uint8_t pinsel_af; /**< Alternate function of the PINSEL# register */ diff --git a/cpu/lpc1768/periph/uart.c b/cpu/lpc1768/periph/uart.c index 8f5c3c3ec3..395c9c46ae 100644 --- a/cpu/lpc1768/periph/uart.c +++ b/cpu/lpc1768/periph/uart.c @@ -24,12 +24,6 @@ #include "periph/uart.h" #include "periph_conf.h" -/* For the clock modules we can take advantage of the offsets in the - * register map to find the bitshifting that is needed. - */ -#define _DEV_ADDR(uart) ((uint32_t)(uart_config[uart].dev)) -#define _DEV_OFFSET(uart) ((_DEV_ADDR(uart) - LPC_APB0_BASE) / 0x4000) - /** * @brief UART device configurations */ @@ -78,14 +72,13 @@ static inline void init_base(uart_t uart, uint32_t baudrate) const uart_conf_t *cfg = &uart_config[uart]; /* The RX/TX must be together */ assert(cfg->pinsel_shift <= 27); - /* power on UART device and select peripheral clock */ - LPC_SC->PCONP |= (1 << _DEV_OFFSET(uart)); - if (_DEV_OFFSET(uart) >= 16) { - LPC_SC->PCLKSEL1 &= ~(0x3 << ((_DEV_OFFSET(uart) * 2) - 32)); + LPC_SC->PCONP |= (1 << cfg->clk_offset); + if (cfg->clk_offset >= 16) { + LPC_SC->PCLKSEL1 &= ~((uint32_t)0x3 << ((cfg->clk_offset - 16) * 2)); } else { - LPC_SC->PCLKSEL0 &= ~(0x3 << (_DEV_OFFSET(uart) * 2)); + LPC_SC->PCLKSEL0 &= ~((uint32_t)0x3 << (cfg->clk_offset * 2)); } /* set mode to 8N1 and enable access to divisor latch */ dev(uart)->LCR = ((0x3 << 0) | (1 << 7)); @@ -96,21 +89,23 @@ static inline void init_base(uart_t uart, uint32_t baudrate) dev(uart)->FCR = 1; /* Clear register for mux selection */ - *(&LPC_PINCON->PINSEL0 + cfg->pinsel) &= ~(0xF << (cfg->pinsel_shift)); + *(&LPC_PINCON->PINSEL0 + cfg->pinsel) &= + ~((uint32_t)0xF << (cfg->pinsel_shift * 2)); /* Select uart TX mux */ *(&LPC_PINCON->PINSEL0 + cfg->pinsel) |= - (cfg->pinsel_af << (cfg->pinsel_shift)); + ((uint32_t)cfg->pinsel_af << (cfg->pinsel_shift * 2)); /* Select uart RX mux */ *(&LPC_PINCON->PINSEL0 + cfg->pinsel) |= - (cfg->pinsel_af << (cfg->pinsel_shift + 2)); - + ((uint32_t)cfg->pinsel_af << (cfg->pinsel_shift * 2 + 2)); /* Clear modes for RX and TX pins */ - *(&LPC_PINCON->PINMODE0 + cfg->pinsel) &= ~(0xF << (cfg->pinsel_shift)); + *(&LPC_PINCON->PINMODE0 + cfg->pinsel) &= + ~((uint32_t)0xF << (cfg->pinsel_shift * 2)); /* Set TX mode */ - *(&LPC_PINCON->PINMODE0 + cfg->pinsel) |= (0x2 << (cfg->pinsel_shift)); + *(&LPC_PINCON->PINMODE0 + cfg->pinsel) |= + ((uint32_t)0x2 << (cfg->pinsel_shift * 2)); /* Set RX mode */ - *(&LPC_PINCON->PINMODE0 + cfg->pinsel) |= (0x2 << (cfg->pinsel_shift + 2)); - + *(&LPC_PINCON->PINMODE0 + cfg->pinsel) |= + ((uint32_t)0x2 << (cfg->pinsel_shift * 2 + 2)); /* disable access to divisor latch */ dev(uart)->LCR &= ~(1 << 7); } @@ -128,13 +123,13 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len) void uart_poweron(uart_t uart) { assert(uart < UART_NUMOF); - LPC_SC->PCONP |= (1 << _DEV_OFFSET(uart)); + LPC_SC->PCONP |= (1 << uart_config[uart].clk_offset); } void uart_poweroff(uart_t uart) { assert(uart < UART_NUMOF); - LPC_SC->PCONP &= ~(1 << _DEV_OFFSET(uart)); + LPC_SC->PCONP &= ~(1 << uart_config[uart].clk_offset); } static void irq_handler(uart_t uart)