cancel
Showing results for 
Search instead for 
Did you mean: 

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

R0b0t1 R0b0t1
Associate II
Posted on May 13, 2018 at 06:07

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

https://github.com/R030t1/stm32-touchpad

.

The HAL setup routines for I2C1 and USART2 both invoke either the HardFault_Handler or the WWDG_IRQHandler (see

https://stackoverflow.com/questions/27623885/stm32-wwdg-interrupt-firing-when-not-configured

). 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

#serial #nucleo-l432kc #hal-usart #serial-communication
3 REPLIES 3
Posted on May 14, 2018 at 00:20

The WWDG_IRQHandler issue is more of you having dozens of IRQ's and System Handlers dumping into the 'Default_Handler' which the GNU Linker is dumping you into when your actual IRQ Handler is missing. If you look at the .MAP you'll see hundreds of symbols sharing the WWDG_IRQHandler address. Unlikely to actually be the WWDG.

>>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.

Observing the value in R4 might be instructive, along with the actual C line that relates too. Is usart2 structure fully initialized? Or zeroed out completely initially.

>>I am surprised that the libraries to not work as distributed and am having a hard time finding any that do.

Honestly not have trouble with things here, perhaps use something like Keil or IAR, and stop using CubeMX, and look at the HAL based examples under the Cube L4 repository. These are written by people, and should be mostly functional. Don't rely on automatons to write your code.

Make sure the USART2 and GPIOA clocks are enabled somewhere, I don't care for this information hiding with the Msp calls.

Will dig up a simple NUCLEO-K432KC framework I built tomorrow, not on the current box. It has the VCP/USART working, and proper Hard Fault Handler, which is a tad more useful than a while(1) loop.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 14, 2018 at 03:11

 ,

 ,

Clive One wrote:

The WWDG_IRQHandler issue is more of you having dozens of IRQ's and System Handlers dumping into the 'Default_Handler' which the GNU Linker is dumping you into when your actual IRQ Handler is missing. If you look at the .MAP you'll see hundreds of symbols sharing the WWDG_IRQHandler address. Unlikely to actually be the WWDG.

 ,

>,>,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.

 ,

Observing the value in R4 might be instructive, along with the actual C line that relates too. Is usart2 structure fully initialized? Or zeroed out completely initially.

I will check the code, but I do not know what a fully initialized structure looks like.

Clive One wrote:

>,>,I am surprised that the libraries to not work as distributed and am having a hard time finding any that do.

Honestly not have trouble with things here, perhaps use something like Keil or IAR, and stop using CubeMX, and look at the HAL based examples under the Cube L4 repository. These are written by people, and should be mostly functional. Don't rely on automatons to write your code.

 ,

Make sure the USART2 and GPIOA clocks are enabled somewhere, I don't care for this information hiding with the Msp calls.

 ,

Will dig up a simple NUCLEO-K432KC framework I built tomorrow, not on the current box. It has the VCP/USART working, and proper Hard Fault Handler, which is a tad more useful than a while(1) loop.

I did try to not use CubeMX and referred directly to the datasheet. Progress this way was slow, largely due to the difficulty in making sure peripheral setup was exhaustive. Especially for L4 parts there are not good references between sections indicating everything that needs set up. There may technically be all the required information, but it is not easy to find.

I gave up using this method and tried to use libopencm3 but the L4 parts are too new. Seeing as I couldn't readily fix libopencm3 from the manual I opted to try to use CubeMX code and then inspect the registers that were written. So far this hasn't worked either, and I am out of options.

The clocks are enabled. The processor doesn't seem to fully initialize the devices. I will have to check to see if the ISRs are missing for some reason.

The example would be appreciated.

Cheers,

 , , , , R0b0t1

Posted on May 14, 2018 at 07:11

For better or worse I tried going back to the LL drivers for all of the peripherals I had enabled. The project now compiles and runs properly, save I am unable to send characters out of USART2. I had originally tried the LL drivers but found the project would not compile.

I suspect there is an issue when regenerating a project that uses a Makefile.

I would appreciate if the original question could be answered, but I am also interested in the best way to proceed from here.