AnsweredAssumed Answered

UART DMA TX/Rx problem w/ STM32F722 example

Question asked by David Pekin on Feb 14, 2018

Hello,

 

I have a program using serial UART communicatons. I based the UART code on the example code UART_TwoBoards_ComDMA.  The system seems to work correctly when it is in command/response mode.  That means, I can send a serial packet from the PC to the F7.  It receives it, processes it, and sends the response back to the PC. It seems fairly reliable.  

 

I really don't understand why the UART is constantly reinitalized.  The code initializes the uart handle, then calls the TransmitDMA function, then reinitialize the UART handle and then calls the ReceiveDMA function.  Why is the reinitialization of the UART handle needed between the Transmit and Receive function??? 

 

While the system is working in the command/response mode, now I need to asynchronously transmit packets from the F7 to the PC based on a timer.  And I need to still handle the command/response from the PC correctly.  Unfortunately, when I start trying to send these packets everything starts to fall apart.  Once the async packets start sending to the PC, the system stops receiving command packets from the PC.

 

So I have the system in RX mode (ReceiveDMA function called) and the timer fires. The code reinitializes the UART handle (why is this necessary?) and then transmits the packet (TransmitDMA). The send code  waits for the UartReady == SET flag which indicates that the transmission is complete and then reinitializes the UART and calls the ReceiveDMA function again. 

 

 

The problem is that once the asynchronous transmit packets start (only once every second right now) the system fails to receive the command packets from the PC.  If I break in the debugger and turn off the asynchronous transmission, the command/response works correctly....   Below is the send code.

 

I would really like to setup and initialize the UART handle once and then just service the TX and RX callbacks.  Is there a way to do that?  

 

Thanks for any suggestions.

 

 

 

 


static void UART_Send(void)
{
HAL_StatusTypeDef retval;

// WHY do we need to reinitialize?
if(HAL_UART_DeInit(&UartHandle) != HAL_OK)
{
Error_Handler();
} 
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}

/*##-2- Start the transmission process #####################################*/
/* While the UART in reception process, user can transmit data through
"aTxBuffer" buffer */

UartReady = RESET;

do {
retval = HAL_UART_Transmit_DMA(&UartHandle, (uint8_t*)&cmd_Response, cmd_Response.msg_len+5); // + 5 for 3 byte header and 2 byte CRC
} while (retval != HAL_OK);  // I know  we need to handle the error condition here...

/*##-3- Wait for the end of the transfer ###################################*/
while (UartReady != SET) // this is set in the TX complete callback
{
}

/* Reset transmission flag */
UartReady = RESET;


/*##-4- Put UART peripheral in reception process ###########################*/

// WHY do we need to reinitialize?
if(HAL_UART_DeInit(&UartHandle) != HAL_OK)
{
Error_Handler();
}
if(HAL_UART_Init(&UartHandle) != HAL_OK)
{
Error_Handler();
}


// leave in receive mode
if(HAL_UART_Receive_DMA(&UartHandle, (uint8_t *)UART_aRxBuffer, sizeof(api_msg_t)) != HAL_OK)
{
Error_Handler();
}
}

Outcomes