Serial port at high speed using UART_DRV

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

Serial port at high speed using UART_DRV

Jump to solution
1,826 Views
hectorgastaminz
Contributor II

Hello everyone. I'm using a FRDM-K64F. I would like to use a UART in a high speed mode. I need to transmit/receive data faster than 115200. I tried up to 115200 without problems but faster than that I couldn't do it. I lost characters, I received wrong characters and so on. I need to make a project using RTCS, USB and Serial ports. My code is based on the Ethernet to Serial port example. but it is using a serial port with the "old" nio driver. I migrated the example to the new "UART_DRV" and it is working worse than before. I made a protocol which use different layers, but I can't do the next step if the serial port layer don't work. I configured the serial port using PE and then I send this configuration to my layer through a specific struct for this.

 

This two tasks which have the same priority are working all the time. This code works until I change the baud-rate from 115200 to 256000, and I want it to run faster than that.

 

<p>

 

void LayerUSART_rx_task (os_task_param_t task_init_data)
{
    SLayerUsartConfigPtr config;
    uart_status_t state;
    uint8_t * buffer;

 

    /* Waiting until the initialization process is finished */
    while(!_LwSemInit.VALID)
    {
        OSA_TimeDelay(UART_RX_BUFFER_TIMEOUT * 5);
    }
    OSA_SemaWait(&_LwSemInit, OSA_WAIT_FOREVER);
    OSA_SemaDestroy(&_LwSemInit);

 

    _Rx_Buffers_last = _Rx_Buffers_index = 0;

 

    /* Endless loop for reading from serial  */
    while(1)
    {
        config = (SLayerUsartConfigPtr)_LayerUsart.configLayerStruct;
        buffer = &(_Rx_Buffers[_Rx_Buffers_index][0]);
        // Wait to receive input data
#ifdef USART_DMA
        state = UART_DRV_EdmaReceiveDataBlocking(config->instance, buffer, UART_RX_BUFFER_SIZE, UART_RX_BUFFER_TIMEOUT);
#else
        state = UART_DRV_ReceiveDataBlocking(config->instance, buffer, UART_RX_BUFFER_SIZE, UART_RX_BUFFER_TIMEOUT);
#endif
        if (kStatus_UART_Success == state)
        {
            _Rx_Received = UART_RX_BUFFER_SIZE;
        }
        else
        {
            if(kStatus_UART_Timeout == state)
            {
                uint32_t bytesRemaining;
#ifdef USART_DMA
                UART_DRV_EdmaGetReceiveStatus(config->instance, &bytesRemaining);
#else
                UART_DRV_GetReceiveStatus(config->instance, &bytesRemaining);
#endif
                _Rx_Received =  UART_RX_BUFFER_SIZE - bytesRemaining;
            }
            else
            {
                /* Error handling */
            }
        }

 

        if((_Rx_Received) && (_Rx_Received <= UART_RX_BUFFER_SIZE))
        {
            _Rx_Buffers_last = _Rx_Buffers_index;
            _Rx_Buffers_index = ((_Rx_Buffers_index + 1) % UART_RX_BUFFER_DEEP);
            OSA_SemaPost(&_LwSemReceived);
        }
    }
}

 


void LayerUSART_rx_completed_task (os_task_param_t task_init_data)
{
    uint8_t * buffer;

 

    /* Waiting until the initialization process is finished */
    while(!_LwSemReceived.VALID)
    {
        OSA_TimeDelay(UART_RX_BUFFER_TIMEOUT * 5);
    }

 

    /* Endless loop for processing data read from serial  */
    while(1)
    {
        OSA_SemaWait(&_LwSemReceived, OSA_WAIT_FOREVER);

 

        buffer = &(_Rx_Buffers[_Rx_Buffers_last][0]);

 

#ifdef LAYER_USART_ECHO
        LayerUSART_Send(buffer, _Rx_Received);
#else
        LayerUSART_Receive(buffer, _Rx_Received);
#endif
    }
}

 

 

uint8_t LayerUSART_Send(uint8_t * data, uint16_t length)
{
    uint8_t retval = 1;

 

    if((data != NULL) && (length > 0))
    {
        if(LayerUSART_ReadyToSend())
        {
            uart_status_t state;
            SLayerUsartConfigPtr config = (SLayerUsartConfigPtr)_LayerUsart.configLayerStruct;

 

#ifdef USART_DMA
            state = UART_DRV_EdmaSendData(config->instance, data, length);
#else
            state = UART_DRV_SendData(config->instance, data, length);
#endif

 

            if(kStatus_UART_Success == state)
            {
                retval = 0;
            }
        }
    }

 

    return (retval);
}

 

</p>

 

This is an example when I try to make an echo at 256000 bps in a terminal.

 

[TX] - <ECHO_*_TEST>
[RX] - <ECHO_*_TEST>
[TX] - <ECHO_*_TEST>
[RX] - ¼Q(êê¥úQ MQò
[TX] - <ECHO_*_TEST>
[RX] - <ECHO_*_TEST¾

 

I hope you can help me. Thanks.

Labels (1)
0 Kudos
1 Solution
1,322 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Hector,

Regarding your issue that you can not communicate successfully with above 115200 baudrate, I think the uart driving clock dismatch with PC leads to the issue. For example, if you communicate between two SCI on the same chip, you can use high baudrate.

I suppose that you communicate between PC and FRDM-K64F, and the PC has precious baudrate. I suggest you use external clock source or crystal and use PLL to get the core/system clock. For the detailed inf about the dismatch of SCI baudrate clock, I suggest you refer to section 52.4.2.9 Baud rate tolerance in the reference manual of K64.

Hope it can help you.

BR

Xiangjun Rong

View solution in original post

2 Replies
1,322 Views
hectorgastaminz
Contributor II

Hi Xiangjun,

Thank you for your help,

I have adjusted the system clock using this information frdm-k64f-at-maximum-speed-of-120-mhz. I've supposed that my PC hasn't a precious baud-rate, so I calculated different baud-rates and its errors; then I tried with many of them. Now its working at 500000bps and 1000000bps without problems.

BR

0 Kudos
1,323 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Hector,

Regarding your issue that you can not communicate successfully with above 115200 baudrate, I think the uart driving clock dismatch with PC leads to the issue. For example, if you communicate between two SCI on the same chip, you can use high baudrate.

I suppose that you communicate between PC and FRDM-K64F, and the PC has precious baudrate. I suggest you use external clock source or crystal and use PLL to get the core/system clock. For the detailed inf about the dismatch of SCI baudrate clock, I suggest you refer to section 52.4.2.9 Baud rate tolerance in the reference manual of K64.

Hope it can help you.

BR

Xiangjun Rong