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.
解決済! 解決策の投稿を見る。
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
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
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