STMicroelectronics / stm32l4xx-hal-driver

Provides the STM32Cube MCU Component "hal_driver" of the STM32L4 series.
BSD 3-Clause "New" or "Revised" License
37 stars 15 forks source link

HAL_UARTEx_ReceiveToIdle_DMA has inconsistent behavior #6

Closed gittymonkey closed 1 year ago

gittymonkey commented 2 years ago

When using ReceiveToIdle, there seems to be a different behavior for when IDLE and FT happen at the same time. With the HT, we get both interrupts(HT and IDLE), but when FT and IDLE happen to be at sizeof(buf), the code decides the buffer is full and cancels the idle interrupt.

This seems strange when using the DMA in circular buffer mode, there should be no concept of a location being more significant compared to another. I would expect to get both interrupts.

In the case when the incoming data wraps the buffer, we get the FT and IDLE. So now there is no way to just detect IDLE interrupts. If it was consistent and we always received the IDLE interrupt, that would make it easier to discard the HT and FT.

Maybe it could check if the DMA is using CIRCULAR mode and send both interrupts.

To explain our use case, we are receiving packets of variable size. Therefore, the size of the data cannot be used to determine when all the data is received. I am aware there are lots of ways of framing the data to detect the packets, but just being consistent with the IDLE interrupts would make it much easier.

I have read this issue https://github.com/STMicroelectronics/stm32f1xx_hal_driver/issues/4 and read the example code, but it does not solve my issue.

The issue also states:

Use of HAL_UARTEx_ReceiveToIdle_DMA service, will generate calls to user defined HAL_UARTEx_RxEventCallback callback for each occurrence of following events :

  • DMA RX Half Transfer event (HT)
  • DMA RX Transfer Complete event (TC)
  • IDLE event on UART Rx line (indicating a pause is UART reception flow)

According to this text, we should get an interrupt for EACH occurrence, but it appears we don't always get the IDLE events.

NeoZng commented 2 years ago

jesus i got the same problem and it cost totally two days for me to figure it out. i debugged step by step and found that it seems that there is no solution to tell which event has happened under this set of design... i have to modify the source code but once i click "generate code" in CubeMX they just gone ! so now i am using a make-shift : read the register of IDLE FLAG, which is not HAL-styled at all! it's far less elegant ...

ASELSTM commented 1 year ago

Hi @gittymonkey, @NeoZng,

Thank you for this report. We have implemented a new function HAL_UARTEx_GetRxEventType in the frame of this commit that provides the Rx Event type (Half transfer event, Transfer complete event or IDL event) which has lead to RxEvent callback execution.

As when HAL_UARTEx_ReceiveToIdle_IT() or HAL_UARTEx_ReceiveToIdle_DMA() API are called, the progress of reception process is provided to application through the calls of Rx Event callback and given that several types of events could occur, this function will allow thus to get the source of the Rx Event type that drove the call of the Rx Event callback.

With regards,

ASELSTM commented 1 year ago

Hi @gittymonkey,

Please allow me to close this thread as no activity. You may reopen it at anytime if you have any details to share with us in order to help you to solve the issue. Thank you for your comprehension.

With regards,