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; }
View more

 

 

 

 

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.  

 

3 REPLIES 3
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

 

 

 

 

Dthum.1
Associate III

Hi @BPrac.1 

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