UART receive with DMA lost sometimes bytes

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

cross mob
user_2747286
Level 3
Level 3
First like received

Hello,

I'd like to use the UART+DMA to talk to a coriolis sensor via modbus.

pastedImage_15.pngpastedImage_18.pngpastedImage_19.pngpastedImage_17.png

All things are work okay, but sometimes after 1-3 minutes I lost one byte of the answer.

Every 100ms a measurement value is querried from the sensor. The answer of the senser should be 37 bytes long.
With the help of an RS485-USB adapter I control the response of the sensor. There you can always see all 37 characters. In the input buffer (MB_inbuffer), which is filled by UART via DMA, there are sometimes only 36 characters!
Additionally the data stream was analyzed by an oscilloscope and no (big) deviations were detected. The sensor transmits with 38661 baud (according osci) and the measured (checked on HSO_0 pin) clk frequency of the UART divded by 8 result in 38460baud. So there is a 0.5% deviation between this two frequencys, which should be okay.
Therefore I cannot explain the missing byte.

Mostly a 00 byte is missing if several are sent in series. (but not always)

USB-Adapter:

01 03 20 47 7D 3C 8A 00 00 00 00 74 BF 41 C8 00 00 00 00 00 00 7F A0 00 00 7F A0 00 00 00 00 00 00 00 00 9A 6B

PSOC-Inputbuffer variable:

01 03 20 47 7D 3C 8A 00 00 00 00 74 BF 41 C8 00 00 00 00 00 00 7F A0 00 00 7F A0 00 00 00 00 00 00 00 9A 6B

In this case on the oscilloskop there is no deviation in the byte length of this 8 '00'-bytes. All 8 bytes are identical. So I have no clue why in the input buffer one is missing...

the dma is initialized with the following code:

pastedImage_11.png

For each query following code is used:

char send_modbus(T_MODBUS *p)

{

    RS485_OUT;     //macro to set sending pin on RS485 transceiver

    CyDmaChDisable(dma_Coriolis_RX_ChannelHandle);

    CyDmaClearPendingDrq(dma_Coriolis_RX_ChannelHandle);

    CyDmaTdSetConfiguration(dma_Coriolis_RX_ChannelHandle_TD, p->count_rec, CY_DMA_DISABLE_TD, dma_Coriolis_RX__TD_TERMOUT_EN | TD_INC_DST_ADR );

    CyDmaChEnable(dma_Coriolis_RX_ChannelHandle, 1u);

    CyDmaChDisable(dma_Coriolis_TX_ChannelHandle);

    CyDmaTdSetConfiguration(dma_Coriolis_TX_ChannelHandle_TD, p->count_send, CY_DMA_DISABLE_TD, dma_Coriolis_TX__TD_TERMOUT_EN | TD_INC_SRC_ADR );

    CyDmaTdSetAddress(dma_Coriolis_TX_ChannelHandle_TD, LO16((uint32_t)&(*p->message)), LO16((uint32)UART_Coriolis_TXDATA_PTR));

    CyDmaChEnable(dma_Coriolis_TX_ChannelHandle, 1u);

}

*p is a pointer to the send/receive structure.

p-> count_rec is 37 for a normal measurement query.

Is there something wrong with the DMA configuration?

Thx,

Stefan

0 Likes
1 Solution

Hi,

I have started another topic, because the problem was not DMA related:

UART lost byte, depended on connection (of not really involved) pin in HW

There I discovered that I have an issue with synchronisation of rx pin.

Unfortunatly this topic was closed, because the answer was marked as correct, so I'd like to give here a short addition.

The real cause is that in my PSoC Creator ( 4.1 Update 1 / 4.1.0.3210) when I insert a pin into the top sheet the sync mode of the pin is set to transparent! And not default to double-sync as the documentation says.

So I get metastabilty an the rx start was missed...

On all UART example the sync mode is set to double-sync, and with this setting all things are fine...

View solution in original post

0 Likes
5 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Stefan,

It is rather strange sensor baud rate you have (38661 bd), shouldn't it be some standard value of 38400?

Why do you use DMA for rather slow communication with sensor, are there other time-consuming tasks running in the background?

The issue is likely in the clock settings. From images provided, it seems that the MASTER_CLK = 20MHz (38.4615375 kHz * 8 * 65 = 20MHz). How do you know that the MASTER_CLK is indeed equals the requested 20MHz? Check it with the scope.

Try other combinations, e.g.

MASTER_CLK=24MHz, UART_coriolis_clk divider = 78 (UART = 38.461 kBd)

/odissey1

0 Likes

Nominally the sensor has 38400 baud, but I measured the 38661baud (on oscilloscop). For the PSOC I measured the uart clk (at pin HSO_0) and this shows 307.840kHz (/8 = 38480baud).. So the deviation between this two uart is ca. 0.5% which is totaly fine. So no byte should be dismissed.

The DMA is used, because of other time consuming tasks.

But for testing I now disabled the DMA and have done with ISR. I also get missing bytes. It looks like that the UART is missing one byte, which looks on oscilloscope totaly fine.

pastedImage_1.png

Here is a typical issue: blue: RX-Line / red: RX-interrupt line

At the cursor line 5.48ms there is the RX-Interrupt missing and so this byte get lost. But this is a valid byte, the Time between Cursor (10 bits) is 258.2µs (=>38700 baud)

Also the bytes before have the same length....

pastedImage_0.png

The whole thing becomes very mysterious, if I change some small things in top sheet (like the HSO_0 pin on the uart clk or ISR), it (apparently) runs stable.

I checked now for several hours. The version with debug pin connected runs stable, the version without debug pin lost after some minutes a byte...

So for me looks like there is a dependence how the top sheet is "compiled". But how could I be sure that everthing works (on timing report I got no timing violation on both designs)

0 Likes

Hi,

I have started another topic, because the problem was not DMA related:

UART lost byte, depended on connection (of not really involved) pin in HW

There I discovered that I have an issue with synchronisation of rx pin.

Unfortunatly this topic was closed, because the answer was marked as correct, so I'd like to give here a short addition.

The real cause is that in my PSoC Creator ( 4.1 Update 1 / 4.1.0.3210) when I insert a pin into the top sheet the sync mode of the pin is set to transparent! And not default to double-sync as the documentation says.

So I get metastabilty an the rx start was missed...

On all UART example the sync mode is set to double-sync, and with this setting all things are fine...

0 Likes
Hari
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hi user_2747286

UART lost byte, depended on connection (of not really involved) pin in HW thread is not yet locked. Please feel free to share the response  in that thread. This would really help others who are trying to find a solution to a similar problem.

Best regards

Harigovind

0 Likes

Hi Harigovind,

thanks for your hint, I had an issue with login, that makes me feel I couldn't answer to a thread which is marked with a correct answer...

0 Likes