UART / CAN Transfer examples

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

UART / CAN Transfer examples

2,691 Views
LArmstrong1985
Contributor III

Based on FRDM-K64 example I use UART and CANBUS in Transfer mode. In this examples (respectively frdmk64f_uart_interrupt_transfer and frdmk64f_flexcan_loopback_transfer), however, in callback only a few status 

are managed, tipically TxIdle and RxIdle, while the actual states are many more. Sometimes the callback return other status, like RxOverrun/TxOverrun or Error and it gets stuck in these states.

How should these states be managed and / or how can I prevent these situations?

Are there more in-depth examples for both the UART and the CANBUS?

Thank you in advance!

Labels (1)
Tags (2)
0 Kudos
10 Replies

2,399 Views
LArmstrong1985
Contributor III

Hi Felipe,

I should have solved it! 

It seems that error was due to baudrate that is too high (I had set it to 921600

even if in the UARTInit function documentation it set baudrate to 20000000).

Reducing it I stopped having serial locking problems in the busy state most likely due to errors in communication.

Having said that, what is the maximum baudrate that can be set for the serial port? Does it depend on the source clock?

Thank you very much!

Fabio

0 Kudos

2,399 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Fabio,

 

The max baud rate varies by device, but can be calculated using the following formula.

 

UART Max Baud Rate = (UART Module Clock Frequency) / 16

 

Please take into consideration that UART0 and UART1 modules operate from the core/system clock, which provides higher performance level for these modules. All other UART modules operate from the bus clock.

 

Best regards,

Felipe

0 Kudos

2,399 Views
LArmstrong1985
Contributor III

Hi Felipe,

I noticed now reading the documentation and seeing the examples that function UART_TransferReceiveNonBlocking is used in combination with ring buffer while I have the ring buffer disabled.

This may be the problem, or the function UART_TransferReceiveNonBlocking can we used without ring buffer?

What is the advantage of the ring buffer compared to the internal FIFO?

Can I use them together?

Thank you in advance. 

0 Kudos

2,399 Views
FelipeGarcia
NXP Employee
NXP Employee

Hi Fabio,

 

In case of overrun you should use kUART_RxOverrunFlag when using UART_ClearStatusFlags. Please check the below explanaition from fsl_uart.c driver.

  1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize to uart handle, enable interrupt to store received data to xfer->data. When all data received, trigger callback.
  1. If RX ring buffer is enabled and not empty, get data from ring buffer first.

       If there are enough data in ring buffer, copy them to xfer->data and return.

       If there are not enough data in ring buffer, copy all of them to xfer->data, save the xfer->data remained                   empty space to uart handle, receive data to this empty space and trigger callback when finished.

Hope it helps!

 

Best regards,

Felipe

0 Kudos

2,399 Views
LArmstrong1985
Contributor III

Hi Felipe,

I saw the function UART_ClearStatusFlags.

Reading the comments it expects a bit mask with the following values:

kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag,
kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag,
kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag.

Which flag should i reset? All? 

In the example the callback it's the following:

void UART_UserCallback(UART_Type *base, uart_handle_t *handle, status_t status, void *userData)
{
    userData = userData;
    if (kStatus_UART_TxIdle == status)
    {
        txBufferFull = false;
        txOnGoing    = false;
    }
    if (kStatus_UART_RxIdle == status)
    {
        rxBufferEmpty = false;
        rxOnGoing     = false;
    }
}
Is it okay if I call the UART_ClearStatusFlags function on callback if status==kStatus_UART_RxHardwareOverrun?
What I have to do if status==kStatus_UART_RxBusy? Very often I find that the UART is stuck in this state and I no longer receive anything
(I use the call UART_TransferReceiveNonBlocking).
It says in the comments: kStatus_UART_RxBusy Previous receive request is not finished.
How come UART hangs?
I also wanted to specify that at the moment I am not using the internal FIFO to which you have seen you refer.
I don't know if it could help. How does it work? In transmission wait for the queue to be full to send message or send as soon as it can?
0 Kudos

2,399 Views
LArmstrong1985
Contributor III

Hello Felipe,

yes, I'm referring to UART/FlexCAN callback.

Specifically regarding UART, in the example on callback, only kStatus_UART_TxIdle and kStatus_UART_RxIdle state are managed, but other states? For example if callback return kStatus_UART_RxHardwareOverrun that typically I find,

what I have to do? You showed me the S1 register but is this not managed internally by fs_uart library?

Are there high-level functions to manage these conditions?

For FlexCAN, for example, that has a similar interface before calling FLEXCAN_TransferSendNonBlocking or FLEXCAN_TransferReceiveNonBlocking,

I call respectively FLEXCAN_TransferAbortSend and FLEXCAN_TransferAbortReceive which should cancel any previous sending / receiving in progress,

but I don't think it's the best solution.

Thank you very much

Fabio

0 Kudos

2,399 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello Fabio,

 

According to the reference manual when receive a hardware overrun status, software should do the following.

1. Remove data from the receive data buffer. This could be done by reading data from the data buffer and processing it if the data in the FIFO was still valuable when the overrun event occurred, or using CFIFO[RXFLUSH] to clear the buffer.

 

2. Clear S1[OR]. Note that if data was cleared using CFIFO[RXFLUSH], then clearing S1[OR] will result in SFIFO[RXUF] asserting. This is because the only way to clear S1[OR] requires reading additional information from the FIFO. Care should be taken to disable the SFIFO[RXUF] interrupt prior to clearing the OR flag and then clearing SFIFO[RXUF] after the OR flag has been cleared.

To do this I recommend you to call UART_ClearStatusFlags function that will clear the flags and flush all data in FIFO.

 

I hope this helps.

 

Best regards,

Felipe

0 Kudos

2,399 Views
LArmstrong1985
Contributor III

Hi Mark,

thanks for your interest, but I'm using the official SDK and I need support for that.

0 Kudos

2,399 Views
FelipeGarcia
NXP Employee
NXP Employee

Hello Fabio,

 

Are you referring to the UART callback? An overrun indicates that received data has been lost because there was a lack of room to store it in the data buffer. Therefore, while S1[OR] is set, no further data is stored in the data buffer until S1[OR] is cleared.

 

I recommend you to check chapter 52.8.4 of the reference manual for more in depth information about this issue.

 

Best regards,

Felipe

0 Kudos

2,399 Views
mjbcswitzerland
Specialist V

Hi Fabio

Also take a look at the open source uTasker project which contains proven parallel operation of I2C, UART and FlexCAN:

https://github.com/uTasker/uTasker-Kinetis

https://www.utasker.com/docs/uTasker/uTasker_I2C.pdf
https://www.utasker.com/docs/uTasker/uTaskerUART.PDF
https://www.utasker.com/docs/uTasker/uTaskerCAN.PDF

https://www.youtube.com/watch?v=Ha8cv_XEvco

as well as simulation of the peripherals for simpler debugging and project development.

The supported developer's version give addition features like integrated CANopen for professional needs.

Regards

Mark
[uTasker project developer for Kinetis and i.MX RT]

0 Kudos