2025-11-26 2:06 AM
Hello everyone. This is my first post so pardon me if I do something wrong.
I have a custom made board with STM32H7S7 MCU and external NOR Flash. Since it is some cheap chinese IC from LCSC I had to make my own External Loader. I didn't use the generated ExtMemLoader project from CubeIDE because it seemed too complex, was hard to understand how it works and mainly it didn't worked at all. I made the external loader with help of some YouTube videos and forum posts. Writing, reading and sector erasing works fine (though I have a problem to erase more than one sector at once) but only if I pull the BOOT0 pin HIGH, so my undestanding is that when BOOT0 is LOW the code in internal flash is executed and intializes the system and some peripherlas so if external loader tries to do the same then some conflict occurs. I have a limited options when debugging the external loader (I am using LED blinking to signalize at which part it breaks) but I found out the code execution won't get past HAL_Init().
Similar thing also happens when I have some data in my program declared to be stored in External flash so CubeIDE has to load that data into external flash before the debugger starts. In that case the code also fails at HAL_Init(), specificaly at HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY) inside HAL_MspInit()
This is the exact place where it jumps to return HAL_ERROR;
/* Check supply configuration */
if ((PWR->CSR2 & PWR_SUPPLY_CONFIG_MASK) != SupplySource)
{
/* Supply configuration update locked, can't apply a new supply config */
return HAL_ERROR;
}This is the code for Init() function of the External Loader. I added som de-init code which ChatGPT recommended me but still no change.
int Init(void) {
__disable_irq();
// 1) Disable and clean/invalidate caches — do this *first*
SCB_CleanInvalidateDCache(); // ensure all D-cache lines are written back then invalidated
SCB_DisableDCache();
SCB_InvalidateICache();
SCB_DisableICache();
// 2) Ensure interrupts masked and HAL reset
HAL_DeInit();
// 3) Disable MPU fully (do before peripheral re-init)
HAL_MPU_Disable();
// 4) Reset clock tree to safe state
// Option A: use provided RCC deinit if available:
HAL_RCC_DeInit(); // resets PLLs, HSE etc. (HAL function)
SystemInit(); // re-apply CMSIS system init if you use it
// 5) Force reset peripherals that may have been used by application
__HAL_RCC_XSPI2_FORCE_RESET();
__HAL_RCC_XSPI2_RELEASE_RESET();
// Reset all GPIO ports that XSPI pins use (example: GPIOA, GPIOB ...)
// Replace with the actual ports used by your XSPI pins
__HAL_RCC_GPION_FORCE_RESET(); __HAL_RCC_GPION_RELEASE_RESET();
SCB->VTOR = 0x20000000 | 0x200;
//__enable_irq(); //enable interrupts
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_XSPI2_Init();
NOR_Init(&hxspi2);
NOR_Restart();
if (NOR_MemoryMappedMode() != HAL_OK) {
__disable_irq(); //disable interrupts
return LOADER_FAIL;
}
/*Trigger read access before HAL_QSPI_Abort() otherwise abort functionality gets stuck*/
uint32_t a = *(uint32_t*) 0x70000000;
a++;
__enable_irq();
return LOADER_OK;
}
So should I somehow de-init the power configuration? What am I doing wrong since in neither of that tutorials I watched there wasn't this kind of problem.