cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 Uart Receive Interrupt and Tx with Standart Peripharel Lib

FarukSozuer
Associate III

I am trying to do serial port communication using the standard Peripharel Lib. But Std has changed a lot compared to other versions. In the older version, the following code block worked fine.

Old version of code block written with peripharel lib.
 
/*******************************************************************************
 * STM32F4::usart6Init
 *******************************************************************************
 * @brief   STM32F4 Discvoery Board USART6 init function
 * 
 * @param   void    Nothing
 * 
 * @return  void    Nothing
 * 
 *******************************************************************************         
 */
void HAL_STM32F4::usart6Init( void )
{   
  GPIO_InitTypeDef GPIO_InitStructure;
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
 
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); // tx
  GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6); // rx
	
	
  USART_InitTypeDef USART_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
	
  USART_InitStructure.USART_BaudRate   = 230400;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits   = USART_StopBits_1;
  USART_InitStructure.USART_Parity     = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl =
    USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
 
  USART_Init(USART6, &USART_InitStructure);
  USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);
 
  USART_Cmd(USART6, ENABLE);
  while (USART_GetFlagStatus(USART6, USART_FLAG_TXE) != SET)
    ;
}
 
 
 
/*******************************************************************************
 * STM32F4::usart6NVICConfig
 *******************************************************************************
 * @brief   STM32F4 Discvoery Board USART6 NVIC configuration
 * 
 * @param   void    Nothing
 * 
 * @return  void    Nothing
 * 
 *******************************************************************************         
 */
void HAL_STM32F4::usart6NVICConfig( void )
{   
	NVIC_InitTypeDef NVIC_InitStructure_USART6;
  NVIC_InitStructure_USART6.NVIC_IRQChannelPreemptionPriority = 0x05;
  NVIC_InitStructure_USART6.NVIC_IRQChannelSubPriority        = 0x04;
  NVIC_InitStructure_USART6.NVIC_IRQChannel                   = USART6_IRQn;
  NVIC_InitStructure_USART6.NVIC_IRQChannelCmd                = ENABLE;
  NVIC_Init(&NVIC_InitStructure_USART6);
}

The ll libraries published with the STM32Cube_FW_H7_V1.5.0 version do not include most of the same functions. Below is the UART Init function written by STM32Cube_FW_H7_V1.5.0. Where do I make mistakes? Receive and trasnmit not working.

void UART1_Init(void)
{
uint8_t Clock_isEnable;
 
LL_GPIO_InitTypeDef		GPIO_InitDef;
LL_USART_InitTypeDef	USART_InitTypeDef;
LL_USART_ClockInitTypeDef USART_ClockInitStructure;
//NVIC_Type				NVIC_InitSturct;
 
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);						
Clock_isEnable += LL_AHB4_GRP1_IsEnabledClock(LL_AHB4_GRP1_PERIPH_GPIOA);
LL_C1_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);						
Clock_isEnable += LL_C1_AHB4_GRP1_IsEnabledClock(LL_AHB4_GRP1_PERIPH_GPIOA);
 
LL_C2_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);						
Clock_isEnable += LL_C2_AHB4_GRP1_IsEnabledClock(LL_AHB4_GRP1_PERIPH_GPIOA);
 
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
LL_C1_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
LL_C2_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
 
GPIO_InitDef.Pin = LL_GPIO_PIN_10 | LL_GPIO_PIN_9; 	
GPIO_InitDef.Mode = LL_GPIO_MODE_ALTERNATE;												
GPIO_InitDef.Pull = GPIO_PULLUP;														
GPIO_InitDef.Speed = LL_GPIO_SPEED_FREQ_MEDIUM;											
GPIO_InitDef.OutputType = LL_GPIO_OUTPUT_PUSHPULL;										
GPIO_InitDef.Alternate = LL_GPIO_AF_8;
 
LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_10, LL_GPIO_AF_8);
LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_8);
LL_GPIO_Init(GPIOA, &GPIO_InitDef);
 
LL_USART_Enable(USART1);
 
USART_ClockInitStructure.ClockOutput = LL_USART_CLOCK_ENABLE;
USART_ClockInitStructure.ClockPhase = LL_USART_PHASE_1EDGE;
USART_ClockInitStructure.ClockPolarity = LL_USART_POLARITY_HIGH;
USART_ClockInitStructure.LastBitClockPulse =LL_USART_LASTCLKPULSE_NO_OUTPUT;
 
