HAL_UART_Transmit_DMA() trigger reset
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-02-06 9:23 PM - last edited on ‎2025-02-07 3:12 AM by Andrew Neil
Hi guys, I was trying to implement HAL_UART_Transmit_DMA() since I am using freeRTOS. It auto trigger a reset for my stm32f427.
Tried HAL_UART_Transmit(), everything works well. Only HAL_UART_Transmit_DMA() causing the reset, Did I missed anything?
for (uint8_t j=1; j!=CPH_MAX_N_PORTS; ++j) // can change to +1 after disabling drone troubleshoot port
{
if(byte_1 == j)
{
if ((ports_handle[j-1])->hdmatx == NULL)
{
USER_LOG_ERROR("TX DMA not linked for UART!");
}
HAL_UART_DMAStop(ports_handle[j-1]); // Stop RX DMA before TX
ports_handle[j-1]->gState = HAL_UART_STATE_READY;
__HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TC); // TX Complete Interrupt
__HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TE); // TX Error Interrupt
if (ports_handle[j-1]->hdmatx == NULL) {
USER_LOG_ERROR("TX DMA not linked for UART!");
}
if (ports_handle[j-1]->gState != HAL_UART_STATE_READY) {
USER_LOG_ERROR("UART TX is busy (State: %d)", ports_handle[j-1]->gState);
}
if (!(ports_handle[j-1]->hdmatx->Instance->CR & DMA_SxCR_TCIE)) {
USER_LOG_WARN("TX DMA Interrupts not enabled! Enabling now...");
__HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TC);
__HAL_DMA_ENABLE_IT(ports_handle[j-1]->hdmatx, DMA_IT_TE);
}
USER_LOG_INFO("UART TX State: %d", HAL_UART_GetState(ports_handle[j-1]));
if (HAL_UART_GetState(ports_handle[j-1]) == HAL_UART_STATE_READY)
{
if(HAL_UART_Transmit(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER,10) != HAL_OK) // forward the buffer
{
USER_LOG_ERROR("UART transmission failed for port %d!", j);
}
}
else
{
USER_LOG_ERROR("UART transmission busy for port %d!", j);
USER_LOG_ERROR("UART state -> %d!", HAL_UART_GetState(ports_handle[j-1]));
}
HAL_UARTEx_ReceiveToIdle_DMA(ports_handle[j-1], DMARxBuf[j], BUFFER_SIZE); // restart the DMA
__HAL_DMA_DISABLE_IT(DMAs_handle[j-1],DMA_IT_HT); // disable the interrupt as we don’t need the Half Transfer interrupt
valid_port_found = true;
break;
}
}
* none of the error log was triggered. Initially, I tried without the non-essential code as below and I got the state value of 0x22 which is HAL_UART_STATE_BUSY_RX and that is why I am adding those extra lines of code.
if (HAL_UART_GetState(ports_handle[j-1]) == HAL_UART_STATE_READY)
{
if(HAL_UART_Transmit(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER,10) != HAL_OK) // forward the buffer
{
USER_LOG_ERROR("UART transmission failed for port %d!", j);
}
}
else
{
USER_LOG_ERROR("UART transmission busy for port %d!", j);
USER_LOG_ERROR("UART state -> %d!", HAL_UART_GetState(ports_handle[j-1]));
}
From my perspective, DMA for RX works fine, which I do receive what I want. Only calling the following will cause the HAL_UART_Transmit_DMA() reset:
HAL_UART_DMAStop(ports_handle[j-1]);
The line of code when calling HAL_UART_Transmit_DMA:
if(HAL_UART_Transmit_DMA(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER) != HAL_OK)
OR should I ask what is the correct way to do this if we detect HAL_UART_STATE_BUSY_RX.
Solved! Go to Solution.
- Labels:
-
DMA
-
STM32F4 Series
-
UART-USART
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-02-10 11:34 PM
Thanks everyone for the help, I think I have found the issue>
HAL_UART_Transmit_DMA(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER)
is reading on the buffer and I am continuing parsing the buffer in the loop.
My hypothesis,
since it is not a blocking function, and the cur_msg_pos is continuously incrementing while I parsing the message, the system might read random memory causing overflow and reset.
Solution:
Make a copy for everything AND place a flag within HAL_UART_TxCpltCallback()
Then check for the flag before sending stuff.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-02-10 6:12 AM
Hello @QE-Nicholas
>> Hi guys, I was trying to implement HAL_UART_Transmit_DMA() since I am using freeRTOS. It auto trigger a reset for my stm32f427.
- What do you mean by "reset"? Is it a system reset?
- Did you try to run the UART transfer without FreeRTOS, please?
>> OR should I ask what is the correct way to do this if we detect HAL_UART_STATE_BUSY_RX.
- You should investigate if the bus is really busy (A transfer is ongoing).
- Also, you need to be sure that the process before calling
HAL_UART_Transmit_DMA
is done correctly and the state is reset to ready.
Thanks
Omar
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-02-10 4:10 PM
Did you enable the DMA for Transmit? I know I've forgotten to enable it for transmit. Though I vaguely remember it hard faulting, not resetting the STM32.
TimerCallback tutorial! | UART and DMA Idle tutorial!
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2025-02-10 11:34 PM
Thanks everyone for the help, I think I have found the issue>
HAL_UART_Transmit_DMA(ports_handle[j-1], USB_recv_buf+cur_msg_pos+MSD_HEADER, totalBufLen-MSD_HEADER)
is reading on the buffer and I am continuing parsing the buffer in the loop.
My hypothesis,
since it is not a blocking function, and the cur_msg_pos is continuously incrementing while I parsing the message, the system might read random memory causing overflow and reset.
Solution:
Make a copy for everything AND place a flag within HAL_UART_TxCpltCallback()
Then check for the flag before sending stuff.
