CaPiTaLiZaTiOn
I was in the middle of adding DMA to my STM32 QuadSPI driver using the ST HAL layer. For the HAL layer to update its QSPI state I need to catch the QUADSPI_IRQn IRQ and call the corresponding HAL QSPI IRQ-handler.
The assembler code below is the STM32 startup weak definition of the QUADSPI_IRQHandler, which goes to an endless loop in Default_Handler if it is not redefined in code.
// Weak definition of the QUADSPI IRQ exception handler function
.weak QUADSPI_IRQHandler
.thumb_set QUADSPI_IRQHandler,Default_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
Below is the override function I defined in my .cpp file.
extern "C"
{
/**
* @brief This function handles QUADSPI interrupt request.
* @param None
* @retval None
*/
void QuadSPI_IRQHandler(void)
{
HAL_QSPI_IRQHandler(&qspiHandle);
}
}
My problem when running the code is that I was thrown into the endless loop default interrupt handler while I expected the interrupt to be handled in my override function.

I expected that my QuadSPI_IRQHandler function had not overridden the default handler. One way to quickly test that is to comment the original weak definition and check for compiler errors:

obj\debug\bcm4platform\boot\startup_stm32g473xx.o:(.isr_vector+0x1bc): undefined reference to `QUADSPI_IRQHandler'
After some head scratching I realized my override function was not capitalized correctly. A quick fix later and my IRQ handling function was being called!
extern "C"
{
/**
* @brief This function handles QUADSPI interrupt request.
* @param None
* @retval None
*/
void QUADSPI_IRQHandler(void)
{
HAL_QSPI_IRQHandler(&qspiHandle);
}
}

The lesson for today is to always check your CaPiTaLiZaTiOn.
