Skip to main content
LScha.3
Associate
March 9, 2022
Question

Can't write option byte in STM32G030

We are developing a custom board with STM32G030 and we intend to update its program through its uart with system bootloader. However, I'm unable to properly configure the option byte. The HAL_FLASHEx_OBProgram always returns HAL_ERROR or HAL_TIMEOUT.

I do call both HAL_FLASH_Unlock and HAL_FLASH_OB_Unlock before this operation.

This topic has been closed for replies.

4 replies

TDK
March 9, 2022

Perhaps show the code you are using or follow the CubeG0 examples.

"If you feel a post has answered your question, please click ""Accept as Solution""."
LScha.3
LScha.3Author
Associate
March 9, 2022

   HAL_FLASHEx_OBGetConfig(&pOBInit);

   pOBInit.OptionType = OPTIONBYTE_USER;

   flashConfig = pOBInit.USERConfig;

   flashConfig &= ~FLASH_OPTR_nBOOT1;

   flashConfig &= ~FLASH_OPTR_nBOOT_SEL;

   pOBInit.USERConfig = flashConfig;

   pOBInit.USERType = flashConfig;

   while(flashRet != HAL_OK){

      flashRet = HAL_FLASH_Unlock();

   }

   flashRet = HAL_TIMEOUT;

   flashRet = HAL_TIMEOUT;

   while(flashRet != HAL_OK){

      flashRet = HAL_FLASH_OB_Unlock();

   }

   flashRet = HAL_TIMEOUT;

   flashRet = HAL_FLASHEx_OBProgram(&pOBInit);

   HAL_FLASH_OB_Launch();

   flashRet = HAL_TIMEOUT;

   while(flashRet != HAL_OK){

      flashRet = HAL_FLASH_OB_Lock();

   }

   flashRet = HAL_TIMEOUT;

   while(flashRet != HAL_OK){

      flashRet = HAL_FLASH_Lock();

   }

TDK
March 10, 2022

>  pOBInit.USERConfig = flashConfig;

>  pOBInit.USERType = flashConfig;

Why are these set the same value? 

I'd recommend looking at the HAL source file for the correct parameters to pass here.

https://github.com/STMicroelectronics/STM32CubeWL/blob/de65a6e5e3aa178705e20c71f7d78db198a80ccc/Drivers/STM32WLxx_HAL_Driver/Inc/stm32wlxx_hal_flash.h#L73

The loops to lock/unlock are weird, and the first one uses an uninitialized flashRet, at least it's not initialized anywhere in the code you've presented. If locking fails once, the correct thing to do would be to find out why it failed, not blindly try again until it works.

You don't store the result from HAL_FLASH_OB_Launch, which would be the useful one to keep track of. Note that the chip resets after a successful call to this.

"If you feel a post has answered your question, please click ""Accept as Solution""."
LScha.3
LScha.3Author
Associate
March 10, 2022

The previous code was an unsuccessful attempt to go around the problem.

The last try is this, still not working.

   FLASH_OBProgramInitTypeDef pOBInit;

   uint32_t flashConfig=0, usertype=0;

   HAL_StatusTypeDef flashRet = HAL_TIMEOUT;

   SET_BIT(RCC->AHBENR, RCC_AHBENR_FLASHEN);

   SET_BIT(FLASH->SR, FLASH_SR_PGAERR);

   SET_BIT(FLASH->SR, FLASH_SR_PGSERR);

   HAL_FLASHEx_OBGetConfig(&pOBInit);

   /* Unlock the Flash to enable the flash control register access */

   pOBInit.OptionType = OPTIONBYTE_USER;

   flashConfig = pOBInit.USERConfig;

   usertype = pOBInit.USERType;

   flashConfig &= ~FLASH_OPTR_nBOOT1;

   flashConfig &= ~FLASH_OPTR_nBOOT_SEL;

   usertype |= OB_USER_nBOOT1;

   usertype |= OB_USER_nBOOT_SEL;

   pOBInit.USERConfig = flashConfig;

   pOBInit.USERType = usertype;

   if(HAL_FLASH_Unlock() == HAL_OK){

      if(HAL_FLASH_OB_Unlock() == HAL_OK){

         HAL_FLASHEx_OBProgram(&pOBInit);

         HAL_FLASH_OB_Lock();

         HAL_FLASH_Lock();

      }

   }

I'm checking the OB_USER_nBOOT1 and FLASH_OPTR_nBOOT_SEL bits through STM32CUBE PROGRAMER