/** * @brief Full erase of FLASH memory sectors * @param VoltageRange: The device voltage range which defines the erase parallelism. * This parameter can be one of the following values: * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, * the operation will be done by byte (8-bit) * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, * the operation will be done by half word (16-bit) * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, * the operation will be done by word (32-bit) * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, * the operation will be done by double word (64-bit) * * @param Banks: Banks to be erased * This parameter can be one of the following values: * @arg FLASH_BANK_1: Bank1 to be erased * @arg FLASH_BANK_2: Bank2 to be erased * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased * * @retval HAL Status */ static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks) { uint32_t tmp_psize = 0; /* Check the parameters */ assert_param(IS_VOLTAGERANGE(VoltageRange)); assert_param(IS_FLASH_BANK(Banks)); /* if the previous operation is completed, proceed to erase all sectors */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= tmp_psize; if(Banks == FLASH_BANK_BOTH) { /* bank1 & bank2 will be erased*/ FLASH->CR |= FLASH_MER_BIT; } else if(Banks == FLASH_BANK_1) { /*Only bank1 will be erased*/ FLASH->CR |= FLASH_CR_MER1; } else { /*Only bank2 will be erased*/ FLASH->CR |= FLASH_CR_MER2; } FLASH->CR |= FLASH_CR_STRT; }
/** * @brief Enable the write protection of the desired bank1 or bank 2 sectors * * @note When the memory read protection level is selected (RDP level = 1), * it is not possible to program or erase the flash sector i if CortexM4 * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 * @note Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1). * * @param WRPSector: specifies the sector(s) to be write protected. * This parameter can be one of the following values: * @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_23 * @arg OB_WRP_SECTOR_All * @note BANK2 starts from OB_WRP_SECTOR_12 * * @param Banks: Enable write protection on all the sectors for the specific bank * This parameter can be one of the following values: * @arg FLASH_BANK_1: WRP on all sectors of bank1 * @arg FLASH_BANK_2: WRP on all sectors of bank2 * @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2 * * @retval HAL FLASH State */ static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_OB_WRP_SECTOR(WRPSector)); assert_param(IS_FLASH_BANK(Banks)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { if(((WRPSector == OB_WRP_SECTOR_All) && ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))) || (WRPSector < OB_WRP_SECTOR_12)) { if(WRPSector == OB_WRP_SECTOR_All) { /*Write protection on all sector of BANK1*/ *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~(WRPSector>>12)); } else { /*Write protection done on sectors of BANK1*/ *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~WRPSector); } }
/** * @brief Full erase of FLASH memory Bank * @param Banks: Banks to be erased * This parameter can be one of the following values: * @arg FLASH_BANK_1: Bank1 to be erased * @arg FLASH_BANK_2: Bank2 to be erased * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased * * @retval None */ static void FLASH_MassErase(uint32_t Banks) { /* Check the parameters */ assert_param(IS_FLASH_BANK(Banks)); /* Clean the error context */ pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; #if defined(FLASH_BANK2_END) if(Banks == FLASH_BANK_BOTH) { /* bank1 & bank2 will be erased*/ SET_BIT(FLASH->CR, FLASH_CR_MER); SET_BIT(FLASH->CR2, FLASH_CR2_MER); SET_BIT(FLASH->CR, FLASH_CR_STRT); SET_BIT(FLASH->CR2, FLASH_CR2_STRT); } else if(Banks == FLASH_BANK_2) { /*Only bank2 will be erased*/ SET_BIT(FLASH->CR2, FLASH_CR2_MER); SET_BIT(FLASH->CR2, FLASH_CR2_STRT); } else { #endif /* FLASH_BANK2_END */ /* Only bank1 will be erased*/ SET_BIT(FLASH->CR, FLASH_CR_MER); SET_BIT(FLASH->CR, FLASH_CR_STRT); #if defined(FLASH_BANK2_END) } #endif /* FLASH_BANK2_END */ }
/** * @brief Mass erase of FLASH memory * @param VoltageRange: The device voltage range which defines the erase parallelism. * This parameter can be one of the following values: * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, * the operation will be done by byte (8-bit) * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, * the operation will be done by half word (16-bit) * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, * the operation will be done by word (32-bit) * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, * the operation will be done by double word (64-bit) * * @param Banks: Banks to be erased * This parameter can be one of the following values: * @arg FLASH_BANK_1: Bank1 to be erased * * @retval None */ static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks) { uint32_t tmp_psize = 0; /* Check the parameters */ assert_param(IS_VOLTAGERANGE(VoltageRange)); assert_param(IS_FLASH_BANK(Banks)); /* If the previous operation is completed, proceed to erase all sectors */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= tmp_psize; FLASH->CR |= FLASH_CR_MER; FLASH->CR |= FLASH_CR_STRT; }
/** * @brief Enable the write protection of the desired bank1 or bank 2 sectors * @param WRPSector specifies the sector(s) to be write protected. * This parameter can be one of the following values: * @arg WRPSector: A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_0 or OB_WRP_SECTOR_All * * @param Banks the specific bank to apply WRP sectors * This parameter can be one of the following values: * @arg FLASH_BANK_1: WRP enable on specified bank1 sectors * @arg FLASH_BANK_2: WRP enable on specified bank2 sectors * @arg FLASH_BANK_BOTH: WRP enable bank1 and bank2 specified sectors * * @retval HAL FLASH State */ static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_FLASH_BANK(Banks)); if((Banks & FLASH_BANK_1) == FLASH_BANK_1) { assert_param(IS_OB_WRP_SECTOR(WRPSector)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); if(status == HAL_OK) { FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN)); } } if((Banks & FLASH_BANK_2) == FLASH_BANK_2) { assert_param(IS_OB_WRP_SECTOR(WRPSector)); /* Wait for last operation to be completed */ status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); if(status == HAL_OK) { FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN)); } } if((Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* Wait for last operation to be completed */ status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); } if((Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* Wait for last operation to be completed */ status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); } return status; }
/** * @brief Disable the write protection of the desired bank 1 sectors * * @note When the memory read protection level is selected (RDP level = 1), * it is not possible to program or erase the flash sector if CortexM3 * debug features are connected or boot code is executed in RAM, even if nWRPi = 1 * * @param WRPSector: specifies the sector(s) to be write protected. * The value of this parameter depend on device used within the same series * * @param Banks: Enable write protection on all the sectors for the specific bank * This parameter can be one of the following values: * @arg FLASH_BANK_1: WRP on all sectors of bank1 * * @retval HAL Status */ static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_OB_WRP_SECTOR(WRPSector)); assert_param(IS_FLASH_BANK(Banks)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); if(status == HAL_OK) { *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector; } return status; }
/** * @brief Full erase of FLASH memory sectors * @param VoltageRange The device program/erase parallelism. * This parameter can be one of the following values: * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits * * @param Banks Banks to be erased * This parameter can be one of the following values: * @arg FLASH_BANK_1: Bank1 to be erased * @arg FLASH_BANK_2: Bank2 to be erased * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased * * @retval HAL Status */ static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks) { /* Check the parameters */ assert_param(IS_FLASH_BANK(Banks)); assert_param(IS_VOLTAGERANGE(VoltageRange)); /* Flash Mass Erase */ if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH) { /* reset Program/erase VoltageRange for Bank1 */ FLASH->CR1 &= (~FLASH_CR_PSIZE); /* Bank1 will be erased, and set voltage range*/ FLASH->CR1 |= FLASH_CR_BER | VoltageRange; FLASH->OPTCR |= FLASH_OPTCR_MER; } else { /* Proceed to erase Flash Bank */ if((Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* reset Program/erase VoltageRange for Bank1 */ FLASH->CR1 &= (~FLASH_CR_PSIZE); /* Bank1 will be erased, and set voltage range*/ FLASH->CR1 |= FLASH_CR_BER | VoltageRange; FLASH->CR1 |= FLASH_CR_START; } if((Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* reset Program/erase VoltageRange for Bank2 */ FLASH->CR2 &= (~FLASH_CR_PSIZE); /* Bank2 will be erased, and set voltage range*/ FLASH->CR2 |= FLASH_CR_BER | VoltageRange; FLASH->CR2 |= FLASH_CR_START; } } }
/** * @brief Program option bytes * @param pOBInit pointer to an FLASH_OBInitStruct structure that * contains the configuration information for the programming. * * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit) { HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_OPTIONBYTE(pOBInit->OptionType)); pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; /*Write protection configuration*/ if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP) { assert_param(IS_WRPSTATE(pOBInit->WRPState)); assert_param(IS_FLASH_BANK(pOBInit->Banks)); if(pOBInit->WRPState == OB_WRPSTATE_ENABLE) { /*Enable of Write protection on the selected Sector*/ status = FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks); } else { /*Disable of Write protection on the selected Sector*/ status = FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks); } if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /* Read protection configuration */ if((pOBInit->OptionType & OPTIONBYTE_RDP) != RESET) { /* Configure the Read protection level */ status = FLASH_OB_RDPConfig(pOBInit->RDPLevel); if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /* User Configuration */ if((pOBInit->OptionType & OPTIONBYTE_USER) != RESET) { /* Configure the user option bytes */ status = FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig); if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /* PCROP Configuration */ if((pOBInit->OptionType & OPTIONBYTE_PCROP) != RESET) { assert_param(IS_FLASH_BANK(pOBInit->Banks)); /*Configure the Proprietary code readout protection */ status = FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks); if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /*BOR Level configuration*/ if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR) { status = FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel); if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /*Boot Address configuration*/ if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD) { status = FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1); if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /*Bank1 secure area configuration*/ if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA) { status = FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks); if(status != HAL_OK) { /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }
/** * @brief Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled * @param pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit) { HAL_StatusTypeDef status = HAL_OK; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); assert_param(IS_VOLTAGERANGE(pEraseInit->VoltageRange)); assert_param(IS_FLASH_BANK(pEraseInit->Banks)); if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* Clear bank 1 pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK1); /* Enable End of Operation and Error interrupts for Bank 1 */ __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1 | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \ FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* Clear bank 2 pending flags (if any) */ __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2 | FLASH_FLAG_ALL_ERRORS_BANK2); /* Enable End of Operation and Error interrupts for Bank 2 */ __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2 | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \ FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2); } if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ if(pEraseInit->Banks == FLASH_BANK_1) { pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1; } else if(pEraseInit->Banks == FLASH_BANK_2) { pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2; } else { pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE; } FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); } else { /* Erase by sector to be done*/ /* Check the parameters */ assert_param(IS_FLASH_BANK_EXCLUSIVE(pEraseInit->Banks)); assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); if(pEraseInit->Banks == FLASH_BANK_1) { pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1; } else { pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2; } pFlash.NbSectorsToErase = pEraseInit->NbSectors; pFlash.Sector = pEraseInit->Sector; pFlash.VoltageForErase = pEraseInit->VoltageRange; /*Erase 1st sector and wait for IT*/ FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange); } return status; }
/** * @brief Perform a mass erase or erase the specified FLASH memory sectors * @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that * contains the configuration information for the erasing. * * @param[out] SectorError pointer to variable that * contains the configuration information on faulty sector in case of error * (0xFFFFFFFF means that all the sectors have been correctly erased) * * @retval HAL Status */ HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError) { HAL_StatusTypeDef status = HAL_OK; uint32_t index = 0; /* Process Locked */ __HAL_LOCK(&pFlash); /* Check the parameters */ assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase)); assert_param(IS_VOLTAGERANGE(pEraseInit->VoltageRange)); assert_param(IS_FLASH_BANK(pEraseInit->Banks)); /* Wait for last operation to be completed */ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); } if(status == HAL_OK) { /*Initialization of SectorError variable*/ *SectorError = 0xFFFFFFFF; if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE) { /*Mass erase to be done*/ FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks); /* Wait for last operation to be completed */ if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); /* if the erase operation is completed, disable the Bank1 BER Bit */ FLASH->CR1 &= (~FLASH_CR_BER); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { status |= FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); /* if the erase operation is completed, disable the Bank2 BER Bit */ FLASH->CR2 &= (~FLASH_CR_BER); } } else { /* Check the parameters */ assert_param(IS_FLASH_BANK_EXCLUSIVE(pEraseInit->Banks)); assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector)); /* Erase by sector by sector to be done*/ for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++) { FLASH_Erase_Sector(index, pEraseInit->Banks, pEraseInit->VoltageRange); if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1); /* If the erase operation is completed, disable the SER Bit */ FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); } if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2); /* If the erase operation is completed, disable the SER Bit */ FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB)); } if(status != HAL_OK) { /* In case of error, stop erase procedure and return the faulty sector*/ *SectorError = index; break; } } } } /* Process Unlocked */ __HAL_UNLOCK(&pFlash); return status; }