cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H747I-DISCO Virtual Com USART Example

Louie88
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions

 

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);
}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

26 REPLIES 26
Karl Yamashita
Lead III

You need to be sure the NVIC is enabled for the UART which most people miss.

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.
Louie88
Associate III

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

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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

 

Guenael Cadier
ST Employee

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.

GuenaelCadier_1-1738051711107.png

GuenaelCadier_0-1738051495166.png

GuenaelCadier_2-1738051794603.png

Regards
Guenael

Louie88
Associate III

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

 


@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() ?

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

KarlYamashita_0-1738059677540.png

 

Don't worry, I won't byte.
TimerCallback tutorial! | UART and DMA Idle tutorial!

If you find my solution useful, please click the Accept as Solution so others see the solution.

@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?