2024-11-04 12:32 AM
Hi, i want use usart DMA to receive data, but i only get last data by HAL_UART_Receive_DMA.
STM32U575VITX
STM32CUBEMX 6.8.0
STM32CubeIDE 1.12.0
the transmit data is $$......##
my code is in main function
when i use HAL_UART_Receive(), i can get correct data, but it has packet loss to some extend.
when i use HAL_UART_Receive_DMA(), i only get last byte # .
cubemx setting for DMA:
cubemx setting for usart :
usart.c file is attached below.
i try this solution https://community.st.com/t5/stm32-mcus-embedded-software/stm32h750-dma-hal-uart-receive-dma-acting-oddly/m-p/569897 but, still can't solve it.
it will be very helpful, if any one tell me something.
thank you.
Solved! Go to Solution.
2024-11-05 11:30 AM
Hi. Problem with DMA configuration. You must set Enabled for Destination Address Increment After Transfer.
2024-11-04 02:45 AM
The function returns immediately, you can't have multiple operations in flight concurrently. Manage fill of buffer in the completion callback.
Avoid using auto/local buffers for DMA, they have collapsing scope on the stack.
2024-11-05 02:14 AM
Hi, let me make the situation more clear.
i can run into IQRHander.
i use the callback function, length=__HAL_DMA_GET_COUNTER can change. (i think MCU have known the interrupt received by usart, but dont know where to read the buffer data)
observation:
1. hdmarx state is HAL_DMA_STATE_BUSY, HAL_UART_Receive_DMA state is HAL_OK
2. pRxBuffPtr is #000....... (only first byte have data, other bytes are all 0)
3. hdmarx->init are all 0, if i set HAL_DMA_Init() in usart.c, it will into HardFault_Handler()
4. i change baud rate from 921600 to 115200, but still not work
i attach the .ioc and main.c file below.
thank you
2024-11-05 11:30 AM
Hi. Problem with DMA configuration. You must set Enabled for Destination Address Increment After Transfer.
2024-11-05 01:49 PM - edited 2024-11-05 01:50 PM
It's not a clarity issue, its a one that lacks understanding of the mechanics
I've told you HAL_UART_Receive_DMA(&hlpuart1,data,256); returns immediately, not after you have 256 bytes, immediately.
You need some volatile semaphone coming back from the callback indicating it completed and is read for a second usage.
volatile int global_flag = 0;
...
while(1)
{
if (global_flag == 0) // nothing pending
{
global_flag = 1; // busy
HAL_UART_Receive_DMA(&hlpuart1,data,256);
}
}
In full completion callback
global_flag = 0;
2024-11-05 06:42 PM
Yes! thank you ,you are right!
After I set this, everything go done well.
2024-11-05 06:58 PM
I try this but fail. Still thanks for your helping.
My solution is given.