2023-09-11 08:38 AM
Hi all,
I am using the Nucleo STM32U575ZI-Q and have been trying to get low level USART with DMA working. Transmitting data works fine as I can see the data using a logic analyser but when I try to receive data either from another Nucleo or putting the wire from Tx to Rx I get nothing.
I have a Asynchronous USART with DMA channels for both Tx and Rx.
In MX_USART1_UART_Init() I enable:
LL_DMA_EnableIT_HT(GPDMA1, LL_DMA_CHANNEL_10);
LL_DMA_EnableIT_TC(GPDMA1, LL_DMA_CHANNEL_10);
LL_DMA_EnableIT_TC(GPDMA1, LL_DMA_CHANNEL_11);
LL_USART_EnableIT_IDLE(USART1);
In my other init function for my code I set the DestAddress, BlkDataLength and also enable the channel:
LL_DMA_SetDestAddress(pDMATypedef, LL_DMA_CHANNEL_10, (uint32_t)RXBuffer);
LL_DMA_SetBlkDataLength(pDMATypedef, LL_DMA_CHANNEL_10, mARRAY_LEN(RXBuffer));
LL_DMA_EnableChannel(pDMATypedef, LL_DMA_CHANNEL_10);
In my Rx DMA interrupt I call a function which calls another function which will check if there is any data in the buffer. This checking function also gets called from the USART interrupt.
My problem is when it comes to check the data in the buffer there is nothing:
uint32_t u32Pos = sizeof(RXBuffer) - LL_DMA_GetBlkDataLength(pDMATypedef, LL_DMA_CHANNEL_10);
This function does not get called from the Rx DMA interrupt but from the USART interrupt.
Is there anything I have missed or have not done correctly?
If there is any other information needed please ask!
Many thanks!
Solved! Go to Solution.
2023-09-12 08:22 AM
Hi @Foued_KH
I have fixed my problem thanks!
In MX_USART1_UART_Init in main.c, cube was not generating 2 function calls which I seemingly need.
I had to add:
NodeConfig.SrcAddress = LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE);
To the auto generated code, as I cannot add this to the user defined area.
But I also had to add these two calls to my user defined area:
LL_DMA_ConfigLinkUpdate(GPDMA1, LL_DMA_CHANNEL_0,
(LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR
| LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CTR3 | LL_DMA_UPDATE_CBR2 | LL_DMA_UPDATE_CLLR),
(uint32_t)&Node_GPDMA1_Channel0);
LL_DMA_EnableChannel(GPDMA1, LL_DMA_CHANNEL_0);
The LL_DMA_ConfigLinkUpdate call should probably be auto generated but it is not.
And as for LL_DMA_EnableChannel, I do call this in another part of my code as part of initialisation but for some reason it needs to be called here as well.
Thanks.
2023-09-11 08:45 AM
Hello @JNoon.1 ,
I suggest you to check the available examples : STM32CubeU5/Projects/NUCLEO-U575ZI-Q/Examples_LL/USART at main · STMicroelectronics/STM32CubeU5 · GitHub
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-09-11 08:55 AM - edited 2023-09-11 08:55 AM
Hi @Foued_KH,
Thank you for your reply. Unfortunately I have been looking at the examples and this one (https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx/blob/main/projects/usart_rx_idle_line_irq_ringbuff_tx_loopback_U5/Src/main.c) but neither seem to help me in this situation. I have been looking through the examples and I am not seeing anything in particular that is wrong.
Google isn't the biggest help either as there are not many LL USART examples out there for the U5 series.
Thanks.
2023-09-11 09:09 AM
2023-09-12 08:22 AM
Hi @Foued_KH
I have fixed my problem thanks!
In MX_USART1_UART_Init in main.c, cube was not generating 2 function calls which I seemingly need.
I had to add:
NodeConfig.SrcAddress = LL_USART_DMA_GetRegAddr(USART1, LL_USART_DMA_REG_DATA_RECEIVE);
To the auto generated code, as I cannot add this to the user defined area.
But I also had to add these two calls to my user defined area:
LL_DMA_ConfigLinkUpdate(GPDMA1, LL_DMA_CHANNEL_0,
(LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 | LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR
| LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CTR3 | LL_DMA_UPDATE_CBR2 | LL_DMA_UPDATE_CLLR),
(uint32_t)&Node_GPDMA1_Channel0);
LL_DMA_EnableChannel(GPDMA1, LL_DMA_CHANNEL_0);
The LL_DMA_ConfigLinkUpdate call should probably be auto generated but it is not.
And as for LL_DMA_EnableChannel, I do call this in another part of my code as part of initialisation but for some reason it needs to be called here as well.
Thanks.