I have a couple dozen of custom boards with STM32G4s on them. These boards are all 'identical' and the software being loaded on them is the same. BOOT0 pin is currently floating so on my initial load I held it to ground and changed the option bytes via HAL functions to choose the software boot bits to use flash memory.
All boards initially passed functional testing, but recently some boards get stuck at memory address 0x1fff`5064 on the chip. The assembly command at this address is B . W 0x1fff'5064 which I think holds the chip at this instruction forever.
That is the latest bit of information I've gotten. I'm trying to stop short of easter egging this and am hoping for some good tests I can perform to figure out exactly what's happening here. I've included more detail below.
Background: Using CubeMx, I'm generating a project with HAL libraries and then adding code around them but leaving generated files untouched. Initial indication of an issue, beyond the chip not behaving as expected, was that uwTick was never incrementing, leading to the problem that SysTick_Handler is never getting reached. This lead me to look at the IPSR register which reports a value of 1e, which is the DMA1_Channel4_IRQHandler in my project. This only updated to have a value when I paused the debugger, which showed me the instruction the chips are stuck on, 0x1fff'5064.
The full line in the debugger is:
0x1fff'5064: 0xf7ff 0xbffe B . W 0x1fff'5064
That memory area is the bootloader, so either someone something in your code is causing a jump into the bootloader code, or something is causing the bootloader to not jump into your code. What values have you programmed into the FLASH_OPTR register and the BOOT_LOCK bit?
FLASH_OPTR register has a value of 0xfbff'f800 with nSWBOOT0 == 0 and nBOOT0 == 1. This aligns with Table 5 from the RM0440. I currently don't have BOOT_LOCK set.
I checked flash space in the debugger and it is empty on the boards that don't work. I think this bug is preventing programming flash.
This is the code that I used to program the option bytes.
HAL_FLASHEx_OBGetConfig(&OBInit); HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); // Allow Access to option bytes sector HAL_FLASH_OB_Unlock(); // Select boot from register instead of pins. OBInit.OptionType = OPTIONBYTE_USER; OBInit.USERType = OB_USER_nSWBOOT0; OBInit.USERConfig = OB_BOOT0_FROM_OB; // Write new values to the option bytes register HAL_FLASHEx_OBProgram(&OBInit); // Lock the option bytes and Flash HAL_FLASH_OB_Lock(); HAL_FLASH_Lock(); // Generate system reset to load new option bytes configuration. HAL_FLASH_OB_Launch();
> I checked flash space in the debugger and it is empty on the boards that
> don't work. I think this bug is preventing programming flash
Well, yes, THAT would be a problem. How did the Flash get erased? I presume you had code programmed into Flash. And it was that code that re-programmed the FLASH_OPTR register as you showed above..
Did you have RDP set to level 1 before you ran that code? Maybe somehow that code caused RDP to change from level 1 to level 0 (I don't think it should have), which would erase the main FLASH bank.. I haven't looked into the HAL_FLASH calls you make (its late and I'm lazy), so that's all I've got.
Curiosity - why don't you program the FLASH_OPTR when you load the initial program?
Flash got erased because I usually mass erase prior to programming; it's a habit that's hard to give up. I included the software change to the user bytes instead of using cube programmer or another ST utility because I'm compiling with IAR and didn't want to add in extra manual steps. Thanks for taking the time.