cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L496RGT, HAL and UART

DCarr.1
Senior

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?

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

4 REPLIES 4
KnarfB
Principal III

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

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.

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

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.