AnsweredAssumed Answered

Unable to set up USART2 on NUCLEO-L432KC: assert_param failure in stm32l4xx_hal_uart.c and/or call to HardFault_Handler.

Question asked by R0b0t1 R0b0t1 on May 13, 2018
Latest reply on May 14, 2018 by R0b0t1 R0b0t1

Hello,

 

I have a NUCLEO-K432KC. In a STM32CubeMX project, I ensured USART2 and GPIOB3 were enabled per the manual. I2C1 is also enabled. A full project can be seen at GitHub - R030t1/stm32-touchpad.

 

The HAL setup routines for I2C1 and USART2 both invoke either the HardFault_Handler or the WWDG_IRQHandler (see arm - STM32 WWDG interrupt firing when not configured - Stack Overflow). In this post I would like to investigate the USART2 failures.

 

Using the vanilla code, HAL_UART_Init fails asserting IS_UART_HWCONTROL_NONE at line 12 below.

 

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
  /* Check the UART handle allocation */
  if(huart == NULL)
  {
    return HAL_ERROR;
  }
 
  if(huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
  {
    /* Check the parameters */
    assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
  }
  else
  {
    /* Check the parameters */
    assert_param((IS_UART_INSTANCE(huart->Instance)) || (IS_LPUART_INSTANCE(huart->Instance)));
  }
 
  if(huart->gState == HAL_UART_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    huart->Lock = HAL_UNLOCKED;
   
    /* Init the low level hardware : GPIO, CLOCK */
    HAL_UART_MspInit(huart);
  }
 
  huart->gState = HAL_UART_STATE_BUSY;
 
  /* Disable the Peripheral */
  __HAL_UART_DISABLE(huart);
 
  /* Set the UART Communication parameters */
  if (UART_SetConfig(huart) == HAL_ERROR)
  {
    return HAL_ERROR;
  }
 
  if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
  {
    UART_AdvFeatureConfig(huart);
  }
 
  /* In asynchronous mode, the following bits must be kept cleared:
  - LINEN and CLKEN bits in the USART_CR2 register,
  - SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/

  CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));
  CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
 
  /* Enable the Peripheral */
  __HAL_UART_ENABLE(huart);
 
  /* TEACK and/or REACK to check before moving huart->gState and huart->RxState to Ready */
  return (UART_CheckIdleState(huart));
}

 

However, if I comment this check out, at HAL_UART_Init+68 the code enters the reset handler when executing "ldr r2, [r4, #0]". I am not sure why. The memory may be out of bounds, or something else may be misconfigured. I am surprised that the libraries to not work as distributed and am having a hard time finding any that do. I had to turn to STM32CubeMX because the L4 parts are not supported by e.g. libopencm3, as they are too new.

 

For completeness here are the settings as generated by STM32CubeMX, so that one may see they should be correct:

 

void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_7B;
  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)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(uartHandle->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */

  /* USER CODE END USART2_MspInit 0 */
    /* USART2 clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();
 
    /**USART2 GPIO Configuration   
    PA2     ------> USART2_TX
    PA15 (JTDI)     ------> USART2_RX
    */

    GPIO_InitStruct.Pin = VCP_TX_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
    HAL_GPIO_Init(VCP_TX_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = VCP_RX_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF3_USART2;
    HAL_GPIO_Init(VCP_RX_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN USART2_MspInit 1 */

  /* USER CODE END USART2_MspInit 1 */
  }
}

 

Thanks in advance,

     R0b0t1

Outcomes