G070KBT6 - HAL_UART_Receive function return HAL_TIMEOUT early.
I called the "HAL_UART_Receive" function in my "at_send_cmd" function and set its timeout parameter to 30 seconds, but I observed that the function immediately returned HAL_TIMEOUT.
My SysTick should be working properly, and I can use the HAL_Delay function normally.
When I call the "at_send_cmd" function, it can send data normally, but cannot receive data normally because of timeout.
#include "atcmd.h"
uint8_t at_rx_buffer[512];
static void at_clean_buffer(UART_HandleTypeDef* usart){
uint8_t buffer;
while (HAL_UART_Receive(usart, &buffer, 1, 0) == HAL_OK);
}
uint16_t at_send_cmd(UART_HandleTypeDef* usart, const char* cmd, uint8_t offset, uint8_t rx_length, uint16_t timeout){
uint8_t i = 3, result;
uint16_t cmd_length = strlen(cmd);
while (i > 0){
at_clean_buffer(usart);
HAL_UART_Transmit(usart, (const uint8_t*)cmd, cmd_length, 3000);
if ((result = HAL_UART_Receive(usart, at_rx_buffer, cmd_length + offset + rx_length, timeout)) == HAL_OK){
at_rx_buffer[cmd_length + offset + rx_length] = '\0';
return cmd_length + offset;
}else if (result == HAL_TIMEOUT){
printf("Timeout.\r\n");
}
i--;
}
return 0;
}
uint8_t ec800m_mqtt_connect(){
if (USART == NULL) return 0;
uint16_t index;
//Set MQTT Config
at_send_cmd(USART, EC800M_CMD_CONFIG, 0, 2, AT_TIMEOUT);
HAL_Delay(1000);
//Open
if ((index = at_send_cmd(USART, EC800M_CMD_OPEN, 0, 15, 30000)) != 0){
printf("%s\r\n", at_rx_buffer + index);
}else{
printf("Error.\r\n", index);
}
HAL_Delay(1000);
//Connect
at_send_cmd(USART, EC800M_CMD_CONN, 0, 2, 30000);
return 0;
}
/**
* @brief Receive an amount of data in blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @note When FIFO mode is enabled, the RXFNE flag is set as long as the RXFIFO
* is not empty. Read operations from the RDR register are performed when
* RXFNE flag is set. From hardware perspective, RXFNE flag and
* RXNE are mapped on the same bit-field.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* address of user data buffer for storing data to be received, should be aligned on a half word frontier
* (16 bits) (as received data will be handled using u16 pointer cast). Depending on compilation chain,
* use of specific alignment compilation directives or pragmas might be required
* to ensure proper alignment for pData.
* @PAram huart UART handle.
* @PAram pData Pointer to data buffer (u8 or u16 data elements).
* @PAram Size Amount of data elements (u8 or u16) to be received.
* @PAram Timeout Timeout duration.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint8_t *pdata8bits;
uint16_t *pdata16bits;
uint16_t uhMask;
uint32_t tickstart;
/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
should be aligned on a u16 frontier, as data to be received from RDR will be
handled through a u16 cast. */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
if ((((uint32_t)pData) & 1U) != 0U)
{
return HAL_ERROR;
}
}
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Init tickstart for timeout management */
tickstart = HAL_GetTick();
huart->RxXferSize = Size;
huart->RxXferCount = Size;
/* Computation of UART mask to apply to RDR register */
UART_MASK_COMPUTATION(huart);
uhMask = huart->Mask;
/* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (uint16_t *) pData;
}
else
{
pdata8bits = pData;
pdata16bits = NULL;
}
/* as long as data have to be received */
while (huart->RxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
{
huart->RxState = HAL_UART_STATE_READY;
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
{
*pdata16bits = (uint16_t)(huart->Instance->RDR & uhMask);
pdata16bits++;
}
else
{
*pdata8bits = (uint8_t)(huart->Instance->RDR & (uint8_t)uhMask);
pdata8bits++;
}
huart->RxXferCount--;
}
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}Hope someone can help me :(
