2025-01-27 02:27 PM
Hi,
If I understand right USART1 is used in STM32H747I-DISCO board for VCOM. I could not find any example for my board. I would like to want for an 8-byte host command using:
HAL_UART_Receive_IT(&huart1, hostCommand.buffer, 8);
Once a command is received then I process it, I create the answer and wait for the next command. So simple.
Noe: on CN13 pin 13 I see the command from my PC on scope, but the HAL_UART_RECEIVE_IT() never receives anything.
Can sombody send me a short example?
Thanks,
Louie
Solved! Go to Solution.
2025-01-28 08:54 AM
void USART1_IRQHandler(void) // gets called per byte/interrupt
{
HAL_UART_IRQHandler(&huart1); // calls into HAL, it works the buffering and calls your call-back when complete
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) // call from HAL_UART_IRQHandler
{
// Do something with the filled buffer
..
HAL_UART_Receive_IT(&huart1, hostCommand.buffer, 8); // initate again (returns immediately)
}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)
{
Error_Handler(); // or manage failure
}
main()
{
..
HAL_UART_Receive_IT(&huart1, hostCommand.buffer, 8); // start (returns immediately)
while(1);
}
2025-01-27 02:41 PM
You need to be sure the NVIC is enabled for the UART which most people miss.
2025-01-27 02:55 PM
Hi Karl,
Thanks for the reply. Of course, it is enabled.
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(huart->Instance==USART1)
{
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInitStruct.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PB7 ------> USART1_RX
PA9 ------> USART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
}
}
Thanks,
Louis
2025-01-27 05:32 PM
HAL_UART_Receive_IT() returns immediately, you have to catch the content in the callback.
Make sure the UART is not flagging some kind of status or error, ie noise, framing, etc
2025-01-27 11:26 PM - edited 2025-01-27 11:51 PM
Hi Tesla DeLoran,
Thanks for the generic answer, but you know the question: How I can do that?
In stm32h7xx_it.c:
void USART1_IRQHandler(void)
{
// RXNE flag will be cleared by reading of RDR register (done in call)
// Call function in charge of handling Character reception
USART1_CharReception_Callback();
// Generated code
// HAL_UART_IRQHandler(&huart1);
}
in main.c:
void USART1_CharReception_Callback(void)
{
// Get ISR register of USART3
uint32_t isr = huart1.Instance->ISR;
// USART_ISR_RXNE_RXFNE = Read Data Register or RX FIFO Not Empty
if (isr & USART_ISR_RXNE_RXFNE)
{
// Read Received character. RXNE flag is cleared by reading of RDR register
hostCommand.buffer[hostCommand.dataIndex++] = (uint8_t)huart1.Instance->RDR;
if (hostCommand.dataIndex >= HOST_CMD_BUF_LENGTH)
hostCommand.dataIndex = 0;
}
}
The interrupt is raised once during startup one and never again.
What is wrong?
Louis
2025-01-28 12:10 AM
Hi @Louie88
Are you using the Virtual COM port on ST-Link connection ?
In this case, I'm not sure you are using the right PIN for RX (PB7).
Could you try PA10 instead ?
In DK manuals and schematics, I think PA9/PA10 are mentioned for VCP connection on this board.
Regards
Guenael
2025-01-28 01:00 AM
Hi Guenael,
You are absolutely right. Thanks for the note. I never checked the pinouts because those were assigned by STM32CubeMX, when I enabled the USART1 for H7 CPU.
Bit I double checked it. I disable USART1 first then, the PB7 was released (form USART1). But when I enable USART1 again the STM32CubeMX always assigns PB7 instead of PA10 as RX pin. You found a bug in STM32CubeMX, I think.
Currently I am not in the office, but I will check it during this afternoon and report back what I found to you..
Thanks again! It seems to be very valuable notice.
Louis
2025-01-28 01:02 AM
@Tesla DeLorean wrote:Make sure the UART is not flagging some kind of status or error, ie noise, framing, etc
@Louie88 wrote:Thanks for the generic answer, but you know the question: How I can do that?
Doesn't the HAL do that - via HAL_UART_IRQHandler() ?
Isn't there a HAL_UART_ErrorCallback() ?
2025-01-28 02:18 AM - edited 2025-01-28 02:22 AM
That's not a bug. USART1 has 3 user selectable Rx pins, and 3 user selectable Tx pins. You just have to override what CubeMX selects when you enable USART1. So in CubeMX, left click PA9 and PA10 pins and choose USART1 Tx and Rx configuration.
Or search for it. For Rx example, you can see the 3 black pins that are available
2025-01-28 02:25 AM
@Louie88 wrote:I never checked the pinouts because those were assigned by STM32CubeMX, when I enabled the USART1
Did you tell CubeMX that it's an STM32H747I-DISCO board?