Make the CC2538 UART driver more configurable
* We can now very easily switch between UART0 and UART1 through a define * We can also configure the UART RX and TX port/pin through defines
This commit is contained in:
parent
1f76b7d0f9
commit
6c6013b898
|
@ -48,49 +48,82 @@
|
|||
|
||||
static int (* input_handler)(unsigned char c);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Once we know what UART we're on, configure correct values to be written to
|
||||
* the correct registers
|
||||
*/
|
||||
#if UART_BASE==UART_1_BASE
|
||||
/* Running, in sleep, in deep sleep, enable the clock for the correct UART */
|
||||
#define SYS_CTRL_RCGCUART_UART SYS_CTRL_RCGCUART_UART1
|
||||
#define SYS_CTRL_SCGCUART_UART SYS_CTRL_SCGCUART_UART1
|
||||
#define SYS_CTRL_DCGCUART_UART SYS_CTRL_DCGCUART_UART1
|
||||
|
||||
#define NVIC_INT_UART NVIC_INT_UART1
|
||||
#define IOC_PXX_SEL_UART_TXD IOC_PXX_SEL_UART1_TXD
|
||||
#define IOC_UARTRXD_UART IOC_UARTRXD_UART1
|
||||
#else /* Defaults for UART0 */
|
||||
#define SYS_CTRL_RCGCUART_UART SYS_CTRL_RCGCUART_UART0
|
||||
#define SYS_CTRL_SCGCUART_UART SYS_CTRL_SCGCUART_UART0
|
||||
#define SYS_CTRL_DCGCUART_UART SYS_CTRL_DCGCUART_UART0
|
||||
|
||||
#define NVIC_INT_UART NVIC_INT_UART0
|
||||
|
||||
#define IOC_PXX_SEL_UART_TXD IOC_PXX_SEL_UART0_TXD
|
||||
#define IOC_UARTRXD_UART IOC_UARTRXD_UART0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
reset(void)
|
||||
{
|
||||
uint32_t lchr;
|
||||
|
||||
/* Make sure the UART is disabled before trying to configure it */
|
||||
REG(UART_0_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
|
||||
REG(UART_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
|
||||
|
||||
/* Clear error status */
|
||||
REG(UART_0_BASE | UART_ECR) = 0xFF;
|
||||
REG(UART_BASE | UART_ECR) = 0xFF;
|
||||
|
||||
/* Store LCHR configuration */
|
||||
lchr = REG(UART_0_BASE | UART_LCRH);
|
||||
lchr = REG(UART_BASE | UART_LCRH);
|
||||
|
||||
/* Flush FIFOs by clearing LCHR.FEN */
|
||||
REG(UART_0_BASE | UART_LCRH) = 0;
|
||||
REG(UART_BASE | UART_LCRH) = 0;
|
||||
|
||||
/* Restore LCHR configuration */
|
||||
REG(UART_0_BASE | UART_LCRH) = lchr;
|
||||
REG(UART_BASE | UART_LCRH) = lchr;
|
||||
|
||||
/* UART Enable */
|
||||
REG(UART_0_BASE | UART_CTL) |= UART_CTL_UARTEN;
|
||||
REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uart_init(void)
|
||||
{
|
||||
/* Enable clock for the UART while Running, in Sleep and Deep Sleep */
|
||||
REG(SYS_CTRL_RCGCUART) |= SYS_CTRL_RCGCUART_UART0;
|
||||
REG(SYS_CTRL_SCGCUART) |= SYS_CTRL_DCGCUART_UART0;
|
||||
REG(SYS_CTRL_DCGCUART) |= SYS_CTRL_DCGCUART_UART0;
|
||||
REG(SYS_CTRL_RCGCUART) |= SYS_CTRL_RCGCUART_UART;
|
||||
REG(SYS_CTRL_SCGCUART) |= SYS_CTRL_SCGCUART_UART;
|
||||
REG(SYS_CTRL_DCGCUART) |= SYS_CTRL_DCGCUART_UART;
|
||||
|
||||
/* Run on SYS_DIV */
|
||||
REG(UART_0_BASE | UART_CC) = 0;
|
||||
REG(UART_BASE | UART_CC) = 0;
|
||||
|
||||
/* PA1: UART TX */
|
||||
REG(IOC_PA1_SEL) = IOC_PXX_SEL_UART0_TXD;
|
||||
/*
|
||||
* Select the UARTx RX pin by writing to the IOC_UARTRXD_UARTn register
|
||||
*
|
||||
* The value to be written will be on of the IOC_INPUT_SEL_Pxn defines from
|
||||
* ioc.h. The value can also be calculated as:
|
||||
*
|
||||
* (port << 3) + pin
|
||||
*/
|
||||
REG(IOC_UARTRXD_UART) = (UART_RX_PORT << 3) + UART_RX_PIN;
|
||||
|
||||
/* PA0: UART RX */
|
||||
REG(IOC_UARTRXD_UART0) = IOC_INPUT_SEL_PA0;
|
||||
|
||||
/* Pad Control: PA1 Output Enable */
|
||||
REG(IOC_PA1_OVER) = IOC_OVERRIDE_OE;
|
||||
/*
|
||||
* Pad Control for the TX pin:
|
||||
* - Set function to UART0 TX
|
||||
* - Output Enable
|
||||
*/
|
||||
ioc_set_sel(UART_TX_PORT, UART_TX_PIN, IOC_PXX_SEL_UART_TXD);
|
||||
ioc_set_over(UART_TX_PORT, UART_TX_PIN, IOC_OVERRIDE_OE);
|
||||
|
||||
/* Set PA[1:0] to peripheral mode */
|
||||
REG(GPIO_A_BASE | GPIO_AFSEL) |= (0x00000002 | 0x00000001);
|
||||
|
@ -100,27 +133,27 @@ uart_init(void)
|
|||
* Acknowledge RX and RX Timeout
|
||||
* Acknowledge Framing, Overrun and Break Errors
|
||||
*/
|
||||
REG(UART_0_BASE | UART_IM) = UART_IM_RXIM | UART_IM_RTIM;
|
||||
REG(UART_0_BASE | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM;
|
||||
REG(UART_BASE | UART_IM) = UART_IM_RXIM | UART_IM_RTIM;
|
||||
REG(UART_BASE | UART_IM) |= UART_IM_OEIM | UART_IM_BEIM | UART_IM_FEIM;
|
||||
|
||||
REG(UART_0_BASE | UART_IFLS) =
|
||||
REG(UART_BASE | UART_IFLS) =
|
||||
UART_IFLS_RXIFLSEL_1_8 | UART_IFLS_TXIFLSEL_1_2;
|
||||
|
||||
/* Make sure the UART is disabled before trying to configure it */
|
||||
REG(UART_0_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
|
||||
REG(UART_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
|
||||
|
||||
/* Baud Rate Generation */
|
||||
REG(UART_0_BASE | UART_IBRD) = UART_CONF_IBRD;
|
||||
REG(UART_0_BASE | UART_FBRD) = UART_CONF_FBRD;
|
||||
REG(UART_BASE | UART_IBRD) = UART_CONF_IBRD;
|
||||
REG(UART_BASE | UART_FBRD) = UART_CONF_FBRD;
|
||||
|
||||
/* UART Control: 8N1 with FIFOs */
|
||||
REG(UART_0_BASE | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
|
||||
REG(UART_BASE | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
|
||||
|
||||
/* UART Enable */
|
||||
REG(UART_0_BASE | UART_CTL) |= UART_CTL_UARTEN;
|
||||
REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN;
|
||||
|
||||
/* Enable UART0 Interrupts */
|
||||
nvic_interrupt_enable(NVIC_INT_UART0);
|
||||
nvic_interrupt_enable(NVIC_INT_UART);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -133,9 +166,9 @@ void
|
|||
uart_write_byte(uint8_t b)
|
||||
{
|
||||
/* Block if the TX FIFO is full */
|
||||
while(REG(UART_0_BASE | UART_FR) & UART_FR_TXFF);
|
||||
while(REG(UART_BASE | UART_FR) & UART_FR_TXFF);
|
||||
|
||||
REG(UART_0_BASE | UART_DR) = b;
|
||||
REG(UART_BASE | UART_DR) = b;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -147,18 +180,18 @@ uart_isr(void)
|
|||
|
||||
/* Store the current MIS and clear all flags early, except the RTM flag.
|
||||
* This will clear itself when we read out the entire FIFO contents */
|
||||
mis = REG(UART_0_BASE | UART_MIS) & 0x0000FFFF;
|
||||
mis = REG(UART_BASE | UART_MIS) & 0x0000FFFF;
|
||||
|
||||
REG(UART_0_BASE | UART_ICR) = 0x0000FFBF;
|
||||
REG(UART_BASE | UART_ICR) = 0x0000FFBF;
|
||||
|
||||
if(mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) {
|
||||
while(!(REG(UART_0_BASE | UART_FR) & UART_FR_RXFE)) {
|
||||
while(!(REG(UART_BASE | UART_FR) & UART_FR_RXFE)) {
|
||||
if(input_handler != NULL) {
|
||||
input_handler((unsigned char)(REG(UART_0_BASE | UART_DR) & 0xFF));
|
||||
input_handler((unsigned char)(REG(UART_BASE | UART_DR) & 0xFF));
|
||||
} else {
|
||||
/* To prevent an Overrun Error, we need to flush the FIFO even if we
|
||||
* don't have an input_handler. Use mis as a data trash can */
|
||||
mis = REG(UART_0_BASE | UART_DR);
|
||||
mis = REG(UART_BASE | UART_DR);
|
||||
}
|
||||
}
|
||||
} else if(mis & (UART_MIS_OEMIS | UART_MIS_BEMIS | UART_MIS_FEMIS)) {
|
||||
|
|
|
@ -52,6 +52,13 @@
|
|||
*/
|
||||
#define UART_0_BASE 0x4000C000
|
||||
#define UART_1_BASE 0x4000D000
|
||||
|
||||
/* Default to UART 0 unless the configuration tells us otherwise */
|
||||
#ifdef UART_CONF_BASE
|
||||
#define UART_BASE UART_CONF_BASE
|
||||
#else
|
||||
#define UART_BASE UART_0_BASE
|
||||
#endif
|
||||
/** @} */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -111,8 +111,11 @@
|
|||
* - CTS: PB0 (Can only be used with UART1)
|
||||
* - RTS: PD3 (Can only be used with UART1)
|
||||
*
|
||||
* We configure the port to use UART0. To use UART1, change UART_CONF_BASE
|
||||
* @{
|
||||
*/
|
||||
#define UART_CONF_BASE UART_0_BASE
|
||||
|
||||
#define UART_RX_PORT GPIO_A_NUM
|
||||
#define UART_RX_PIN 0
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
*/
|
||||
#include "contiki.h"
|
||||
#include "reg.h"
|
||||
#include "uart.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -71,12 +72,22 @@ void usb_isr(void);
|
|||
#define usb_isr default_handler
|
||||
#endif
|
||||
|
||||
/* Likewise for the UART ISR */
|
||||
/* Likewise for the UART[01] ISRs */
|
||||
#if UART_CONF_ENABLE
|
||||
void uart_isr(void);
|
||||
|
||||
#if UART_BASE==UART_1_BASE
|
||||
#define uart0_isr default_handler
|
||||
#define uart1_isr uart_isr
|
||||
#else
|
||||
#define uart_isr default_handler
|
||||
#define uart0_isr uart_isr
|
||||
#define uart1_isr default_handler
|
||||
#endif
|
||||
|
||||
#else /* UART_CONF_ENABLE */
|
||||
#define uart0_isr default_handler
|
||||
#define uart1_isr default_handler
|
||||
#endif /* UART_CONF_ENABLE */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Allocate stack space */
|
||||
static unsigned long stack[512];
|
||||
|
@ -123,8 +134,8 @@ void(*const vectors[])(void) =
|
|||
gpio_port_c_isr, /* 18 GPIO Port C */
|
||||
gpio_port_d_isr, /* 19 GPIO Port D */
|
||||
0, /* 20 none */
|
||||
uart_isr, /* 21 UART0 Rx and Tx */
|
||||
default_handler, /* 22 UART1 Rx and Tx */
|
||||
uart0_isr, /* 21 UART0 Rx and Tx */
|
||||
uart1_isr, /* 22 UART1 Rx and Tx */
|
||||
default_handler, /* 23 SSI0 Rx and Tx */
|
||||
default_handler, /* 24 I2C Master and Slave */
|
||||
0, /* 25 Reserved */
|
||||
|
|
Loading…
Reference in a new issue