cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723VGTx DMA TX reboot use fail

YutinhLin
Associate II

Cube setting is OK!

First run OK!

if(HAL_OK != HAL_UART_Transmit(CO_INFO.channel, co_dma_tx_data, send_len, 0xFFFF))
    {
        DEBUG_PRINT("CO MODULE SEND DATA ERROR!!\r\n");
    }
 
Then setting OK!
if(HAL_OK==HAL_UART_AbortReceive(CO_INFO.channel))
if(HAL_OK==HAL_UARTEx_ReceiveToIdle_DMA(CO_INFO.channel,(uint8_t*)CO_INFO.RX.data,CO_UART_BUF_LENGTH))
 
But second run Fail !!
if(HAL_OK != HAL_UART_Transmit(CO_INFO.channel, co_dma_tx_data, send_len, 0xFFFF))
 
trace HAL_UART_Transmit() function
if (huart->gState == HAL_UART_STATE_READY) 
the huart->gState value always 0x33
so always return HAL_BUSY
6 REPLIES 6
TDK
Super User

The functions you listed will work as expected with the latest HAL library. You are probably executing a DMA transmit somewhere that you've forgotten about or you are using 3+ year old library code.

If you still have problems, please provide a full compile-able project which shows the issue.

 

Here is code which functions without error on a new STM32H723 project:

  if (HAL_UART_Transmit(&huart4, data, sizeof(data), HAL_MAX_DELAY) != HAL_OK) {
  	Error_Handler();
  }
  if (HAL_UART_AbortReceive(&huart4) != HAL_OK) {
  	Error_Handler();
  }
  if (HAL_UARTEx_ReceiveToIdle_DMA(&huart4, &data, sizeof(data)) != HAL_OK) {
  	Error_Handler();
  }
  if (HAL_UART_Transmit(&huart4, data, sizeof(data), HAL_MAX_DELAY) != HAL_OK) {
  	Error_Handler();
  }

 

TX and RX states for UART are independent and are handled correctly within HAL.

 

Related/duplicate:

HAL_UART_Transmit_DMA 使用 HAL_UART_AbortReceive 後異常 - STMicroelectronics Community

If you feel a post has answered your question, please click "Accept as Solution".

I'm sorry, this was my mistake.
The correct question is use HAL_UART_Transmit_DMA(CO_INFO.channelco_dma_tx_datasend_len)
not HAL_UART_Transmit(CO_INFO.channel, co_dma_tx_data, send_len, 0xFFFF)

Is this question solved?

If not, can you show the actual code you are using and not code subject to sloppy copy/paste errors? There are examples to go off of. They work.

If you feel a post has answered your question, please click "Accept as Solution".

The problem remains unresolved. Pasting the complete code would contain too much unnecessary information. My problem is simple: change your test steps to use DMA transfer. Unless you use `HAL_UART_Transmit_DMA(&huart4, data, sizeof(data))` which also works correctly.

The reason I use it this way is because I use `CO_INFO.RX.count=CO_UART_BUF_LENGTH-(__HAL_DMA_GET_COUNTER(CO_INFO.channel->hdmarx));` to get the current data index position. I want the data index position to always start from 0.

TDK
Super User

Changing the TX call to use DMA makes the second TX call fail because the first one is still in progress. This is the expected behavior. DMA works in the background and you need to wait for the previous call to finish before starting a new transfer.

If you want to abort the TX transfer, HAL_UART_AbortTransmit should be used, not HAL_UART_AbortReceive.

If you feel a post has answered your question, please click "Accept as Solution".

This raises some questions.

1.When TX calls DMA, does the state not automatically return to IDLE after data transfer is complete?
2.The reason HAL_UART_AbortReceive(&huart4) is used is because it can achieve the effect of returning the data indicator to 0. Since the DMA receive indicator will return to 0, why doesn't the DMA TX state return to IDLE?

HAL_UART_AbortTransmit, on the contrary, fails to achieve the desired effect of returning the data indicators to zero.