LPC55 UART RX FIFO OVERFLOW

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC55 UART RX FIFO OVERFLOW

976 Views
SiuHo1
Contributor I

Hi, I am trying to implement an uart protocol which uses dma transfer. 

My problem is when the transferred character is more than the defined data size, the excessive character arrived later and remains in the rx fifo. I have tried to flush the fifo by using macro "USART_FIFOCFG_EMPTYRX(1);" but this didn't help.

Similar behaviour can be replicated with the SDK example freertos_usart. The defined data size is 4 characters and if I send "12345", the "5" remains in the fifo and the last character of the next incoming character will get truncated.

Can anyone recommend how this can be address? thanks.

#data batch12
Tx123459876 <- missing
Rx12345987

 

I am using LPC55S69 development kit and the SDK version is 2.10.1 and IDE v11.5.0. 

/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
* The USART example for FreeRTOS demonstrates the possibility to use the USART driver in the RTOS.
* The example uses single instance of USART IP and writes string into, then reads back chars.
* After every 4B received, these are sent back on USART.
*/

/* FreeRTOS kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"

/* Freescale includes. */
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"

#include "fsl_usart_freertos.h"
#include "fsl_usart.h"

#include "fsl_power.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_USART USART0
#define DEMO_USART_CLK_SRC kCLOCK_Flexcomm0
#define DEMO_USART_CLK_FREQ CLOCK_GetFlexCommClkFreq(0U)
#define DEMO_USART_IRQHandler FLEXCOMM0_IRQHandler
#define DEMO_USART_IRQn FLEXCOMM0_IRQn
/* Task priorities. */
#define uart_task_PRIORITY (configMAX_PRIORITIES - 1)
#define USART_NVIC_PRIO 5
/*******************************************************************************
* Prototypes
******************************************************************************/
static void uart_task(void *pvParameters);

/*******************************************************************************
* Code
******************************************************************************/
char *to_send = "FreeRTOS USART driver example!\r\n";
char *send_buffer_overrun = "\r\nRing buffer overrun!\r\n";
uint8_t background_buffer[32];
uint8_t recv_buffer[4];

usart_rtos_handle_t handle;
struct _usart_handle t_handle;

struct rtos_usart_config usart_config = {
.baudrate = 115200,
.parity = kUSART_ParityDisabled,
.stopbits = kUSART_OneStopBit,
.buffer = background_buffer,
.buffer_size = sizeof(background_buffer),
};

/*!
* @brief Application entry point.
*/
int main(void)
{
/* Init board hardware. */
/* set BOD VBAT level to 1.65V */
POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
/* attach main clock divide to FLEXCOMM0 (debug console) */
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();

if (xTaskCreate(uart_task, "Uart_task", configMINIMAL_STACK_SIZE + 100, NULL, uart_task_PRIORITY, NULL) != pdPASS)
{
PRINTF("Task creation failed!.\r\n");
while (1)
;
}
vTaskStartScheduler();
for (;;)
;
}

/*!
* @brief Task responsible for loopback.
*/
static void uart_task(void *pvParameters)
{
int error;
size_t n = 0;
usart_config.srcclk = BOARD_DEBUG_UART_CLK_FREQ;
usart_config.base = DEMO_USART;

NVIC_SetPriority(DEMO_USART_IRQn, USART_NVIC_PRIO);

if (kStatus_Success != USART_RTOS_Init(&handle, &t_handle, &usart_config))
{
vTaskSuspend(NULL);
}

/* Send introduction message. */
if (kStatus_Success != USART_RTOS_Send(&handle, (uint8_t *)to_send, strlen(to_send)))
{
vTaskSuspend(NULL);
}

/* Receive user input and send it back to terminal. */
do
{
error = USART_RTOS_Receive(&handle, recv_buffer, sizeof(recv_buffer), &n);

if (error == kStatus_USART_RxRingBufferOverrun)
{
/* Notify about hardware buffer overrun */
if (kStatus_Success !=
USART_RTOS_Send(&handle, (uint8_t *)send_buffer_overrun, strlen(send_buffer_overrun)))
{
vTaskSuspend(NULL);
}
}
if (n > 0)
{
/* send back the received data */
USART_RTOS_Send(&handle, recv_buffer, n);
}
} while (kStatus_Success == error);

USART_RTOS_Deinit(&handle);
vTaskSuspend(NULL);
}

 

