2026-01-22 1:58 AM
Hello, I have a query about how HAL_UART_Receive_DMA and HAL_UARTEx_ReceiveToIdle_DMA work?
For my application there is a varying payload size, so I am wondering how would I trigger the HAL_UART_Receive_DMA(&huart3, rx_buffer, 4096, 0xFFFF); interupt? As from my understanding it would be waiting for all 4096 bytes of data which won't arrive unless a different frame was sent.
Whereas HAL_UARTEx_ReceiveToIdle_DMA(&huart3, rx_buffer, 4096); triggers once the serial port stops communicating, however it stores the received data in 512 byte chunks, which has proven difficult to access when generating a LUT from the rx_buffer.
If anyone can shed some insight over how these interrupts work? And how to make them applicable for a variable payload would be great.
Solved! Go to Solution.
2026-02-19 5:50 AM
The issue was caused by the DMA being configured to normal mode, and my hardware had a 512 byte cache that was filling up before triggering the interrupt or populating the buffer.
This was fixed by switching to circular mode.
2026-01-22 6:35 AM
HAL_UARTEx_ReceiveToIdle_DMA should be used if you want notified when the stream becomes idle. Data is processed within the HAL_UARTEx_RxEventCallback callback which gets called in three cases:
2026-01-22 7:46 AM
Thank you. Do you know how the data is stored for both of these cases if using a DMA?
2026-01-22 7:47 AM
Data is stored in the buffer you point to. DMA transfers data from the peripheral to memory.
2026-01-22 9:20 AM - last edited on 2026-01-22 9:51 AM by Andrew Neil
Thank you, from my understanding receive_to_idle stores the data in 512 byte segments, however when trying to write from this memory I have been struggling to access any data beyond this, even if I edit the address in the linker code, and check my buffer is fully populated.
the writing to a look up table is conducted as below:
for (uint16_t k = 0, i = 5; i < length + 5; ++k, i += 2){
lut[k] = (rx_buffer[i+1] | rx_buffer[i] << 8);
if (lut[k] >= 4095) {
lut[k] = 4095;
}
}
Edited to apply proper source code formatting - please see How to insert source code for future reference.
2026-01-22 9:49 AM
There is no 512-byte restriction or limitation or feature within HAL_UARTEx_ReceiveToIdle_DMA. The length of data depends on the size of the buffer and how much data was received.
You can see a working example of HAL_UARTEx_ReceiveToIdle_DMA here:
Data available in buffer is passed as a parameter to HAL_UARTEx_RxEventCallback.
2026-02-19 5:50 AM
The issue was caused by the DMA being configured to normal mode, and my hardware had a 512 byte cache that was filling up before triggering the interrupt or populating the buffer.
This was fixed by switching to circular mode.