2025-09-11 12:37 AM - last edited on 2025-09-11 1:03 AM by Andrew Neil
Hello ST Community,
I am working with STM32H750VBTx on STM32CubeIDE. I use UART7 + DMA with HAL_UARTEx_ReceiveToIdle_DMA()
to receive responses from a GSM modem.
Problem:
- GSM responses are stored in my gsm_response_buffer[] incrementally
- For example: first "RDY", then "AT OK", then "ATE0 OK" → all get appended
- I expected each new DMA reception to start at buffer[0].
Debug screenshots are attached.
Could you please advise how to properly useDMA reception so each new response starts from
gsm_response_buffer[0]?
Thanks in advance!
Refer the code in the Test_GSM.c file also if needed
in the main.c file i call
```c
/* USER CODE BEGIN 2 */
#if (ENABLE_006_GSM_Folder == 1)
HAL_UARTEx_ReceiveToIdle_DMA( &huart7, gsm_response_buffer, GSM_RESPONSE_BUFFER_SIZE );
__HAL_DMA_DISABLE_IT(&hdma_uart7_rx, DMA_IT_HT);
#endif
```
```c
/* USER CODE BEGIN 0 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart->Instance == UART7){
HAL_UARTEx_ReceiveToIdle_DMA(&huart7,
gsm_response_buffer,
GSM_RESPONSE_BUFFER_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_uart7_rx, DMA_IT_HT);
}
}
/* USER CODE END 0 */
```
Edited to apply proper source code formatting - please see How to insert source code for future reference.
2025-09-11 12:42 AM
these are my ioc settings
2025-09-11 2:33 AM
It looks like the Rx Complete callback is only called once, at the end of all reception sequence.
In other words could it happen that all received data are sent in sequence without sufficient time between some cars to trig the IDLE event ?
A test you could make is to add a counter in HAL_UARTEx_RxEventCallback() to check how many times it is called, and try to check what is the value of Size when called.
Hope this helps
2025-09-11 5:46 AM
You were right the HAL_UARTEx_RxEventCallback was not getting called at all in my previous setup.
Even when i was receiving data from the GSM module.
without the global interrupt the
HAL_UARTEx_ReceiveToIdle_DMA(&huart7,
gsm_response_buffer,
GSM_RESPONSE_BUFFER_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_uart7_rx, DMA_IT_HT);
call only ran once and it continued to receive the RX data.
```c
/* USER CODE BEGIN 0 */
#if (ENABLE_006_GSM_Folder == 1)
int count = 0;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
count+=1;
printf("count = %d\n", count);
printf("size = %d\n", Size);
#if (ENABLE_006_GSM_Folder == 1)
if(huart->Instance == UART7){
HAL_UARTEx_ReceiveToIdle_DMA(&huart7,
gsm_response_buffer,
GSM_RESPONSE_BUFFER_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_uart7_rx, DMA_IT_HT);
}
#endif
}
#endif
/* USER CODE END 0 */
```
i did this now it works *.
i enabled the UART7 global interrupt
and also increased it's preemption priority to 7 from 5
* well in a weird way the replay from the gsm module is getting received sometimes
When i turn on the gsm module i will get a RDY replay in RX
if i get this i get the rest of the AT command replays
if i don't receive any at all
now the weird thing is even if i don't get any replays the gsm module is able to send the message to mqtt broker.
2025-09-11 6:15 AM - edited 2025-09-11 6:16 AM
Another weird thing i noticed was when i ran the code without any breakpoints i got no replay from the RX line.
but when i debug with breakpoints i put one on the call
HAL_UARTEx_ReceiveToIdle_DMA( &huart7,
gsm_response_buffer,
GSM_RESPONSE_BUFFER_SIZE);
of /* USER CODE BEGIN 2 */
when i do this the responses came.
Now i put a delay as shown below and it worked!
```c
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_UART7_Init();
/* USER CODE BEGIN 2 */
#if (ENABLE_006_GSM_Folder == 1)
HAL_Delay(2000);
HAL_UARTEx_ReceiveToIdle_DMA( &huart7,
gsm_response_buffer,
GSM_RESPONSE_BUFFER_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_uart7_rx, DMA_IT_HT);
#endif
```
Does anyone know why is this so?
2025-09-11 11:25 AM
There is two ways you can go about fixing it.
2025-09-11 1:03 PM
You need to restart the DMA buffer after each complete reception. By default, HAL_UARTEx_ReceiveToIdle_DMA() keeps appending until the buffer is full. In your case, once a response is processed, you should:
Stop the DMA (HAL_UART_DMAStop()),
Clear or reset your gsm_response_buffer,
Call HAL_UARTEx_ReceiveToIdle_DMA() again with the same buffer pointer.
This way, each new GSM response starts writing at buffer[0] instead of appending.
2025-09-11 9:58 PM
/* USER CODE BEGIN 0 */
#if (ENABLE_006_GSM_Folder == 1)
int count = 0;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
count+=1;
printf("count = %d\n", count);
printf("size = %d\n", Size);
HAL_UART_DMAStop(&huart7);
#if (ENABLE_006_GSM_Folder == 1)
if(huart->Instance == UART7){
HAL_UARTEx_ReceiveToIdle_DMA(&huart7,
gsm_response_buffer,
GSM_RESPONSE_BUFFER_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_uart7_rx, DMA_IT_HT);
}
#endif
}
#endif
/* USER CODE END 0 */
I tried this it didn't work.
2025-09-11 10:01 PM
Thanks for the link.
I will try it sometime in the future.
Currently my problem got resolved by putting a delay after the initialization code.
I don't know why is this happening, if you know please inform me.