Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

XMC™ Forum Discussions

User10696
Level 4
First solution authored
Level 4
I have an application where an external device more or less continously sends messges of different lengths via UART.
My XMC4500 DAVE application needs to startup and receive these messages, but this does not work correctly.

As the length of the message is unknown, I am using UART_Receive() with a length of one in interrupt mode, with FIFO. I expect to get an interrupt after each byte is received, but more often than not it does not start receiving.

I have analysed the problem and it seems the DAVE App initializes the Receive in the wrong order. On calling the UART_Receive() the following steps are done:
1. The FIFO is flushed
2. The limit is set to 0
3. The events are enabled to generate the interrupt

This sequence looks OK, but the problem is that the USIC FIFO has the problem that an event is only generated when the limit is reached (not when the limit is exceeded). So in my case the follwoing happens:
1. The FIFO is flushed
2. While the limit is being set to 0 the next byte is received, so the FIFO now has one entry
3. The events are enabled, but as the filling level has already changed from zero to one, this event is never generated.

The underlying problem is with the USIC FIFO, events should be generated whenever the limit is exceeded, Infineon should change the silicon.
0 Likes
1 Solution
LinglingG_46
Moderator
Moderator 250 sign-ins 750 replies posted First comment on KBA
Moderator
Hi Amanning,

What you said "
The flush at the beginning of the receive function is a really bad idea! I am regulary missing characters as they get flushed.
This implementation of the UART receive does not work with partners that are continuously sending messages of different lengths.
Once a message has been received the receiving task needs to react to this message before waiting for the next message.
If this reaction time is too long, there may be the start of the next message in the FIFO, which then gets flushed and is lost."

I agree with your opinion, so I think if you have such a requirement, it is recommend that you don't use such control mode.
In addition, Asynchronous communication does have the risk of missing data, I think the code the APP code example shown, have a obvious design defects.

Here, we need to flush the FIFO buffer, because before changing the trigger limit, it is necessary to clear the FIFO.

Anymore, as my understanding, the USIC FIFO interrupt was activated when above the limit, not only when reaching the limit.

View solution in original post

0 Likes
12 Replies
LinglingG_46
Moderator
Moderator 250 sign-ins 750 replies posted First comment on KBA
Moderator
Could you give us your test project, maybe it is convenient for us to debug the issue using your project?
0 Likes
User10696
Level 4
First solution authored
Level 4
I do not think it is necessay to send the project.
Just set up the DAVE UART app to use interrupts and FIFO.
Then have an external device continuously send messages at a high baud rate (115200).
Start the extern device, then start the XMC4500 and you will see that the receive interrupt does not always come as the FIFO can already have received a character between flushing and enabling the interrupt.
0 Likes
LinglingG_46
Moderator
Moderator 250 sign-ins 750 replies posted First comment on KBA
Moderator
1:I don't think setting to 0 is the right way.
2: You can change the trigger limit using the following API:
void XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(XMC_USIC_CH_t *const channel,
const XMC_USIC_CH_FIFO_SIZE_t size,
const uint32_t limit)
3: When you the interrupt occur, then you should make sure that all the data in the FIFO has been read out.
4: Please refer to the code to handle the rx intterrupt:
/* Read the RX FIFO till it is empty */
while(!XMC_USIC_CH_RXFIFO_IsEmpty(XMC_UART1_CH0))
{
rx_data[rx_index++] = XMC_UART_CH_GetReceivedData(XMC_UART1_CH0);
}

/* If all the data have been received */
if(rx_index == (NUM_DATA))
{
/* Check if every received data match with the transmitted data */
for (int tmp=0; tmp {
/* If reception fails stays in an infinite while loop and switch off the LED */
if (tx_data[tmp]!=rx_data[tmp])
{
while(1)
{
XMC_GPIO_SetOutputLow(LED1);
}
}
else
{
/* If reception is successful switch on the LED */
XMC_GPIO_SetOutputHigh(LED1);
}
}
}

/* If the remaining data to be received is smaller than the initial RX FTFO Limit
* it is modified to the remaining data minus 1 in order react when we have all the data received*/
if((NUM_DATA-rx_index) < RX_FIFO_INITIAL_LIMIT)
{
XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(XMC_UART1_CH0, XMC_USIC_CH_FIFO_SIZE_8WORDS, (NUM_DATA-rx_index)-1);
}
}

