2023-12-05 05:55 AM
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.
2023-12-05 06:13 AM
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.
2023-12-05 06:47 AM - edited 2023-12-05 06:53 AM
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:
after loop:
2024-04-08 12:21 AM
Hi @BPrac.1
Have you found any solution/workaround for this issue? I am facing a similar problem with STM32G0B1.