AnsweredAssumed Answered

We are experiencing UART0 FIFO problems.

Question asked by Mark Scovel on Jan 2, 2017
Latest reply on Jan 5, 2017 by xiangjun.rong

We are experiencing UART0 FIFO problems. We've found that receiving many 17-byte packets frequently causes a condition where some characters appear to be in the Rx FIFO and it seems that there is no way to get them (reading S1 & D retrieve garbage). We see a similar situation with Tx where bytes become stuck in the FIFO and sending a new byte (writing to base->D) causes an old stuck one to be sent on the wire instead. It would help if we could see a complete working reference implementation of non-blocking Rx/Tx. KSDK examples and those online do not implement full Tx/Rx FIFO sending and receiving where partial packets are contacenated into fully recognizable packets. The KSDK API reference does not explain how all of the calls are supposed to be used to formulate a complete, working implementation. Where can we get that? We are using KSDK 1.3 on an MK22FN512VLL12 (rev 3 so errata does not appear to apply).

Edit: We found multiple problems in our own code (interrupts being disabled too long, stack overflow). Once they were fixed the problems stopped happening. For the record, the KSDK code works as expected. The way to use the FIFO correctly is to:

1. Insert your own Rx ISR callback during init: UART_DRV_InstallRxCallback(DEBUG_IDX, uartDebugCallback_ISR,
rx_buffer, NULL, true);

2. Buffer the received character within the ISR: 

void uartDebugCallback_ISR(uint32_t instance, void *p_void)
{
uint8_t ch;
uart_state_t *p_uart_state = (uart_state_t *)p_void;

if (p_uart_state->rxBuff)
{
ch = p_uart_state->rxBuff[0u];

circularBufferPutByte(&g_cir_rx_buf, ch);

}

}

3. Use KSDK to transmit buffers:

void uartDebugPutString(const char *const p_str)
{
uint32_t bytes_remaining;

do
{
//find out if the last thing we sent is done transmitting
while (kStatus_UART_TxBusy == UART_DRV_GetTransmitStatus(DEBUG_IDX,
&bytes_remaining))
{
}

//and if there are no bytes remaining, just send the new data
if (bytes_remaining == 0U)
{
UART_DRV_SendData(DEBUG_IDX, (const uint8_t *)p_str,
strlen(p_str));//lint !e534 !e668 return doesn't matter
}
}
while (bytes_remaining);

}
 

Outcomes