2025-01-13 05:47 PM
Hi, this is my first post so I will try to provide as much information as possible. Any help is greatly appreciated! I will try to provide any missing details.
What I'm Trying To Do
Context
Problem
Note
Sample Code
FLASH_EraseInitTypeDef p_erase_init = {0};
uint32_t page_error;
p_erase_init.TypeErase = FLASH_TYPEERASE_SECTORS;
p_erase_init.Banks = FLASH_BANK_1;
p_erase_init.Sector = 1;
p_erase_init.NbSectors = 1U;
p_erase_init.VoltageRange = FLASH_VOLTAGE_RANGE_3;
HAL_FLASHEx_Erase(&p_erase_init, &page_error);
...
#if AL_EVENT_ENABLED
/* Configure GPIO as SPI interrupt input */
HW_GPIO_ClkSource(pSpiIoCfg->pIntrPort, ENABLE);
GPIO_InitStructure.Pin = pSpiIoCfg->IntrPin;
GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(pSpiIoCfg->pIntrPort, &GPIO_InitStructure);
/* Enable SPI interrupt source at NVIC */
HAL_NVIC_SetPriorityGrouping(HW_NVIC_PRIORITY_GROUP);
HAL_NVIC_SetPriority(pSpiIoCfg->IntrIrq, pSpiIoCfg->IntrPrePrio, pSpiIoCfg->IntrSubPrio);
// CPU hangs when calling this function
HAL_NVIC_EnableIRQ(pSpiIoCfg->IntrIrq);
HAL_GPIO_WritePin(USER_LED_GPIO_Port, USER_LED_Pin, 0);
#endif
...
Pin and Clock Configuration
Clock Tree
NVIC1 Settings
Solved! Go to Solution.
2025-01-14 12:59 PM
Okay I did some more testing and realized that the init function from our BSP was enabling the SPI interrupts BEFORE the SPI peripheral was initialized. My guess is that an interrupt was being fired as soon as the SPI interrupts were enabled and because the SPI peripheral wasn't even initialized yet, it caused the CPU to hang. So I guess the lesson is don't blindly trust your vendor BSP's init functions.
/* Configure SPI peripheral */
pSpiHandle->Instance = pSpiIoCfg->pInstance;
/* Reset the SPI memory interface */
pSpiHandle->Init.Mode = SPI_MODE_MASTER;
pSpiHandle->Init.Direction = SPI_DIRECTION_2LINES;
pSpiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
pSpiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH;
pSpiHandle->Init.CLKPhase = SPI_PHASE_2EDGE;
pSpiHandle->Init.NSS = SPI_NSS_SOFT;
pSpiHandle->Init.BaudRatePrescaler = pSpiIoCfg->Baudrate;
pSpiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
pSpiHandle->Init.TIMode = SPI_TIMODE_DISABLE;
pSpiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
pSpiHandle->Init.CRCPolynomial = 0;
pSpiHandle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
pSpiHandle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_04DATA;
/* Enable SPI periphral */
if (HAL_SPI_Init(pSpiHandle) != HAL_OK)
{
return -1;
}
#if AL_EVENT_ENABLED
/* Configure GPIO as SPI interrupt input */
HW_GPIO_ClkSource(pSpiIoCfg->pIntrPort, ENABLE);
GPIO_InitStructure.Pin = pSpiIoCfg->IntrPin;
GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(pSpiIoCfg->pIntrPort, &GPIO_InitStructure);
/* Enable SPI interrupt source at NVIC */
HAL_NVIC_SetPriorityGrouping(HW_NVIC_PRIORITY_GROUP);
HAL_NVIC_SetPriority(pSpiIoCfg->IntrIrq, pSpiIoCfg->IntrPrePrio, pSpiIoCfg->IntrSubPrio);
// CPU hangs when calling this function
HAL_NVIC_EnableIRQ(pSpiIoCfg->IntrIrq);
#endif
2025-01-13 06:10 PM - edited 2025-01-13 06:11 PM
Hello and welcome to the forum!
So you want to erase a sector in the internal flash of STM32H755.
SPI is not related to this so there's no any sense in enabling its interrupt (and what is "SPI interrupt source" at all?)
Remove or comment out lines 24, 27. Will it work?
2025-01-13 06:14 PM
Hangs where? If you stop the MCU in debugger where is it?
Hard Fault or perpetually locked in IRQ Handler trying and failing to clear the source.
You Erase a sector with live code in it?
2025-01-14 10:59 AM
Ah sorry for not providing the context for the SPI. For our project, the SPI is used to communicate with an EtherCAT slave controller subsystem to it is required. The code above for initializing the SPI interrupts are from our vendor BSP.
Commenting our lines 24,27 does indeed work and does not cause the MCU to hang.
2025-01-14 11:04 AM - edited 2025-01-14 12:40 PM
It hangs on this line
// CPU hangs when calling this function
HAL_NVIC_EnableIRQ(pSpiIoCfg->IntrIrq);
The interesting thing is when I step through debug the MCU, it does not hang on this line and this is true for both STM32CubeIDE and VSCode's Cortex-debug extension with our cmake project.
Hard Fault or perpetually locked in IRQ Handler trying and failing to clear the source.
Oh I see this is a good point, I will try to see if I can catch a hard fault or stuck in an IRQ handler without the debugger with the user led
You Erase a sector with live code in it?
No, the sector is cleared with 0xFF
Sorry derp, yes the sector has live code in it as in our application code lives in that sector. So just to broaden the context here, we need to clear this sector to prepare for an incoming firmware image to be written to that sector.
2025-01-14 12:59 PM
Okay I did some more testing and realized that the init function from our BSP was enabling the SPI interrupts BEFORE the SPI peripheral was initialized. My guess is that an interrupt was being fired as soon as the SPI interrupts were enabled and because the SPI peripheral wasn't even initialized yet, it caused the CPU to hang. So I guess the lesson is don't blindly trust your vendor BSP's init functions.
/* Configure SPI peripheral */
pSpiHandle->Instance = pSpiIoCfg->pInstance;
/* Reset the SPI memory interface */
pSpiHandle->Init.Mode = SPI_MODE_MASTER;
pSpiHandle->Init.Direction = SPI_DIRECTION_2LINES;
pSpiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
pSpiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH;
pSpiHandle->Init.CLKPhase = SPI_PHASE_2EDGE;
pSpiHandle->Init.NSS = SPI_NSS_SOFT;
pSpiHandle->Init.BaudRatePrescaler = pSpiIoCfg->Baudrate;
pSpiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
pSpiHandle->Init.TIMode = SPI_TIMODE_DISABLE;
pSpiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
pSpiHandle->Init.CRCPolynomial = 0;
pSpiHandle->Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
pSpiHandle->Init.FifoThreshold = SPI_FIFO_THRESHOLD_04DATA;
/* Enable SPI periphral */
if (HAL_SPI_Init(pSpiHandle) != HAL_OK)
{
return -1;
}
#if AL_EVENT_ENABLED
/* Configure GPIO as SPI interrupt input */
HW_GPIO_ClkSource(pSpiIoCfg->pIntrPort, ENABLE);
GPIO_InitStructure.Pin = pSpiIoCfg->IntrPin;
GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(pSpiIoCfg->pIntrPort, &GPIO_InitStructure);
/* Enable SPI interrupt source at NVIC */
HAL_NVIC_SetPriorityGrouping(HW_NVIC_PRIORITY_GROUP);
HAL_NVIC_SetPriority(pSpiIoCfg->IntrIrq, pSpiIoCfg->IntrPrePrio, pSpiIoCfg->IntrSubPrio);
// CPU hangs when calling this function
HAL_NVIC_EnableIRQ(pSpiIoCfg->IntrIrq);
#endif