2018-10-12 02:57 AM
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
2018-10-12 10:42 AM
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".
2018-10-16 09:14 PM
Hi Bob,
Many thanks for the reply,
Basically i want to check if any data receive.
Thanks,
John
2018-10-17 01:19 AM
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?
2018-10-17 08:21 AM
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.
2018-10-19 12:59 AM
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
2018-10-19 07:16 AM
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.
2018-10-19 08:39 PM
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
2018-10-23 12:12 AM
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
2018-10-23 12:32 AM
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.