0 Kudos
2 Replies

942 Views
SiuHo1
Contributor I

Hi XiangJun,

Thanks for point out the expected behaviour. However, I am trying to implement error handling as my program expects incoming command from serial port and it should raise an error if the entered command has the wrong format (wrong command / length of command character is wrong). 

 

Could you please advise how I can clear the rx fifo before the next command comes in as calling USART_FIFOCFG_EMPTYRX(1); doesn't seem to flush anything? Thanks!

0 Kudos

961 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

For the function calling

USART_RTOS_Receive(&handle, recv_buffer, sizeof(recv_buffer), &n)

The operating system will be blocked at the above function until number of characters predefined by length variables(sizeof(recv_buffer)) has been received.

I think the system behaves normally, if you send 5 characters for once transfer, after 4 characters have been received, USART_RTOS_Receive() will be unblocked. The remaining one character will be treated as next receiving process.

BTW, I suppose that you'd better  not to change the low level driver of SDK or Freertos as you have done to call  the USART_FIFOCFG_EMPTYRX(1);, which will miss the characters.

 

Hope it can help you

BR

XiangJun Rong

 

 

 

/*!
* brief Receives data.
*
* This function receives data from USART. It is a synchronous API. If data is immediately available,
* it is returned immediately and the number of bytes received.
*
* param handle The RTOS USART handle.
* param buffer The pointer to buffer where to write received data.
* param length The number of bytes to receive.
* param received The pointer to a variable of size_t where the number of received data is filled.
*/
int USART_RTOS_Receive(usart_rtos_handle_t *handle, uint8_t *buffer, uint32_t length, size_t *received)
{
EventBits_t ev;
size_t n = 0;
int retval = kStatus_Fail;
size_t local_received = 0;
status_t status;

if (NULL == handle->base)
{
/* Invalid handle. */
return kStatus_Fail;
}
if (0U == length)
{
if (received != NULL)
{
*received = n;
}
return kStatus_Success;
}
if (NULL == buffer)
{
return kStatus_InvalidArgument;
}

/* New transfer can be performed only after current one is finished */
if (pdFALSE == xSemaphoreTake(handle->rxSemaphore, portMAX_DELAY))
{
/* We could not take the semaphore, exit with 0 data received */
return kStatus_Fail;
}

handle->rxTransfer.data = buffer;
handle->rxTransfer.dataSize = (uint32_t)length;

/* Non-blocking call */
status = USART_TransferReceiveNonBlocking(handle->base, handle->t_state, &handle->rxTransfer, &n);
if (status != kStatus_Success)
{
(void)xSemaphoreGive(handle->rxSemaphore);
return kStatus_Fail;
}

ev = xEventGroupWaitBits(handle->rxEvent, RTOS_USART_COMPLETE | RTOS_USART_RING_BUFFER_OVERRUN, pdTRUE, pdFALSE,
portMAX_DELAY);
if ((ev & RTOS_USART_RING_BUFFER_OVERRUN) != 0U)
{
/* Stop data transfer to application buffer, ring buffer is still active */
USART_TransferAbortReceive(handle->base, handle->t_state);
/* Prevent false indication of successful transfer in next call of USART_RTOS_Receive.
RTOS_USART_COMPLETE flag could be set meanwhile overrun is handled */
(void)xEventGroupClearBits(handle->rxEvent, RTOS_USART_COMPLETE);
retval = kStatus_USART_RxRingBufferOverrun;
local_received = 0;
}
else if ((ev & RTOS_USART_COMPLETE) != 0U)
{
retval = kStatus_Success;
local_received = length;
}
else
{
retval = kStatus_USART_RxError;
local_received = 0;
}

/* Prevent repetitive NULL check */
if (received != NULL)
{
*received = local_received;
}

/* Enable next transfer. Current one is finished */
if (pdFALSE == xSemaphoreGive(handle->rxSemaphore))
{
/* We could not post the semaphore, exit with error */
retval = kStatus_Fail;
}
return retval;
}

Tags (1)
0 Kudos