5: The Infineon offer the rich material about the code example, please refer to the below linker:
https://www.infineon.com/cms/en/product/microcontroller/32-bit-industrial-microcontroller-based-on-a...
6: Hope my response can help you.

Thanks,
Lingling
0 Likes
User10696
Level 4
First solution authored
Level 4
I think things are getting a little confused here!
I know the correct way to use the USIC using the XMClib API. Here the problem is with the DAVE 4 UART App.

If I only want to read one byte using the DAVE UART App I use:
UART_Receive(&UART_HOST, &receiveBuffer[receiveIndex], 1);

The code of this App then sets the limit to 0, which is correct. It is also the job of the Apps interrupt routine is read all the data from the FIFO.

All I am saying is that the App code can cause problems, but it would make everyones life easier if the USIC FIFO interrupt was activated when above the limit, not only when reaching the limit.
0 Likes
LinglingG_46
Moderator
Moderator 250 sign-ins 750 replies posted First comment on KBA
Moderator
1: When you disable the FIFO, this is not suitable for you to deal with the long byte packet that you described to receive at a high speed.
2: If you don't disable the FIFO, then the code don't enter in the following branch:

if (handle->config->rx_fifo_size != XMC_USIC_CH_FIFO_DISABLED)
{
/*Clear the receive FIFO, configure the trigger lime
* and enable the receive events*/
XMC_USIC_CH_RXFIFO_Flush(handle->channel);

/*Configure the FIFO trigger limit based on the required data size*/
UART_lReconfigureRxFIFO(handle, count);

XMC_USIC_CH_RXFIFO_EnableEvent(handle->channel,
(uint32_t)((uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD |
(uint32_t)XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATE));
}
0 Likes
User10696
Level 4
First solution authored
Level 4
I do not understand what you are trying to say!

If the FIFO is enabled it will enter the code sequence you have shown. Your point 2 is incorrect.
This bit of code is exactly where the problem is!
The UART_IReconfigureRxFIFO() function takes a certain amount of time and during this time the next byte can have been received, so the FIFO is already at level one when the interrupt is enabled in the next line. So the interrupt is never called as the change from zero to one has been missed.
0 Likes
User11773
Level 4
First like received First solution authored
Level 4
Any update?

I see the problem.
Also I have another problem, but I'll put in another thread.
0 Likes
User10696
Level 4
First solution authored
Level 4
The flush at the beginning of the receive function is a really bad idea! I am regulary missing characters as they get flushed.

This implementation of the UART receive does not work with partners that are continuously sending messages of different lengths. Once a message has been received the receiving task needs to react to this message before waiting for the next message. If this reaction time is too long, there may be the start of the next message in the FIFO, which then gets flushed and is lost.
0 Likes
User11773
Level 4
First like received First solution authored
Level 4
I agree the UART implemenation is bad. The "A" in UART is for Asynchronous.
But have a look at my other post about UART Problem.

If you can, use 2 UARTS, one for TX only & the other for RX only.
0 Likes
User11773
Level 4
First like received First solution authored
Level 4
I agree the UART implemenation is bad. The "A" in UART is for Asynchronous.
But have a look at my other post about UART Problem.

If you can, use 2 UARTS, one for TX only & the other for RX only.
0 Likes
LinglingG_46
Moderator
Moderator 250 sign-ins 750 replies posted First comment on KBA
Moderator
Hi Amanning,

What you said "
The flush at the beginning of the receive function is a really bad idea! I am regulary missing characters as they get flushed.
This implementation of the UART receive does not work with partners that are continuously sending messages of different lengths.
Once a message has been received the receiving task needs to react to this message before waiting for the next message.
If this reaction time is too long, there may be the start of the next message in the FIFO, which then gets flushed and is lost."

I agree with your opinion, so I think if you have such a requirement, it is recommend that you don't use such control mode.
In addition, Asynchronous communication does have the risk of missing data, I think the code the APP code example shown, have a obvious design defects.

Here, we need to flush the FIFO buffer, because before changing the trigger limit, it is necessary to clear the FIFO.

Anymore, as my understanding, the USIC FIFO interrupt was activated when above the limit, not only when reaching the limit.
0 Likes
User10696
Level 4
First solution authored
Level 4
Hi GLLing

No, the interrupt is only generated when the limit is reached. This has caused me problems with other USIC configurations (e.g. I2C).
0 Likes