//LL_USART_ClockStructInit(&USART_ClockInitStructure);
LL_USART_ClockInit(USART1, &USART_ClockInitStructure);
 
USART_InitTypeDef.BaudRate  = 115200;
USART_InitTypeDef.HardwareFlowControl  = LL_USART_HWCONTROL_NONE;
USART_InitTypeDef.TransferDirection = LL_USART_DIRECTION_TX_RX;
USART_InitTypeDef.Parity = LL_USART_PARITY_NONE;
USART_InitTypeDef.StopBits = LL_USART_STOPBITS_1;
USART_InitTypeDef.DataWidth	= LL_USART_DATAWIDTH_8B;
USART_InitTypeDef.PrescalerValue = LL_USART_PRESCALER_DIV32;
USART_InitTypeDef.OverSampling = LL_USART_OVERSAMPLING_16;
 
LL_USART_Init(USART1, &USART_InitTypeDef);
 
//	LL_USART_EnableIT_RXNE_RXFNE(USART1);
//	LL_USART_EnableIT_TXE_TXFNF(USART1);
//	//LL_USART_EnableIT_TC(USART1);
//	NVIC_EnableIRQ(USART1_IRQn);
 
}

Sincelery

1 ACCEPTED SOLUTION

Accepted Solutions
Pavel A.
Evangelist III

Aha. If the problem is only with the RX interrupt on STM32H7 - disable RX overrun detection.

In the Cube library, this is one of AdvancedInit.AdvFeatureInit bits.

The Cube RX code for some reason does not even try to detect and dismiss overrun condition.

Not sure why, TL;DR just disable it, unless you want it.

-- pa

View solution in original post

5 REPLIES 5
Pavel A.
Evangelist III

Before going to the LL APIs,, please begin with the default "HAL" library.

Define all aspects of your UART in the Cube. Let it generate all its stuff.

If your project is complicated, start with a small test project that just includes the UART.

Make it work. Then move to the LL API if you like to.

-- pa

The HAL and SPL are two entirely different library approaches. LL is a third, about half-way between.

Not sure involving both cores is helpful here until you get one working.

To debug this you're going to have to work through the peripheral settings to understand what is not set correctly.

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

Thanks for answer @Community member​  and @Pavel A.​ 

I have been working with HAL Lib for a long time. But after STM32CubeIDE, I started having problems with the UART Receive Interrupt. Maybe I forget something. Code interrupt works but does not enter to interrupt after a certain time.

The corresponding code is below.

/**
  * @brief NVIC Configuration.
  * @retval None
  */
static void MX_NVIC_Init(void)
{
  /* USART1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* TIM4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(TIM4_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(TIM4_IRQn);
  /* HSEM2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(HSEM2_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(HSEM2_IRQn);
}
 
/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
void MX_USART1_UART_Init(void)
{
 
  /* USER CODE BEGIN USART1_Init 0 */
 
  /* USER CODE END USART1_Init 0 */
 
  /* USER CODE BEGIN USART1_Init 1 */
 
  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV32;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);
  /* USER CODE END USART1_Init 2 */
}
 
/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart1);
 
  //HAL_UART_RxCpltCallback(&huart1);
  if (HAL_UART_Receive_IT(&huart1,&UartReceiveData.ReceiveByteData, 1) == HAL_OK)
  {
	  UartReceiveData.IncomingBuffer[UartReceiveData.IncomingIndex++] = UartReceiveData.ReceiveByteData;
	  if (UartReceiveData.IncomingIndex >= UARTBUFFERSIZE)
	  {
		  UartReceiveData.IncomingIndex = 0;
	  }
  }
}
 

Pavel A.
Evangelist III

Aha. If the problem is only with the RX interrupt on STM32H7 - disable RX overrun detection.

In the Cube library, this is one of AdvancedInit.AdvFeatureInit bits.

The Cube RX code for some reason does not even try to detect and dismiss overrun condition.

Not sure why, TL;DR just disable it, unless you want it.

-- pa

HAL_UART_Receive_IT isn't a blocking function. It doesn't return with data.

You would need to capture the data in the callback routine, add it to your buffer, and then start another request.

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