cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with option bytes set from program level- G0B1

BPrac.1
Associate II

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.  

 

2 REPLIES 2
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".

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