UART Recieve Missing characters

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

UART Recieve Missing characters

1,755 Views
beng_
Contributor III

I'm using the Kinetis SDK and FreeRTOS.

I'm using the UART to output and input debug data within in a task. E.g I will send message like;

•Sensor Task Started

•Measurment Read

etc....

And I expect the console task to handle incoming string such as:

•"RESET/r" reset

•"CAL/r" send a mesasge to sensor task to re-cal sensor

etc...

Transmitting data is fine, recieving is not. Basically the UART recieve functions are regularly missing characters.

The incoming strings can be any length (within reason) and can be recieved at any time (again within reason). Most of the SDK functions rely on awaiting a specific number of characters and the RTOS recieve function is blocking, which is as useful as a choclacte teapot.

I've tried using both a ring buffer method and just using an interrupt driven method (the ring buffer method is below). Recieving of characters is sketchy at best.

Is there a better way of recieving characters using the SDK or is it best to write my own custom code (to peform the same/similar function as the Ring Buffer example below)

Ring Buffer Method

void console_init(void)
{
  port_pin_config_t config;
  uint32_t uart_clock_freq;

  CLOCK_EnableClock(kCLOCK_Uart2);
  uart_clock_freq = CLOCK_GetFreq(kCLOCK_BusClk);

  UART_GetDefaultConfig(&uart_config);  // Not really needed as we set all the parameters below.
  uart_config.baudRate_Bps = 57600U;  // We limited to what baud-rates we can set.
  uart_config.parityMode = kUART_ParityDisabled;
  uart_config.enableTx = true;
  uart_config.enableRx = true;
  UART_Init(UART2, &uart_config, uart_clock_freq);

  UART_TransferCreateHandle(UART2, &uart_handle, UART_Callback_FN, NULL);

  // Other Init stuff here
}

static void console_task_func(void *p_data)
{
  uint32_t queue_timeout;
  uint8_t local_cns_buffer[RECEIVE_BUFF_SIZE] = {0};
  uint8_t local_cns_index = 0;
  uint8_t *buff_ptr;
  size_t count;
  bool success;

  buff_ptr = (uint8_t *)receive_buffer;  // Casting here to prevent a warning about discarding volatile qualifier.
  receive_transfer.data = buff_ptr;
  receive_transfer.dataSize = 1;

  UART_TransferStartRingBuffer(UART2, &uart_handle, ringBuffer, RING_BUFFER_SIZE);

  while (1)
  {
    console_msg_t msg;

    if ( UART_TransferReceiveNonBlocking(UART2, &uart_handle, &receive_transfer, &count) == kStatus_Success )
    {
      if (count >= 1)
      {
        data_recieved = true;
        
        //....... Then do something with the data recievd........
      }
    }
    
    queue_timeout = 5;
 
    success = xQueueReceive(console_msg_queue, &msg, queue_timeout);

    if (!success)
    {
      /* Entirely possible to timeout here. In this event re-queue */
      continue;
    }

    switch (msg.opcode)
    {
    // Handling orf incoming messages here (Not related to UART)

    default:
      configASSERT_wConsole(false);
      break;
    }
  }
}

Labels (1)
0 Kudos
3 Replies

1,345 Views
beng_
Contributor III

Looking at this a little further - this may not be an SDK issue. Even the following simple Ring Buffer is missing characters.

#define RING_BUFFER_SIZE  20
uint8_t ring_buffer[RING_BUFFER_SIZE];
uint8_t head = 0;
uint8_t tail = 0;

void UART2_RX_TX_DriverIRQHandler(void)
{
  if (UART_S1_RDRF_MASK & (UART2->S1) )
  {
    uint8_t chr = UART2->D;

    ring_buffer[head++] = chr;
    UART2->D = chr; // Echo Character Back
    if (head >= RING_BUFFER_SIZE)
    {
      head = 0;
    }
    if (head == tail)
    {
      tail++;
      if (tail >= RING_BUFFER_SIZE)
      {
        tail = 0;
      }
    }
  }
}

0 Kudos

1,345 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi,

https://community.nxp.com/message/1011451?commentID=1011451#comment-1011451

Please look at this question. I guess you problems are the same.

Regards,

Jing

1,345 Views
beng_
Contributor III

Thanks

0 Kudos