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:
parent
df913bf9bf
commit
966527d168
@ -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,
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user