Our platform is CC2538 Evalauation module (EM) over SamrtRF06 Evaluation Board (EB). We are using UART0 whose RX and TX are wired to PA0 and PA1 by default.
TX works very fine (i.e. when MCU transmits on to the UART, we can receive the transmitted data at a peripheral device/PC with 100% success). However, the problem is with the UART RX (reception), when a PC/peripheral transmits some data to the MCU, miss rate is very high. Data is received only once in a while. We learnt from our further debugging that RX ISR is not triggered at all. Can we please get some input on what can be the reason (HW/SW issue)?
For reference I am pasting the uart_init() and iSR code below:
uart_init(void)
{
/* Enable clock for the UART while Running, in Sleep and Deep Sleep */
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_BASE | UART_CC) = 0;
/*
* 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;
/*
* 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 RX and TX pins to peripheral mode */
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(UART_TX_PORT), GPIO_PIN_MASK(UART_TX_PIN));
GPIO_PERIPHERAL_CONTROL(GPIO_PORT_TO_BASE(UART_RX_PORT), GPIO_PIN_MASK(UART_RX_PIN));
/*
* UART Interrupt Masks:
* Acknowledge RX and RX Timeout
* Acknowledge Framing, Overrun and Break Errors
*/
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_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_BASE | UART_CTL) = UART_CTL_TXE | UART_CTL_RXE;
/* Baud Rate Generation */
REG(UART_BASE | UART_IBRD) = UART_CONF_IBRD;
REG(UART_BASE | UART_FBRD) = UART_CONF_FBRD;
/* UART Control: 8N1 with FIFOs */
REG(UART_BASE | UART_LCRH) = UART_LCRH_WLEN_8 | UART_LCRH_FEN;
/* UART Enable */
REG(UART_BASE | UART_CTL) |= UART_CTL_UARTEN;
/* Enable UART0 Interrupts */
nvic_interrupt_enable(NVIC_INT_UART);
}
uart_isr(void)
{
uint16_t mis;
* 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_BASE | UART_MIS) & 0x0000FFFF;
REG(UART_BASE | UART_ICR) = 0x0000FFBF;
if(mis & (UART_MIS_RXMIS | UART_MIS_RTMIS)) {
while(!(REG(UART_BASE | UART_FR) & UART_FR_RXFE)) { // RXFIFO not empty
if(input_handler != NULL) {
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_BASE | UART_DR);
}
}
} else if(mis & (UART_MIS_OEMIS | UART_MIS_BEMIS | UART_MIS_FEMIS)) {
/* ISR triggered due to some error condition */
reset();
}
}