NUCLEO-WL55JC Change FLASH_OPTR and Enter SPI Bootloader
Hello,
Full application code is based off of LoRaWAN_End_Node_LBM. I am using the below code to attempt to change the OTPR bits to boot from bootloader (system) for SPI connection. This code is executed after receiving a command via SPI communications by another microcontroller. The idea is for the other microcontroller to receive the update file and program the STM32WL55 via SPI.
Pattern 13: nBoot0(bit) = 0, nBoot1(bit) = 1 and nSWBoot0(bit) = 0
FLASH->CR is 0x00000000
I monitor the FLASH->OPTR register in debug and see that the OPTR does not change from 0x3FFFF0AA before reset.
After reset, I lose connection with debug. I know it is still booting into Flash because it reconnects with our LoRaWAN Gateway.
- Am I missing something? Trying to piece things together with three different documents and trying to determine if BFU_1_Slot is relevant and how it can be modified for SPI.
- Are there any clear example code specifically for my device that already demonstrates what I am attempting to accomplish?
- Should I be able to observe the changes in the FLASH->OPTR bits before reset? Why can’t I change the OPTR register?
- Am I understanding this right that the flow chart from AN2606 Figure 118 is the embedded bootloader? No extra programming needed?
- Does the bootloader loop indefinitely until the synchronization byte (0x5A from AN4286) and frame is received?
- Do the OPTR register return to its default 0x3FFFF0AA after exiting the bootloader (Go Command)?
HAL_StatusTypeDef ClearnBootSel()
{
uint32_t UserType,UserConfig,RDPLevel;
FLASH_OBProgramInitTypeDef OB;
HAL_FLASHEx_OBGetConfig(&OB);
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
//UserType = OB_USER_BOOT_LOCK|OB_USER_nSWBOOT0|OB_USER_nBOOT0|OB_USER_nBOOT1;
//UserConfig = OB_BOOT_LOCK_DISABLE|OB_BOOT0_FROM_OB|OB_BOOT0_RESET|OB_BOOT1_SET;
//RDPLevel = OB_RDP_LEVEL_0;
//FLASH_OB_OptrConfig(UserType,UserConfig,RDPLevel);//(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
OB.OptionType = OPTIONBYTE_USER;
OB.UserType = OB_USER_BOOT_LOCK;
OB.UserConfig = OB_BOOT_LOCK_DISABLE;
if ( HAL_FLASHEx_OBProgram(&OB) != HAL_OK )
{
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return HAL_ERROR;
}
OB.OptionType = OPTIONBYTE_USER;
OB.UserType = OB_USER_nSWBOOT0;
OB.UserConfig = OB_BOOT0_FROM_OB;//OB_BOOT0_RESET;
if ( HAL_FLASHEx_OBProgram(&OB) != HAL_OK )
{
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return HAL_ERROR;
}
OB.OptionType = OPTIONBYTE_USER;
OB.UserType = OB_USER_nBOOT0;
OB.UserConfig = OB_BOOT0_RESET;
if ( HAL_FLASHEx_OBProgram(&OB) != HAL_OK )
{
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return HAL_ERROR;
}
OB.OptionType = OPTIONBYTE_USER;
OB.UserType = OB_USER_nBOOT1;
OB.UserConfig = OB_BOOT1_SET;
if ( HAL_FLASHEx_OBProgram(&OB) != HAL_OK )
{
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return HAL_ERROR;
}
HAL_FLASH_OB_Launch();
// We should not make it past the Launch, so lock flash memory and return an error from function
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
return HAL_ERROR;
}
