mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
kinetis: Refactor UART driver
This commit is contained in:
parent
1162f2beff
commit
a107a416cf
@ -79,24 +79,19 @@ extern "C"
|
||||
* @name UART configuration
|
||||
* @{
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
#define UART_0_EN 1
|
||||
#define UART_IRQ_PRIO 1
|
||||
#define UART_CLK CLOCK_CORECLOCK
|
||||
|
||||
/* UART 0 device configuration */
|
||||
#define KINETIS_UART UART_Type
|
||||
#define UART_0_DEV UART0
|
||||
#define UART_0_CLKEN() (SIM->SCGC4 |= (SIM_SCGC4_UART0_MASK))
|
||||
#define UART_0_CLK UART_CLK
|
||||
#define UART_0_IRQ_CHAN UART0_RX_TX_IRQn
|
||||
#define UART_0_ISR isr_uart0_rx_tx
|
||||
/* UART 0 pin configuration */
|
||||
#define UART_0_PORT_CLKEN() (SIM->SCGC5 |= (SIM_SCGC5_PORTB_MASK))
|
||||
#define UART_0_PORT PORTB
|
||||
#define UART_0_RX_PIN 16
|
||||
#define UART_0_TX_PIN 17
|
||||
#define UART_0_AF 3
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{
|
||||
.dev = UART0,
|
||||
.clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
|
||||
.freq = CLOCK_CORECLOCK,
|
||||
.pin_rx = GPIO_PIN(PORT_B, 16),
|
||||
.pin_tx = GPIO_PIN(PORT_B, 17),
|
||||
.pcr_rx = PORT_PCR_MUX(3),
|
||||
.pcr_tx = PORT_PCR_MUX(3),
|
||||
.irqn = UART0_RX_TX_IRQn,
|
||||
},
|
||||
};
|
||||
#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -34,6 +34,11 @@
|
||||
/** Disable hardware watchdog, for debugging purposes, don't use this on production builds. */
|
||||
#define DISABLE_WDOG 1
|
||||
|
||||
/**
|
||||
* @brief Use the UART1 for STDIO on this board
|
||||
*/
|
||||
#define UART_STDIO_DEV UART_DEV(1)
|
||||
|
||||
/**
|
||||
* @brief xtimer configuration
|
||||
* @{
|
||||
|
@ -96,49 +96,29 @@ extern "C"
|
||||
* @name UART configuration
|
||||
* @{
|
||||
*/
|
||||
#define UART_NUMOF (2U)
|
||||
#define UART_0_EN 1
|
||||
#define UART_1_EN 1
|
||||
#define UART_2_EN 0
|
||||
#define UART_3_EN 0
|
||||
#define UART_4_EN 0
|
||||
#define UART_IRQ_PRIO CPU_DEFAULT_IRQ_PRIO
|
||||
|
||||
/* UART 0 device configuration */
|
||||
#define UART_0_DEV UART1
|
||||
#define UART_0_CLKEN() (BITBAND_REG32(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT) = 1)
|
||||
#define UART_0_CLKDIS() (BITBAND_REG32(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT) = 0)
|
||||
#define UART_0_CLK (CLOCK_CORECLOCK)
|
||||
#define UART_0_IRQ_CHAN UART1_RX_TX_IRQn
|
||||
#define UART_0_ISR isr_uart1_status
|
||||
/* UART 0 pin configuration */
|
||||
#define UART_0_PORT_CLKEN() (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT) = 1)
|
||||
#define UART_0_PORT PORTC
|
||||
#define UART_0_TX_PIN 4
|
||||
#define UART_0_RX_PIN 3
|
||||
/* Function number in pin multiplex, see K60 Sub-Family Reference Manual,
|
||||
* section 10.3.1 K60 Signal Multiplexing and Pin Assignments */
|
||||
#define UART_0_AF 3
|
||||
#define UART_0_TX_PCR_MUX 3
|
||||
#define UART_0_RX_PCR_MUX 3
|
||||
|
||||
/* UART 1 device configuration */
|
||||
#define UART_1_DEV UART0
|
||||
#define UART_1_CLKEN() (BITBAND_REG32(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT) = 1)
|
||||
#define UART_1_CLKDIS() (BITBAND_REG32(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT) = 0)
|
||||
#define UART_1_CLK (CLOCK_CORECLOCK)
|
||||
#define UART_1_IRQ_CHAN UART0_RX_TX_IRQn
|
||||
#define UART_1_ISR isr_uart0_status
|
||||
/* UART 1 pin configuration */
|
||||
#define UART_1_PORT_CLKEN() (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT) = 1)
|
||||
#define UART_1_PORT PORTA
|
||||
#define UART_1_TX_PIN 14
|
||||
#define UART_1_RX_PIN 15
|
||||
/* Function number in pin multiplex, see K60 Sub-Family Reference Manual,
|
||||
* section 10.3.1 K60 Signal Multiplexing and Pin Assignments */
|
||||
#define UART_1_AF 3
|
||||
#define UART_1_TX_PCR_MUX 3
|
||||
#define UART_1_RX_PCR_MUX 3
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{
|
||||
.dev = UART0,
|
||||
.clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
|
||||
.freq = CLOCK_CORECLOCK,
|
||||
.pin_rx = GPIO_PIN(PORT_A, 14),
|
||||
.pin_tx = GPIO_PIN(PORT_A, 15),
|
||||
.pcr_rx = PORT_PCR_MUX(3),
|
||||
.pcr_tx = PORT_PCR_MUX(3),
|
||||
.irqn = UART0_RX_TX_IRQn,
|
||||
},
|
||||
{
|
||||
.dev = UART1,
|
||||
.clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT)),
|
||||
.freq = CLOCK_CORECLOCK,
|
||||
.pin_rx = GPIO_PIN(PORT_C, 3),
|
||||
.pin_tx = GPIO_PIN(PORT_C, 4),
|
||||
.pcr_rx = PORT_PCR_MUX(3),
|
||||
.pcr_tx = PORT_PCR_MUX(3),
|
||||
.irqn = UART1_RX_TX_IRQn,
|
||||
},
|
||||
};
|
||||
#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0]))
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -30,6 +30,11 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Use the UART2 for STDIO on this board
|
||||
*/
|
||||
#define UART_STDIO_DEV UART_DEV(2)
|
||||
|
||||
/**
|
||||
* @name LED pin definitions and handlers
|
||||
* @{
|
||||
|
@ -81,38 +81,39 @@ extern "C"
|
||||
* @name UART configuration
|
||||
* @{
|
||||
*/
|
||||
#define UART_NUMOF (1U)
|
||||
#define UART_0_EN 1
|
||||
#define UART_1_EN 0
|
||||
#define UART_IRQ_PRIO 1
|
||||
#define UART_CLK (48e6)
|
||||
|
||||
/* UART 0 device configuration */
|
||||
#define KINETIS_UART UART_Type
|
||||
#define UART_0_DEV UART2
|
||||
#define UART_0_CLKEN() (SIM->SCGC4 |= (SIM_SCGC4_UART2_MASK))
|
||||
#define UART_0_CLK UART_CLK
|
||||
#define UART_0_IRQ_CHAN UART2_RX_TX_IRQn
|
||||
#define UART_0_ISR isr_uart2_rx_tx
|
||||
/* UART 0 pin configuration */
|
||||
#define UART_0_PORT_CLKEN() (SIM->SCGC5 |= (SIM_SCGC5_PORTD_MASK))
|
||||
#define UART_0_PORT PORTD
|
||||
#define UART_0_RX_PIN 2
|
||||
#define UART_0_TX_PIN 3
|
||||
#define UART_0_AF 3
|
||||
|
||||
/* UART 1 device configuration */
|
||||
#define UART_1_DEV UART0
|
||||
#define UART_1_CLKEN() (SIM->SCGC4 |= (SIM_SCGC4_UART0_MASK))
|
||||
#define UART_1_CLK UART_CLK
|
||||
#define UART_1_IRQ_CHAN UART0_RX_TX_IRQn
|
||||
#define UART_1_ISR isr_uart0_rx_tx
|
||||
/* UART 1 pin configuration */
|
||||
#define UART_1_PORT_CLKEN() (SIM->SCGC5 |= (SIM_SCGC5_PORTD_MASK))
|
||||
#define UART_1_PORT PORTD
|
||||
#define UART_1_RX_PIN 6
|
||||
#define UART_1_TX_PIN 7
|
||||
#define UART_1_AF 3
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{
|
||||
.dev = UART0,
|
||||
.clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
|
||||
.freq = CLOCK_CORECLOCK,
|
||||
.pin_rx = GPIO_PIN(PORT_D, 6),
|
||||
.pin_tx = GPIO_PIN(PORT_D, 7),
|
||||
.pcr_rx = PORT_PCR_MUX(3),
|
||||
.pcr_tx = PORT_PCR_MUX(3),
|
||||
.irqn = UART0_RX_TX_IRQn,
|
||||
},
|
||||
{
|
||||
.dev = UART1,
|
||||
.clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT)),
|
||||
.freq = CLOCK_CORECLOCK,
|
||||
.pin_rx = GPIO_UNDEF,
|
||||
.pin_tx = GPIO_UNDEF,
|
||||
.pcr_rx = PORT_PCR_MUX(3),
|
||||
.pcr_tx = PORT_PCR_MUX(3),
|
||||
.irqn = UART1_RX_TX_IRQn,
|
||||
},
|
||||
{
|
||||
.dev = UART2,
|
||||
.clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART2_SHIFT)),
|
||||
.freq = CLOCK_BUSCLOCK,
|
||||
.pin_rx = GPIO_PIN(PORT_D, 2),
|
||||
.pin_tx = GPIO_PIN(PORT_D, 3),
|
||||
.pcr_rx = PORT_PCR_MUX(3),
|
||||
.pcr_tx = PORT_PCR_MUX(3),
|
||||
.irqn = UART2_RX_TX_IRQn,
|
||||
},
|
||||
};
|
||||
#define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0]))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -77,14 +77,6 @@ extern "C"
|
||||
#define PORTE_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name UART driver settings
|
||||
*/
|
||||
/** @{ */
|
||||
/** UART typedef from CPU header. */
|
||||
#define KINETIS_UART UART_Type
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Clock settings for the LPTMR0 timer
|
||||
* @{
|
||||
|
@ -103,15 +103,15 @@ WEAK_DEFAULT void isr_can1_rx_warn(void);
|
||||
WEAK_DEFAULT void isr_can1_wake_up(void);
|
||||
/* void dummy_handler(void); */
|
||||
WEAK_DEFAULT void isr_uart0_lon(void);
|
||||
WEAK_DEFAULT void isr_uart0_status(void);
|
||||
WEAK_DEFAULT void isr_uart0_rx_tx(void);
|
||||
WEAK_DEFAULT void isr_uart0_error(void);
|
||||
WEAK_DEFAULT void isr_uart1_status(void);
|
||||
WEAK_DEFAULT void isr_uart1_rx_tx(void);
|
||||
WEAK_DEFAULT void isr_uart1_error(void);
|
||||
WEAK_DEFAULT void isr_uart2_status(void);
|
||||
WEAK_DEFAULT void isr_uart2_rx_tx(void);
|
||||
WEAK_DEFAULT void isr_uart2_error(void);
|
||||
WEAK_DEFAULT void isr_uart3_status(void);
|
||||
WEAK_DEFAULT void isr_uart3_rx_tx(void);
|
||||
WEAK_DEFAULT void isr_uart3_error(void);
|
||||
WEAK_DEFAULT void isr_uart4_status(void);
|
||||
WEAK_DEFAULT void isr_uart4_rx_tx(void);
|
||||
WEAK_DEFAULT void isr_uart4_error(void);
|
||||
/* void dummy_handler(void); */
|
||||
/* void dummy_handler(void); */
|
||||
@ -224,15 +224,15 @@ ISR_VECTORS const void *interrupt_vector[] = {
|
||||
(void*) isr_can1_wake_up,
|
||||
(void*) dummy_handler,
|
||||
(void*) isr_uart0_lon,
|
||||
(void*) isr_uart0_status,
|
||||
(void*) isr_uart0_rx_tx,
|
||||
(void*) isr_uart0_error,
|
||||
(void*) isr_uart1_status,
|
||||
(void*) isr_uart1_rx_tx,
|
||||
(void*) isr_uart1_error,
|
||||
(void*) isr_uart2_status,
|
||||
(void*) isr_uart2_rx_tx,
|
||||
(void*) isr_uart2_error,
|
||||
(void*) isr_uart3_status,
|
||||
(void*) isr_uart3_rx_tx,
|
||||
(void*) isr_uart3_error,
|
||||
(void*) isr_uart4_status,
|
||||
(void*) isr_uart4_rx_tx,
|
||||
(void*) isr_uart4_error,
|
||||
(void*) dummy_handler,
|
||||
(void*) dummy_handler,
|
||||
|
@ -316,28 +316,33 @@
|
||||
* The register UARTx_BDH to UARTx_C4 look almost the same.
|
||||
* We distinguish the type of the UART
|
||||
* using the BRFA field in the UART C4 register.
|
||||
* Currently, only the base functionality is available.
|
||||
* Currently, only the base TX/RX functionality is available.
|
||||
*
|
||||
* ### UART configuration Example (for periph_conf.h) ###
|
||||
*
|
||||
* #define UART_NUMOF (1U)
|
||||
* #define UART_0_EN 1
|
||||
* #define UART_IRQ_PRIO 1
|
||||
* #define UART_CLK (48e6)
|
||||
*
|
||||
* // UART 0 device configuration
|
||||
* #define KINETIS_UART UART0_Type
|
||||
* #define UART_0_DEV UART0
|
||||
* #define UART_0_CLKEN() (SIM->SCGC4 |= (SIM_SCGC4_UART0_MASK))
|
||||
* #define UART_0_CLK UART_CLK
|
||||
* #define UART_0_IRQ_CHAN UART0_IRQn
|
||||
* #define UART_0_ISR isr_uart0
|
||||
* // UART 0 pin configuration
|
||||
* #define UART_0_PORT_CLKEN() (SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK))
|
||||
* #define UART_0_PORT PORTA
|
||||
* #define UART_0_RX_PIN 1
|
||||
* #define UART_0_TX_PIN 2
|
||||
* #define UART_0_AF 2
|
||||
* static const uart_conf_t uart_config[] = {
|
||||
* {
|
||||
* .dev = UART0,
|
||||
* .clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART0_SHIFT)),
|
||||
* .freq = CLOCK_CORECLOCK,
|
||||
* .pin_rx = GPIO_PIN(PORT_A, 14),
|
||||
* .pin_tx = GPIO_PIN(PORT_A, 15),
|
||||
* .pcr_rx = PORT_PCR_MUX(3),
|
||||
* .pcr_tx = PORT_PCR_MUX(3),
|
||||
* .irqn = UART0_RX_TX_IRQn,
|
||||
* },
|
||||
* {
|
||||
* .dev = UART1,
|
||||
* .clken = (volatile uint32_t*)(BITBAND_REGADDR(SIM->SCGC4, SIM_SCGC4_UART1_SHIFT)),
|
||||
* .freq = CLOCK_CORECLOCK,
|
||||
* .pin_rx = GPIO_PIN(PORT_C, 3),
|
||||
* .pin_tx = GPIO_PIN(PORT_C, 4),
|
||||
* .pcr_rx = PORT_PCR_MUX(3),
|
||||
* .pcr_tx = PORT_PCR_MUX(3),
|
||||
* .irqn = UART1_RX_TX_IRQn,
|
||||
* },
|
||||
* };
|
||||
* #define UART_NUMOF (sizeof(uart_config) / sizeof(uart_config[0]))
|
||||
*
|
||||
* Optional settings:
|
||||
*
|
||||
|
@ -298,6 +298,20 @@ enum {
|
||||
#define TIMER_LPTMR_DEV(x) (TIMER_DEV(PIT_NUMOF + (x)))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief UART module configuration options
|
||||
*/
|
||||
typedef struct {
|
||||
UART_Type *dev; /**< Pointer to module hardware registers */
|
||||
volatile uint32_t *clken; /**< Clock enable bitband register address */
|
||||
uint32_t freq; /**< Module clock frequency, usually CLOCK_CORECLOCK or CLOCK_BUSCLOCK */
|
||||
gpio_t pin_rx; /**< RX pin, GPIO_UNDEF disables RX */
|
||||
gpio_t pin_tx; /**< TX pin */
|
||||
uint32_t pcr_rx; /**< Pin configuration register bits for RX */
|
||||
uint32_t pcr_tx; /**< Pin configuration register bits for TX */
|
||||
IRQn_Type irqn; /**< IRQ number for this module */
|
||||
} uart_conf_t;
|
||||
|
||||
/**
|
||||
* @brief CPU internal function for initializing PORTs
|
||||
*
|
||||
|
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Eistec AB
|
||||
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
*
|
||||
@ -17,6 +18,7 @@
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Johann Fischer <j.fischer@phytec.de>
|
||||
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
@ -42,7 +44,7 @@
|
||||
*/
|
||||
static uart_isr_ctx_t config[UART_NUMOF];
|
||||
|
||||
static inline void kinetis_set_brfa(KINETIS_UART *dev, uint32_t baudrate, uint32_t clk)
|
||||
static inline void kinetis_set_brfa(UART_Type *dev, uint32_t baudrate, uint32_t clk)
|
||||
{
|
||||
#if KINETIS_UART_ADVANCED
|
||||
/* set baudrate fine adjust (brfa) */
|
||||
@ -55,87 +57,43 @@ static int init_base(uart_t uart, uint32_t baudrate);
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
assert(uart < UART_NUMOF);
|
||||
/* do basic initialization */
|
||||
int res = init_base(uart, baudrate);
|
||||
if (res != UART_OK) {
|
||||
return res;
|
||||
}
|
||||
UART_Type *dev = uart_config[uart].dev;
|
||||
|
||||
/* remember callback addresses */
|
||||
config[uart].rx_cb = rx_cb;
|
||||
config[uart].arg = arg;
|
||||
|
||||
/* enable receive interrupt */
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
|
||||
case UART_0:
|
||||
NVIC_SetPriority(UART_0_IRQ_CHAN, UART_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(UART_0_IRQ_CHAN);
|
||||
UART_0_DEV->C2 |= (1 << UART_C2_RIE_SHIFT);
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
|
||||
case UART_1:
|
||||
NVIC_SetPriority(UART_1_IRQ_CHAN, UART_IRQ_PRIO);
|
||||
NVIC_EnableIRQ(UART_1_IRQ_CHAN);
|
||||
UART_1_DEV->C2 |= (1 << UART_C2_RIE_SHIFT);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return UART_NODEV;
|
||||
}
|
||||
NVIC_EnableIRQ(uart_config[uart].irqn);
|
||||
dev->C2 |= (1 << UART_C2_RIE_SHIFT);
|
||||
|
||||
return UART_OK;
|
||||
}
|
||||
|
||||
static int init_base(uart_t uart, uint32_t baudrate)
|
||||
{
|
||||
KINETIS_UART *dev;
|
||||
PORT_Type *port;
|
||||
UART_Type *dev = uart_config[uart].dev;
|
||||
uint32_t clk;
|
||||
uint16_t ubd;
|
||||
uint8_t tx_pin = 0;
|
||||
uint8_t rx_pin = 0;
|
||||
uint8_t af;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
clk = uart_config[uart].freq;
|
||||
|
||||
case UART_0:
|
||||
dev = UART_0_DEV;
|
||||
port = UART_0_PORT;
|
||||
clk = UART_0_CLK;
|
||||
tx_pin = UART_0_TX_PIN;
|
||||
rx_pin = UART_0_RX_PIN;
|
||||
af = UART_0_AF;
|
||||
UART_0_PORT_CLKEN();
|
||||
UART_0_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
|
||||
case UART_1:
|
||||
dev = UART_1_DEV;
|
||||
port = UART_1_PORT;
|
||||
clk = UART_1_CLK;
|
||||
tx_pin = UART_1_TX_PIN;
|
||||
rx_pin = UART_1_RX_PIN;
|
||||
af = UART_1_AF;
|
||||
UART_1_PORT_CLKEN();
|
||||
UART_1_CLKEN();
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return UART_NODEV;
|
||||
/* initialize pins */
|
||||
if (uart_config[uart].pin_rx != GPIO_UNDEF) {
|
||||
gpio_init_port(uart_config[uart].pin_rx, uart_config[uart].pcr_rx);
|
||||
}
|
||||
if (uart_config[uart].pin_tx != GPIO_UNDEF) {
|
||||
gpio_init_port(uart_config[uart].pin_tx, uart_config[uart].pcr_tx);
|
||||
}
|
||||
|
||||
/* configure RX and TX pins, set pin to use alternative function mode */
|
||||
port->PCR[rx_pin] = PORT_PCR_MUX(af);
|
||||
port->PCR[tx_pin] = PORT_PCR_MUX(af);
|
||||
/* Turn on module clock gate */
|
||||
*(uart_config[uart].clken) = 1;
|
||||
|
||||
/* disable transmitter and receiver */
|
||||
dev->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK);
|
||||
@ -180,46 +138,33 @@ static int init_base(uart_t uart, uint32_t baudrate)
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
KINETIS_UART *dev;
|
||||
|
||||
switch (uart) {
|
||||
#if UART_0_EN
|
||||
case UART_0:
|
||||
dev = UART_0_DEV;
|
||||
break;
|
||||
#endif
|
||||
#if UART_1_EN
|
||||
case UART_1:
|
||||
dev = UART_1_DEV;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
UART_Type *dev = uart_config[uart].dev;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
while (!(dev->S1 & UART_S1_TDRE_MASK));
|
||||
while (!(dev->S1 & UART_S1_TDRE_MASK)) {}
|
||||
dev->D = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void irq_handler(uart_t uartnum, KINETIS_UART *dev)
|
||||
static inline void irq_handler(uart_t uart)
|
||||
{
|
||||
UART_Type *dev = uart_config[uart].dev;
|
||||
|
||||
/*
|
||||
* On Cortex-M0, it happens that S1 is read with LDR
|
||||
* instruction instead of LDRB. This will read the data register
|
||||
* at the same time and arrived byte will be lost. Maybe it's a GCC bug.
|
||||
*
|
||||
* Observed with: arm-none-eabi-gcc (4.8.3-8+..)
|
||||
* It does not happen with: arm-none-eabi-gcc (4.8.3-9+11)
|
||||
*/
|
||||
* On Cortex-M0, it happens that S1 is read with LDR
|
||||
* instruction instead of LDRB. This will read the data register
|
||||
* at the same time and arrived byte will be lost. Maybe it's a GCC bug.
|
||||
*
|
||||
* Observed with: arm-none-eabi-gcc (4.8.3-8+..)
|
||||
* It does not happen with: arm-none-eabi-gcc (4.8.3-9+11)
|
||||
*/
|
||||
|
||||
if (dev->S1 & UART_S1_RDRF_MASK) {
|
||||
/* RDRF flag will be cleared when dev-D was read */
|
||||
uint8_t data = dev->D;
|
||||
|
||||
if (config[uartnum].rx_cb != NULL) {
|
||||
config[uartnum].rx_cb(config[uartnum].arg, data);
|
||||
if (config[uart].rx_cb != NULL) {
|
||||
config[uart].rx_cb(config[uart].arg, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,19 +176,29 @@ static inline void irq_handler(uart_t uartnum, KINETIS_UART *dev)
|
||||
#endif
|
||||
|
||||
cortexm_isr_end();
|
||||
|
||||
}
|
||||
|
||||
#if UART_0_EN
|
||||
void UART_0_ISR(void)
|
||||
void isr_uart0_rx_tx(void)
|
||||
{
|
||||
irq_handler(UART_0, UART_0_DEV);
|
||||
irq_handler(UART_DEV(0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_1_EN
|
||||
void UART_1_ISR(void)
|
||||
void isr_uart1_rx_tx(void)
|
||||
{
|
||||
irq_handler(UART_1, UART_1_DEV);
|
||||
irq_handler(UART_DEV(1));
|
||||
}
|
||||
|
||||
void isr_uart2_rx_tx(void)
|
||||
{
|
||||
irq_handler(UART_DEV(2));
|
||||
}
|
||||
|
||||
void isr_uart3_rx_tx(void)
|
||||
{
|
||||
irq_handler(UART_DEV(3));
|
||||
}
|
||||
|
||||
void isr_uart4_rx_tx(void)
|
||||
{
|
||||
irq_handler(UART_DEV(4));
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user