cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Transmit() with HAL_UART_Receive_IT() fails if RX when TX not completed.

Thomas LB
Associate III

I used to send AT command to a module with HAL_UART_Transmit():

void send_uart(char * buffer)
{
	uint16_t buffer_size = strlen(buffer);	
	uint8_t CRLFbuff[] = "\r\n";
	HAL_UART_Transmit(&hlpuart1, CRLFbuff, 2, 0xFF); // ok
	HAL_UART_Transmit(&hlpuart1, (uint8_t *)buffer, buffer_size, 0xFF); // ok
	HAL_UART_Transmit(&hlpuart1, CRLFbuff, 2, 0xFF); // ok
}

and receive answer with HAL_UART_Receive_IT() byte per byte:

HAL_UART_Receive_IT(&hlpuart1, &Rx_data, 1);
 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)  
{
        if (huart->Instance == LPUART1){ // Current UART
		if (Rx_indx + 1 > rx_buffer_size){
			Rx_indx = 0;
		}
                if (Rx_data != 0x0A){ // If received data different from LF
                        Rx_Buffer[Rx_indx++] = Rx_data;    // Add data to Rx_Buffer
		}
		else {
			Rx_indx = 0;
			Transfer_cplt++;//transfer complete, data is ready to read
		}
		HAL_UART_Receive_IT(&hlpuart1, &Rx_data, 1);   //activate UART receive interrupt every time          
	}
}

And this is working well at 9600 in nominal TX/RX. But if I send bad data to the module it sends immediately "ERROR: parse error" while my STM32L031 is still transmitting. This as the effect of killing my RX interrupt. Instead of being HAL_UART_STATE_BUSY_RX the UART->RxState switches to HAL_UART_STATE_READY and RX interrupt is never triggered (transmit part still works good).

I changed my transmit code to HAL_UART_Transmit_IT (with little rework) and this behavior is not observed (works well).

Is this normal ?

10 REPLIES 10

I know, I'm late!

Thanks a lot for your explanations. I'm using the STM32Cube_FW_G4_V1.5.1. In the functions HAL_UART_Transmit_IT and the HAL_UART_Receive_IT containt the macro __HAL_LOCK().

If I wand to process TX and RX with variable length. I would implement the RxCallback like this.

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	// Store the recieve character to the next layer
 
        // Restart Receive
	HAL_StatusTypeDef status = HAL_UART_Receive_IT(&huart1, UART1_rxBuffer, 1);
	if (status != HAL_OK) {
		__NOP(); // Only for setting breakpoint
	}
}

And somewhere in the main loop (for example) I would like to trigger a TX-Message like this.

...
HAL_StatusTypeDef status = HAL_UART_Transmit_IT(&huart1, UART1_txBuffer, length);
if(status!=HAL_OK) {
    __NOP(); // Only for setting breakpoint
}
...

Due the asynchronous processing there is a race condition by the __HAL_LOCK().

What did I miss? Thank you for your help.