cancel
Showing results for 
Search instead for 
Did you mean: 

STM32l4 UART driver

John3
Associate II

Hi everyone,

I am using stm32l4xx UART driver. I can read and write data. I am using 

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

API to read and write the data.

I am trying to know how many bytes written in "HAL_UART_Transmit", number of read bytes in API "HAL_UART_Receive" and count number of characters in receive buffer.

Could anyone please help me on this.

Thanks in advance.

John

17 REPLIES 17
Bob S
Principal

Look at the return values. If HAL_OK, then they sent/received as many bytes are you told them to send or receive. If HAL_TIMEOUT then they sent/received fewer bytes than you asked for. For the receive function, if you get a HAL_TIMEOUT, check the huart->RxFerCount value. That is how many bytes it had left to receive when it timed out. For transmit, check huart->TxXferCount for the number of UN-sent bytes.

Note that I use the term "bytes" presuming that you are transferring 8-bit data on the UART. If you are handling 9-bit larger data, then "bytes" should really be "words".

John3
Associate II

Hi Bob,

Many thanks for the reply,

Basically i want to check if any data receive.

Thanks,

John

John3
Associate II

Hi Bob,

I have written API to return number of bytes read/written.

int uart_write(UART_HandleTypeDef *huart, char *pbyte, word16 count, word16 timeout)

{

  HAL_StatusTypeDef status;

  int retcode = 0;

  if (count != 0) {

   status = HAL_UART_Transmit( huart, (uint8_t *) pbyte, count, timeout);

   if (status == HAL_OK) {

     retcode = count;

   } else {

     retcode = -1;

   }

  }

  return( retcode); 

}

int uart_read(UART_HandleTypeDef *huart, char *pbyte, word16 count, word16 timeout)

{

  HAL_StatusTypeDef status;

  int retcode = 0;

  if (count != 0) {

    status = HAL_UART_Receive(huart, (uint8_t *) pbyte, count, timeout);

    if (status == HAL_OK) {

      retcode = count;

    } else {

      retcode = -1;

    }

  }

  return( retcode);

}

I am able to transmit data , but when don't get any data on uart_read?

 Could you please help?

Bob S
Principal

I'm not sure what you are asking "but when don't get any data on uart_read". What I *think* you are asking (or what I see that you are not doing) is returning the actual number of bytes sent or received when status != HAL_OK. You always return -1 in both "else" clauses. Instead of "-1", you need to calculate the number of bytes actually sent or actually received. See my first post (copied here for your convenience with a typo fixed). I leave the math up to you.

> If HAL_TIMEOUT then they sent/received fewer bytes than you asked for.

> For the receive function, if you get a HAL_TIMEOUT, check the huart->RxXferCount

> value. That is how many bytes it had left to receive when it timed out. For transmit,

> check huart->TxXferCount for the number of UN-sent bytes.

John3
Associate II

Hi Bob,

Many thanks for the reply.

I have changed the read and write API as below:

int uart_read(UART_HandleTypeDef *huart, char *pbyte, word16 count, word16 timeout)

{

  HAL_StatusTypeDef status;

  int retcode = 0;

  if (count != 0) {

    status = HAL_UART_Receive(huart, (uint8_t *) pbyte, count, timeout);

    if (status == HAL_OK) {

      retcode = count;

    }

    else if(HAL_TIMEOUT == status) {

     retcode = count - huart->RxXferCount;

    }

    else {

      retcode = -1;

    }

  }

  return( retcode);

}

int uart_write(UART_HandleTypeDef *huart, char *pbyte, word16 count, word16 timeout)

{

  HAL_StatusTypeDef status;

  int retcode = 0;

  if (count != 0) {

   status = HAL_UART_Transmit( huart, (uint8_t *) pbyte, count, timeout);

   if (status == HAL_OK) {

     retcode = count;

   }

   else if(HAL_TIMEOUT == status) {

    retcode = count - huart->TxXferCount;

   }

   else {

     retcode = -1;

   }

  }

  return( retcode); 

}

and I am able to transmit and receive the data and also able to return the number of bytes.

I am not sure what causing an issue, but the UART receive is very slow, I mean to say if I type around 5 character on terminal it receives only 2-3 character. Do you know what could cause an issue?

Thanks,

John

Bob S
Principal

That depends on lots of things you haven't told us yet. Post your code that calls these two functions that you wrote and we'll see whats going on.

And by the way, I don't think you ever need to return -1. You either sent/recevied all the data (HAL_OK), or not all the data (!= HAL_OK). Any time it returns anything other than HAL_OK, the TxXferCount or RxXferCount will tell you what was or wasn't sent.

John3
Associate II

Hi Bob,

I have pasted code in code snippet:

void read_data(void) {
 
 char input_buf[3] = {0}; 
 
 char cmd_buf[160] = {0};
 
 word16 rx_cnt = 0;
 
 word16 rd_cnt = 0;
 
 word16 len = 0;
 
while (1) {
 
   // check if any data   
 
   rx_cnt = uart_recv_count(&UART1);
 
   if (rx_cnt > 0) {
 
     rd_cnt = uart_read(&UART1, &input_buf[0], rx_cnt, 500);
 
     char ch = input_buf[rd_cnt-1];
 
     if ((ch == '\b') || (ch == 0x7f)) {
 
     // delete previous character from buffer
 
     if (len > 0) {
 
      len -= 1;
 
      cmd_buf[len] = 0;      
 
     }
 
     rd_cnt -= 1;
 
     input_buf[rd_cnt] = 0;
 
    }
 
    if (rd_cnt > 0) {
 
     memcpy(&cmd_buf[len], &input_buf, rd_cnt);
 
     len += rd_cnt; // update counter
 
     cmd_buf[len] = 0;
 
     }
 
    }
 
     
 
    if ((ch == '\n') || (ch == '\r')) {
 
 
if (strncmp("testing", cmd_buf, 7) == 0) {
 
console_puts(&UART1, "Command matched");
 
 }
 
 else if (strncmp("off", cmd_buf, 3) == 0) {
 
console_puts(&UART1, "OFF Command");
 
 }     
 
}
 
else {
 
OS_Delay(10);
 
 }
 
}
 
//I am calling below API to init UART:
 
uart_init(LPG_USB_UART1, 115200, UART_WORDLENGTH_8B, UART_STOPBITS_1, UART_PARITY_NONE, UART_HWCONTROL_RTS_CTS);
 
 
 
//Definition
 
int uart_init(USART_TypeDef *huart, uint32_t baudrate, uint32_t bits_mask, uint32_t stops_mask, uint32_t parity_mask, uint32_t flowcontrol)
 
{ 
 
 uart1.Instance = huart;
 
 uart1.Init.BaudRate  = baudrate;
 
 uart1.Init.WordLength = bits_mask;
 
 uart1.Init.StopBits  = stops_mask;
 
 uart1.Init.Parity   = parity_mask;
 
 uart1.Init.HwFlowCtl = flowcontrol;
 
 uart1.Init.Mode    = UART_MODE_TX_RX;
 
 uart1.Init.OverSampling = UART_OVERSAMPLING_16;
 
 uart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 
 //uart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 
 if (HAL_UART_Init(&uart1) != HAL_OK)
 
 {
 
  return FALSE;
 
 }
 
 return TRUE;
 
}
 
 
 
 
 
__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
 
{
 
 GPIO_InitTypeDef GPIO_InitStruct;
 
 
 
 if(huart->Instance==USART1)
 
 {
 
   /* USER CODE BEGIN USART1_MspInit 0 */
 
    /* GPIO Ports Clock Enable */
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
 
   /* USER CODE END USART1_MspInit 0 */
 
   /* Peripheral clock enable */
 
   __HAL_RCC_USART1_CLK_ENABLE();
 
  
 
   /**USART1 GPIO Configuration   
 
   PA9   ------> USART1_TX
 
   PA10   ------> USART1_RX
 
   PA11   ------> USART1_CTS
 
   PA12   ------> USART1_RTS 
 
   */
 
   GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
 
   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
   GPIO_InitStruct.Pull = GPIO_NOPULL;
 
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
 
   GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
 
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
 }
 
}
 
 
 
int uart_write(UART_HandleTypeDef *huart, char *pbyte, word16 count, word16 timeout)
 
{
 
  HAL_StatusTypeDef status;
 
  int retcode = 0;
 
 
 
  if (count != 0) {
 
   status = HAL_UART_Transmit( huart, (uint8_t *) pbyte, count, timeout);
 
    
 
   if (status == HAL_OK)
 
     retcode = count;
 
   else 
 
    retcode = count - huart->TxXferCount;
 
  }
 
  return( retcode); 
 
}
 
 
 
int uart_read(UART_HandleTypeDef *huart, char *pbyte, word16 count, word16 timeout)
 
{
 
  HAL_StatusTypeDef status;
 
  int retcode = 0;
 
 
 
  if (count != 0) {
 
    status = HAL_UART_Receive(huart, (uint8_t *) pbyte, count, timeout);
 
 
 
    if (status == HAL_OK) 
 
      retcode = count;
 
    else 
 
     retcode = count - huart->RxXferCount;
 
  }
 
  return( retcode);
 
}
 
 
 
uint16_t uart_recv_count(UART_HandleTypeDef *huart)     /* count number of characters in receive buffer */
 
{
 
  HAL_StatusTypeDef status;
 
  int retcode = 0;
 
 
 
  status = HAL_UART_Receive(huart, (uint8_t *)recv_buff, UART_RECV_SIZE, 1);
 
   
 
  if (status == HAL_OK) 
 
    retcode = UART_RECV_SIZE;
 
  else 
 
   retcode = UART_RECV_SIZE - huart->RxXferCount;
 
  return( retcode);
 
}

Thanks,

John

John3
Associate II

Hi Bob,

I think the issue with API uart_recv_count(), it's not returning the count value every time.

uint16_t uart_recv_count(UART_HandleTypeDef *huart)     /* count number of characters in receive buffer */
 
{
 
  HAL_StatusTypeDef status;
 
  int retcode = 0;
 
 
 
  status = HAL_UART_Receive(huart, (uint8_t *)recv_buff, UART_RECV_SIZE, 1);
 
   
 
  if (status == HAL_OK) 
 
    retcode = UART_RECV_SIZE;
 
  else 
 
   retcode = UART_RECV_SIZE - huart->RxXferCount;
 
  return( retcode);
 
}

Currently I am not using any interrupt. Do I need to use Rx interrupt and API HAL_UART_Receive_IT.

Thanks,

John

T J
Lead

I would like to say that the DMA functionality on these processors works very well.

I am not sure why you wouldn't want to use it.