STM32F4 Handling peripheral error while making a DMA Transfer (RX)

3.9k views Asked by At

I am trying to communicate with the UART peripheral using DMA for both RX and TX. I am using the HAL library that is supplied by ST (Generated with STCubeMX).

I am handling a UART channel with 1.5MBaud - so in order to not loose any data, I've configured the DMA in direct mode, with circular buffer, and handled the half-transfers interrupts to take care of the data, and keep the DMA online for more data to come.

The problem is that sometimes I can see in the Status Register of the UART that the Frame Error bit is on, and sometimes the Overrun Error flag is also on.

I can handle to lost bytes (using crc on the structured packets), but the problem is that the peripheral stops receiving data - but the DMA does not raise error, or stop the transfer.

So if I try to receive data, and the flag is on the system hangs.

I saw that the HAL provides a __weak function that should handle UART_Error, but it is never called - and the status in the HAL handle remains normal. only a look at the register can tell that there is a problem.

How should I detect/handle these kind of errors?

Thanks

1

There are 1 answers

0
too honest for this site On BEST ANSWER

I do not use the HAL for performance reasons, as it is very clumsy and - imo also does not provide much abstraction to justify that. Handling the hardware directly is not much more complicated; even more as you still have to understand very well what goes on. And as you already detected, the HAL does only support a certain approach; once you follow your own trail, you are lost.

You apparently have similar issues as the overflow-flag is set. After such an error, you have to re-sync the receiver with the transmitter bytestream after an error in general. That would require out-of-band signalling using a symbol or line-condition not occuring within a packet. Framing errors are a good indicator there are problems to sync to the start of a symbol (start-bit) properly.

If the line is clean (not EMC problems), there should be no framing errors or data corruption (unless timing parameters do not match).

If using a simple ping-pong, a timeout might be sufficient. However, tha proper solution depends on the protocol. A good protocol design takes transmission errors and overflows into account.

Note that you have to enable receive-error interrupts in addition to DMA transfers to be informed. However, if you use a timeout (and a ping-pong protocol), you just can erase the flags, as the data did apparently not arrive in-time. If actually using error-interrupts be aware of race-conditions, too.