2022-04-25 12:40 AM
Hi everyone!
I've been trying to implement UART reception using LL library in polling mode. The code below is what handles the reception:
uint8_t LL_USART_Receive_Byte(USART_TypeDef *USARTx) {
// Wait for Read Data Register is not empty
while (!LL_USART_IsActiveFlag_RXNE(USARTx));
return LL_USART_ReceiveData8(USARTx);;
}
/**
* @brief Receive `len` amount of bytes on USARTx by calling LL_USART_Receive_Byte function.
* Usually, this function will be used to receive data in our programs.
* @param USARTx USART instance.
* @param buff Receive buffer.
* @param len Amount of bytes to receive
*/
void LL_USART_Receive(USART_TypeDef *USARTx, uint8_t *buff, uint32_t len) {
for (int i = 0; i < len; i++) {
buff[i] = LL_USART_Receive_Byte(USARTx);
}
}
In order to test it, I have interconnected the UART6 Tx and UART1 Rx pins in the MCU and in the main program I simply send a message.
/* USER CODE BEGIN 2 */
uint8_t textTx[8] = "Hello!\r\n";
uint8_t textRx[8] = {};
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
LL_USART_Transmit(USART6, textTx, sizeof(textTx));
LL_USART_Receive(USART1, textRx, sizeof(textRx));
LL_mDelay(2000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
The transmit function is working as expected, but the problem is that it only receives the first character. I tested it in debug mode and checked Live Expressions and Variables.
The problem is because LL_USART_Receive_Byte() function is stuck in the while (!LL_USART_IsActiveFlag_RXNE(USARTx)) loop after receiving the first character. The first iteration of the for loop in LL_USART_Receive is fine but when receiving the second character is not working anymore.
I see that the problem is something related to the RXNE flag and maybe with Overrun flag as well as I read in the docs but I can't figure out how to read the whole message.
Hope someone can help me :)
2022-04-25 06:42 AM
Hello @MCUnoob,
Yes, I don't know which MCU you are using but effectively, Overrun flags is raised and you have lost the rest of the characters.
I would suggest if you want to keep this interconnect tests on USART on the same MCU :
1) to use IT rather than polling for reception & emission of characters if you want to keep the above loop
2) transmit & receive 1 character at a time
BR,
Bruno
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2022-04-25 06:15 PM
First you transmit all of the bytes and then you start reception... You are lucky to get receive even the first byte. ;)
2022-04-25 11:42 PM
I don't really want to keep this interconnection, I set it up as a test in order to make sure how to implement UART Tx & Rx in polling mode using LL drivers. The main goal is to substitute the HAL functions HAL_UART_Transmit(...) & HAL_UART_Receive(...) with LL drivers in order to transmit and receive commands and its respones (fixed and known lengths).
By the way, I use STM32F401RE both in test and development environment. With IT, how could I receive a fixed length message?
Thank you for your time.
2022-04-25 11:43 PM
Why am I lucky? It is not suposed to work? I've seen the DMA approach, but I sticked to the polling mode solution (but it seems not to be ideal).
2022-04-25 11:54 PM
By the time you start to listen, the transmitted bytes are all gone.
JW
2022-04-26 12:19 AM
I see. Is this because of my test set up using various UARTs in the same MCU or it will be the same with UART communication between a STM32 & a modem SIM7070G?
2022-04-26 12:24 AM
What you basically need to learn is multitasking, i.e. ways to mimic the processor is doing multiple things at once. There are several approaches to this: using polling and state machines in superloop, using interrupts (DMA is roughly the same cathegory), using RTOS, maybe there are others or various subgroups and mixes.
Polling is simple, but you must not be stuck in one loop, and you have to remember the state of given process explicitly. Here, you would go like:
JW