2022-03-10 01:29 AM
Hello all,
I'm having some serious problems communicating with a device attached to USART2 on a custom STM32L496RGT, board, configured in CubeMX.
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
I reset the device using a GPIO signal at which point it sends the string "%REBOOT%" to the USART.
If I set up the USART to generate an RXNE interrupt which I handle in my own code and store in a ring buffer, the string is received without difficulty:
const int buf_sz = 32;
char buf[buf_sz];
HAL_GPIO_WritePin(BL_RST_GPIO_Port, BL_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(BL_RST_GPIO_Port, BL_RST_Pin, GPIO_PIN_SET);
read_from_ring(buf_sz, buf);
Which I'm taking to demonstrate the the USART baud rate etc has been correctly configured and that the board wiring is OK.
However, if I don't enable the interrupt in CubeMX and just use the HAL call:
const int buf_sz = 32;
char buf[buf_sz];
HAL_GPIO_WritePin(BL_RST_GPIO_Port, BL_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(BL_RST_GPIO_Port, BL_RST_Pin, GPIO_PIN_SET);
HAL_StatusTypeDef hal = HAL_OK;
for(int i = 0; hal == HAL_OK && i < cnt; ++i) {
hal = HAL_UART_Receive(&huart2, &buf[i], 1, 1000);
}
I either receive one character or nothing at all, all terminated with a timeout I also tried a single read
const int buf_sz = 32;
char buf[buf_sz];
HAL_GPIO_WritePin(BL_RST_GPIO_Port, BL_RST_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(BL_RST_GPIO_Port, BL_RST_Pin, GPIO_PIN_SET);
HAL_StatusTypeDef hal = HAL_UART_Receive(&huart2, buf, buf_sz, 1000);
with the same result: either nothing or just one character gets read and then there's a timeout
Using the interrupt handler to read would actually fine for me, but the problem is that sending strings from the MCU also seems to fail, and I'm guessing that it's for the same reason that the simple read fails.
Is there some trick to getting STM32L496RGT, HAL and UART to work together?
Solved! Go to Solution.
2022-03-10 11:32 PM
Thank you again.
DMA in this case is not an appropriate solution as I'm already using all the available channels for background screen and IO updates.
I solved the problem by accessing the USART directly without bothering with the HAL functions at all which it turns out really aren't all that well suited to my needs.
2022-03-10 03:34 AM
Reading UART in a for loop is not good, because the receiving site should be *always* listening.
Your last code may work if the buffer size equals the string length and you use HAL_MAX_DELAY for the timeout.
Advanced methods are receive to idle HAL_UARTEx_ReceiveToIdle
and/or using a DMA buffer for incoimng chars: https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx
hth
KnarfB
2022-03-10 04:54 AM
Thankyou for your anwser.
Before getting into optimised techniques, I was hoping to get the simple ones working.
The call to HAL_UART_Receive(&huart2, buf, buf_sz, 1000) should clearly timeout after the eighth byte, but instead fails either immediately or after one byte.
Reading one byte at a time was just a test to see what was going on.
2022-03-10 06:13 AM
HAL_UARTEx_ReceiveToIdle is not complicated if the messages have some max. length, like line oriented command with a max. line lenght like 256 or such.
HAL_UARTEx_ReceiveToIdle( &huart2, line, sizeof(line), &len, 1000);
DMA is also not too complicated but probably not needed. Suited if you receive a practically endless stream of chars.
hth
KnarfB
2022-03-10 11:32 PM
Thank you again.
DMA in this case is not an appropriate solution as I'm already using all the available channels for background screen and IO updates.
I solved the problem by accessing the USART directly without bothering with the HAL functions at all which it turns out really aren't all that well suited to my needs.