cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UARTEx_ReceiveToIdle_DMA only fills the first carater of my array

ABricout
Associate III

Hello,

I am trying to receive an unknown length of data on a UART on a STM32H7A3

I have declared a buffer to receive the data and aligned it :

#define UART_RX_BUFF_SIZE 256
ALIGN_32BYTES (static uint8_t uart_buff[UART_RX_BUFF_SIZE]);

Then as I am working on a cortex M7 I have declared a "free" zone at the address of my buffer for the DMA to access it :

0693W00000HqnLAQAZ.png 

0693W00000HqnK2QAJ.png0693W00000HqnJxQAJ.pngThen I set up the handler to receive the character

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if (huart->Instance == USART10)
	{
            __NOP();
	    HAL_UARTEx_ReceiveToIdle_DMA(&huart10, (uint8_t *)uart_buff, UART_RX_BUFF_SIZE);
	}
}

and finally i trigger the RX phase with the following:

HAL_UARTEx_ReceiveToIdle_DMA(&huart10, (uint8_t *)uart_buff, UART_RX_BUFF_SIZE);

My problem is that what the interrupt happens, I see that the size is correct (the number of bytes that I am expecting) but the RX buffer if filled only on the first character. So, I can only see the last received character and not the full data. Each byte overwrites the one that came before and I am left with only the last one. Is there a missing increment that I am supposed to change or do I miss something?

Thank you by advance

Augustin

5 REPLIES 5
Piranha
Chief II

You have to manage D-cache:

https://community.st.com/s/question/0D53W00000oXSzySAG/different-cache-behavior-between-stm32h7-and-stm32f7

Alternatively you can use MPU to configure non-cacheable region. For quick testing purposes just do not enable D-cache.

And you have to manage your receive buffer pretty awfully:

https://community.st.com/s/question/0D53W00001JBm0PSAT/haluartexreceivetoidledma-idle-event-what-is-that-whatever-it-is-is-not-working-for-me

QLeco.1
Associate II

I came across the exact same issue and was stuck on it for 3 days. I couldn't find anything on the web,

but I finally found out something that could interest you. For some reasons, the auto generated code in my main function made it so UART is initialized BEFORE DMA. And thus, nothing works as intended after this. I found out by checking the DMA registers. I found that the CIRC bit of S0CR register was not set when it should have, and then tried to find where it was supposed to be set on a working demo I had. Guess what ? it's set in the UART initialise function. Which was called before DMA initialisation and so before S0CR was accessible I think. Hope this helps you and others that might encounter this issue.

Br,

Quentin

Yes this was this issue !

Thank you for telling me why the generation was broken, I couldn't understand why it was doing this.

Have a nice day !

Quentin

Pavel A.
Evangelist III

@QLeco.1​ Also, the base address of a MPU region must be aligned on the region size.

You've defined a region with size 1KB at 0x24000420.

The cube should validate the MPU settings better...