1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 04:52:59 +01:00

cpu/lpc1768: Fix uart initialization

The pinsel_shift should be multiplied by 2 as each bitfield is 2 bits
This commit is contained in:
MrKevinWeiss 2020-09-09 16:28:25 +02:00
parent df913bf9bf
commit 966527d168
4 changed files with 22 additions and 22 deletions

View File

@ -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,
}
};

View File

@ -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

View File

@ -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 */

View File

@ -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)