Skip to main content
Graduate
December 5, 2023
Question

Problem with option bytes set from program level- G0B1

  • December 5, 2023
  • 3 replies
  • 2249 views

Hi! I have problem with setting option bytes from program. Setting OBs from Cube Programmer working good. MCU im using is STM32G0B1. 

 

I found and implement this function:

 

 

 

HAL_StatusTypeDef optionByteSetBootFromPin(void) {

	FLASH_OBProgramInitTypeDef OB;
		HAL_FLASHEx_OBGetConfig(&OB);

		/* OB.USERConfig returns the FLASH_OPTR register */
		// Use it to check if OB programming is necessary
		if (OB.USERConfig & FLASH_OPTR_nBOOT_SEL)
		{

			 HAL_StatusTypeDef status;

			 OB.OptionType = OPTIONBYTE_USER;
			 OB.USERType = OB_USER_nBOOT_SEL;
			 OB.USERConfig = OB_BOOT0_FROM_PIN;

			 status = HAL_FLASH_Unlock();
			 status = HAL_FLASH_OB_Unlock();

			 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

			 status = HAL_FLASHEx_OBProgram(&OB);

			 if ( status != HAL_OK )
			 {
				 status = HAL_FLASH_OB_Lock();
				 status = 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;
		}

		return HAL_OK;
}

 

 

 

 

I ran this after HAL_Init();

That's effect:

HAL_FLASH_Unlock() and HAL_FLASH_OB_Unlock() returns HAL_OK- fine.

HAL_FLASHEx_OB_Program:

Properly ran that:

 

 

 

 else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
 {
 /* Only modify user so get current RDP level */
 optr = FLASH_OB_GetRDP();
 FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
 }

 

 

then, theres a problem with 

 

 

 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

 

 

let's get into. Program skips this if:

 

 

 /* Wait if any operation is ongoing */
#if defined(FLASH_DBANK_SUPPORT)
 error = (FLASH_SR_BSY1 | FLASH_SR_BSY2);
#else
 error = FLASH_SR_BSY1;
#endif /* FLASH_DBANK_SUPPORT */

 while ((FLASH->SR & error) != 0x00U)
 {
 if (HAL_GetTick() >= timeout)
 {
 return HAL_TIMEOUT;
 }
 }

 

 

 

then, before this:

 

 

 

 /* check flash errors */
 error = (FLASH->SR & FLASH_SR_ERRORS);

 /* Clear SR register */
 FLASH->SR = FLASH_SR_CLEAR;

 

 

FLASH->SR contains 1000000000010100000 whitch means CFGBSY, PGSERR and PGAERR exists. Then, program run:

 

 

 FLASH->SR = FLASH_SR_CLEAR;

 

 

clearing PGAERR, PGSERR, but bit 18(CFGBSY) is still set. Whitch causes enter in that if:

 

 

 if (error != 0x00U)
 {
 /*Save the error code*/
 pFlash.ErrorCode = error;
 return HAL_ERROR;
 }

 

 

 

and return HAL_ERROR by the 

 

 

FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);

 

 

whitch causes HAL_ERROR return from:

 

 

 

HAL_FLASHEx_OBProgram(&OB)

 

 

 

So, now program enter that if:

 

 

			 status = HAL_FLASH_Unlock();
			 status = HAL_FLASH_OB_Unlock();

			 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET);

			 status = HAL_FLASHEx_OBProgram(&OB);

			 if ( status != HAL_OK )
			 {
				 status = HAL_FLASH_OB_Lock();
				 status = HAL_FLASH_Lock();
				 return HAL_ERROR;
			 }

 

 

 

whitch causes HardFault_Handler running  SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK) here:

 

 

HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
{
 HAL_StatusTypeDef status = HAL_ERROR;

 /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
 SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);

 /* verify option bytes are locked */
 if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00u)
 {
 status = HAL_OK;
 }

 return status;
}

 

 

 

Whats going on? I was try to set proper wait state(before run optionByteSetBootFromPin();):

 

 

int main(void) {
	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_2);

	int latency = __HAL_FLASH_GET_LATENCY();

	optionByteSetBootFromPin();

 

 

and checked it, but nothing changed. 

I was try to run optionByteSetBootFromPin() after HAL_Init(), after SystemClock_Config(), and before main while loop in program- same effect.  

 

    This topic has been closed for replies.

    3 replies

    Super User
    December 5, 2023

    Check FLASH->SR at the start of the procedure. Those flags may be getting set from something the debugger is doing. If so, clear them.

    BPrac.1Author
    Graduate
    December 5, 2023

    Okay, you're right - these bits was set before run functions. But if i cleared that, program returns HAL_ERROR from second FLASH_WaitForLastOperation() in:

     

     

     

     }
    #endif /* FLASH_SECURABLE_MEMORY_SUPPORT */
    
     /* Wait for last operation to be completed */
     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    
     if (status == HAL_OK)
     {
     /* Set OPTSTRT Bit */
     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
    
     /* Wait for last operation to be completed */
     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
    
     /* If the option byte program operation is completed, disable the OPTSTRT Bit */
     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
     }
    
     /* Process Unlocked */
     __HAL_UNLOCK(&pFlash);
    
     /* return status */
     return status;
    }

     

     

     

    Also PGA and PGS....

    I checked when its was set to 1(these flags was cleared in prevous wait)- and it was set in this while loop in previous wait, whitch is chegking only 18th bit:

     

     

     

     while ((FLASH->SR & FLASH_SR_CFGBSY) != 0x00U)
     {
     if (HAL_GetTick() >= timeout)
     {
     return HAL_TIMEOUT;
     }
     }

     

     

    before loop:

    BPrac1_2-1701788017107.png

     

    after loop:

    BPrac1_3-1701788031358.png

     

     

     

    Graduate
    April 8, 2024

    Hi @BPrac.1 

    Have you found any solution/workaround for this issue? I am facing a similar problem with STM32G0B1.

    Visitor II
    May 27, 2025

    I'm having the exact same thing with an STM32F103.   I use the code described in "How to program STM32 Option Bytes with the HAL API", and it always fails in HAL_FLASHEx_OBProgram() -> FLASH_OB_UserConfig()  on the 2nd call to FLASH_WaitForLastOperation()  getting HAL_ERROR