STM32F479xx HAL User Manual
stm32f4xx_hal_flash_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_flash_ex.c
00004   * @author  MCD Application Team
00005   * @brief   Extended FLASH HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the FLASH extension peripheral:
00008   *           + Extended programming operations functions
00009   *
00010   @verbatim
00011   ==============================================================================
00012                    ##### Flash Extension features #####
00013   ==============================================================================
00014 
00015   [..] Comparing to other previous devices, the FLASH interface for STM32F427xx/437xx and
00016        STM32F429xx/439xx devices contains the following additional features
00017 
00018        (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write
00019            capability (RWW)
00020        (+) Dual bank memory organization
00021        (+) PCROP protection for all banks
00022 
00023                       ##### How to use this driver #####
00024   ==============================================================================
00025   [..] This driver provides functions to configure and program the FLASH memory
00026        of all STM32F427xx/437xx, STM32F429xx/439xx, STM32F469xx/479xx and STM32F446xx
00027        devices. It includes
00028       (#) FLASH Memory Erase functions:
00029            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
00030                 HAL_FLASH_Lock() functions
00031            (++) Erase function: Erase sector, erase all sectors
00032            (++) There are two modes of erase :
00033              (+++) Polling Mode using HAL_FLASHEx_Erase()
00034              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
00035 
00036       (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to :
00037            (++) Set/Reset the write protection
00038            (++) Set the Read protection Level
00039            (++) Set the BOR level
00040            (++) Program the user Option Bytes
00041       (#) Advanced Option Bytes Programming functions: Use HAL_FLASHEx_AdvOBProgram() to :
00042        (++) Extended space (bank 2) erase function
00043        (++) Full FLASH space (2 Mo) erase (bank 1 and bank 2)
00044        (++) Dual Boot activation
00045        (++) Write protection configuration for bank 2
00046        (++) PCROP protection configuration and control for both banks
00047 
00048   @endverbatim
00049   ******************************************************************************
00050   * @attention
00051   *
00052   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
00053   * All rights reserved.</center></h2>
00054   *
00055   * This software component is licensed by ST under BSD 3-Clause license,
00056   * the "License"; You may not use this file except in compliance with the
00057   * License. You may obtain a copy of the License at:
00058   *                        opensource.org/licenses/BSD-3-Clause
00059   *
00060   ******************************************************************************
00061   */
00062 
00063 /* Includes ------------------------------------------------------------------*/
00064 #include "stm32f4xx_hal.h"
00065 
00066 /** @addtogroup STM32F4xx_HAL_Driver
00067   * @{
00068   */
00069 
00070 /** @defgroup FLASHEx FLASHEx
00071   * @brief FLASH HAL Extension module driver
00072   * @{
00073   */
00074 
00075 #ifdef HAL_FLASH_MODULE_ENABLED
00076 
00077 /* Private typedef -----------------------------------------------------------*/
00078 /* Private define ------------------------------------------------------------*/
00079 /** @addtogroup FLASHEx_Private_Constants
00080   * @{
00081   */
00082 #define FLASH_TIMEOUT_VALUE       50000U /* 50 s */
00083 /**
00084   * @}
00085   */
00086 
00087 /* Private macro -------------------------------------------------------------*/
00088 /* Private variables ---------------------------------------------------------*/
00089 /** @addtogroup FLASHEx_Private_Variables
00090   * @{
00091   */
00092 extern FLASH_ProcessTypeDef pFlash;
00093 /**
00094   * @}
00095   */
00096 
00097 /* Private function prototypes -----------------------------------------------*/
00098 /** @addtogroup FLASHEx_Private_Functions
00099   * @{
00100   */
00101 /* Option bytes control */
00102 static void               FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks);
00103 static HAL_StatusTypeDef  FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks);
00104 static HAL_StatusTypeDef  FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks);
00105 static HAL_StatusTypeDef  FLASH_OB_RDP_LevelConfig(uint8_t Level);
00106 static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint8_t Iwdg, uint8_t Stop, uint8_t Stdby);
00107 static HAL_StatusTypeDef  FLASH_OB_BOR_LevelConfig(uint8_t Level);
00108 static uint8_t            FLASH_OB_GetUser(void);
00109 static uint16_t           FLASH_OB_GetWRP(void);
00110 static uint8_t            FLASH_OB_GetRDP(void);
00111 static uint8_t            FLASH_OB_GetBOR(void);
00112 
00113 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) ||\
00114     defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||\
00115     defined(STM32F423xx)
00116 static HAL_StatusTypeDef  FLASH_OB_EnablePCROP(uint32_t Sector);
00117 static HAL_StatusTypeDef  FLASH_OB_DisablePCROP(uint32_t Sector);
00118 #endif /* STM32F401xC || STM32F401xE || STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx
00119           STM32F413xx || STM32F423xx */
00120 
00121 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
00122 static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks);
00123 static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks);
00124 static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t BootConfig);
00125 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
00126 
00127 extern HAL_StatusTypeDef         FLASH_WaitForLastOperation(uint32_t Timeout);
00128 /**
00129   * @}
00130   */
00131 
00132 /* Exported functions --------------------------------------------------------*/
00133 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
00134   * @{
00135   */
00136 
00137 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
00138  *  @brief   Extended IO operation functions
00139  *
00140 @verbatim
00141  ===============================================================================
00142                 ##### Extended programming operation functions #####
00143  ===============================================================================
00144     [..]
00145     This subsection provides a set of functions allowing to manage the Extension FLASH
00146     programming operations.
00147 
00148 @endverbatim
00149   * @{
00150   */
00151 /**
00152   * @brief  Perform a mass erase or erase the specified FLASH memory sectors
00153   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
00154   *         contains the configuration information for the erasing.
00155   *
00156   * @param[out]  SectorError pointer to variable  that
00157   *         contains the configuration information on faulty sector in case of error
00158   *         (0xFFFFFFFFU means that all the sectors have been correctly erased)
00159   *
00160   * @retval HAL Status
00161   */
00162 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
00163 {
00164   HAL_StatusTypeDef status = HAL_ERROR;
00165   uint32_t index = 0U;
00166 
00167   /* Process Locked */
00168   __HAL_LOCK(&pFlash);
00169 
00170   /* Check the parameters */
00171   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
00172 
00173   /* Wait for last operation to be completed */
00174   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00175 
00176   if (status == HAL_OK)
00177   {
00178     /*Initialization of SectorError variable*/
00179     *SectorError = 0xFFFFFFFFU;
00180 
00181     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
00182     {
00183       /*Mass erase to be done*/
00184       FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
00185 
00186       /* Wait for last operation to be completed */
00187       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00188 
00189       /* if the erase operation is completed, disable the MER Bit */
00190       FLASH->CR &= (~FLASH_MER_BIT);
00191     }
00192     else
00193     {
00194       /* Check the parameters */
00195       assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));
00196 
00197       /* Erase by sector by sector to be done*/
00198       for (index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++)
00199       {
00200         FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange);
00201 
00202         /* Wait for last operation to be completed */
00203         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00204 
00205         /* If the erase operation is completed, disable the SER and SNB Bits */
00206         CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB));
00207 
00208         if (status != HAL_OK)
00209         {
00210           /* In case of error, stop erase procedure and return the faulty sector*/
00211           *SectorError = index;
00212           break;
00213         }
00214       }
00215     }
00216     /* Flush the caches to be sure of the data consistency */
00217     FLASH_FlushCaches();
00218   }
00219 
00220   /* Process Unlocked */
00221   __HAL_UNLOCK(&pFlash);
00222 
00223   return status;
00224 }
00225 
00226 /**
00227   * @brief  Perform a mass erase or erase the specified FLASH memory sectors  with interrupt enabled
00228   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
00229   *         contains the configuration information for the erasing.
00230   *
00231   * @retval HAL Status
00232   */
00233 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
00234 {
00235   HAL_StatusTypeDef status = HAL_OK;
00236 
00237   /* Process Locked */
00238   __HAL_LOCK(&pFlash);
00239 
00240   /* Check the parameters */
00241   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
00242 
00243   /* Enable End of FLASH Operation interrupt */
00244   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
00245 
00246   /* Enable Error source interrupt */
00247   __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
00248 
00249   /* Clear pending flags (if any) */
00250   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
00251                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
00252 
00253   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
00254   {
00255     /*Mass erase to be done*/
00256     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
00257     pFlash.Bank = pEraseInit->Banks;
00258     FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
00259   }
00260   else
00261   {
00262     /* Erase by sector to be done*/
00263 
00264     /* Check the parameters */
00265     assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));
00266 
00267     pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE;
00268     pFlash.NbSectorsToErase = pEraseInit->NbSectors;
00269     pFlash.Sector = pEraseInit->Sector;
00270     pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange;
00271 
00272     /*Erase 1st sector and wait for IT*/
00273     FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange);
00274   }
00275 
00276   return status;
00277 }
00278 
00279 /**
00280   * @brief   Program option bytes
00281   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
00282   *         contains the configuration information for the programming.
00283   *
00284   * @retval HAL Status
00285   */
00286 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
00287 {
00288   HAL_StatusTypeDef status = HAL_ERROR;
00289 
00290   /* Process Locked */
00291   __HAL_LOCK(&pFlash);
00292 
00293   /* Check the parameters */
00294   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
00295 
00296   /*Write protection configuration*/
00297   if ((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
00298   {
00299     assert_param(IS_WRPSTATE(pOBInit->WRPState));
00300     if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
00301     {
00302       /*Enable of Write protection on the selected Sector*/
00303       status = FLASH_OB_EnableWRP(pOBInit->WRPSector, pOBInit->Banks);
00304     }
00305     else
00306     {
00307       /*Disable of Write protection on the selected Sector*/
00308       status = FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks);
00309     }
00310   }
00311 
00312   /*Read protection configuration*/
00313   if ((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
00314   {
00315     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
00316   }
00317 
00318   /*USER  configuration*/
00319   if ((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
00320   {
00321     status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_IWDG_SW,
00322                                  pOBInit->USERConfig & OB_STOP_NO_RST,
00323                                  pOBInit->USERConfig & OB_STDBY_NO_RST);
00324   }
00325 
00326   /*BOR Level  configuration*/
00327   if ((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
00328   {
00329     status = FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
00330   }
00331 
00332   /* Process Unlocked */
00333   __HAL_UNLOCK(&pFlash);
00334 
00335   return status;
00336 }
00337 
00338 /**
00339   * @brief   Get the Option byte configuration
00340   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
00341   *         contains the configuration information for the programming.
00342   *
00343   * @retval None
00344   */
00345 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
00346 {
00347   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR;
00348 
00349   /*Get WRP*/
00350   pOBInit->WRPSector = (uint32_t)FLASH_OB_GetWRP();
00351 
00352   /*Get RDP Level*/
00353   pOBInit->RDPLevel = (uint32_t)FLASH_OB_GetRDP();
00354 
00355   /*Get USER*/
00356   pOBInit->USERConfig = (uint8_t)FLASH_OB_GetUser();
00357 
00358   /*Get BOR Level*/
00359   pOBInit->BORLevel = (uint32_t)FLASH_OB_GetBOR();
00360 }
00361 
00362 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
00363     defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) ||\
00364     defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) ||\
00365     defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||\
00366     defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00367 /**
00368   * @brief   Program option bytes
00369   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
00370   *         contains the configuration information for the programming.
00371   *
00372   * @retval HAL Status
00373   */
00374 HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
00375 {
00376   HAL_StatusTypeDef status = HAL_ERROR;
00377 
00378   /* Check the parameters */
00379   assert_param(IS_OBEX(pAdvOBInit->OptionType));
00380 
00381   /*Program PCROP option byte*/
00382   if (((pAdvOBInit->OptionType) & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP)
00383   {
00384     /* Check the parameters */
00385     assert_param(IS_PCROPSTATE(pAdvOBInit->PCROPState));
00386     if ((pAdvOBInit->PCROPState) == OB_PCROP_STATE_ENABLE)
00387     {
00388       /*Enable of Write protection on the selected Sector*/
00389 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
00390     defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||\
00391     defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00392       status = FLASH_OB_EnablePCROP(pAdvOBInit->Sectors);
00393 #else  /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx || STM32F469xx || STM32F479xx */
00394       status = FLASH_OB_EnablePCROP(pAdvOBInit->SectorsBank1, pAdvOBInit->SectorsBank2, pAdvOBInit->Banks);
00395 #endif /* STM32F401xC || STM32F401xE || STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx ||
00396           STM32F413xx || STM32F423xx */
00397     }
00398     else
00399     {
00400       /*Disable of Write protection on the selected Sector*/
00401 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
00402     defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||\
00403     defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00404       status = FLASH_OB_DisablePCROP(pAdvOBInit->Sectors);
00405 #else /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx || STM32F469xx || STM32F479xx */
00406       status = FLASH_OB_DisablePCROP(pAdvOBInit->SectorsBank1, pAdvOBInit->SectorsBank2, pAdvOBInit->Banks);
00407 #endif /* STM32F401xC || STM32F401xE || STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx ||
00408           STM32F413xx || STM32F423xx */
00409     }
00410   }
00411 
00412 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
00413   /*Program BOOT config option byte*/
00414   if (((pAdvOBInit->OptionType) & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG)
00415   {
00416     status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig);
00417   }
00418 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
00419 
00420   return status;
00421 }
00422 
00423 /**
00424   * @brief   Get the OBEX byte configuration
00425   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
00426   *         contains the configuration information for the programming.
00427   *
00428   * @retval None
00429   */
00430 void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
00431 {
00432 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
00433     defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||\
00434     defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
00435   /*Get Sector*/
00436   pAdvOBInit->Sectors = (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
00437 #else  /* STM32F427xx || STM32F437xx || STM32F429xx|| STM32F439xx || STM32F469xx || STM32F479xx */
00438   /*Get Sector for Bank1*/
00439   pAdvOBInit->SectorsBank1 = (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
00440 
00441   /*Get Sector for Bank2*/
00442   pAdvOBInit->SectorsBank2 = (*(__IO uint16_t *)(OPTCR1_BYTE2_ADDRESS));
00443 
00444   /*Get Boot config OB*/
00445   pAdvOBInit->BootConfig = *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS;
00446 #endif /* STM32F401xC || STM32F401xE || STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx ||
00447           STM32F413xx || STM32F423xx */
00448 }
00449 
00450 /**
00451   * @brief  Select the Protection Mode
00452   *
00453   * @note   After PCROP activated Option Byte modification NOT POSSIBLE! excepted
00454   *         Global Read Out Protection modification (from level1 to level0)
00455   * @note   Once SPRMOD bit is active unprotection of a protected sector is not possible
00456   * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
00457   * @note   This function can be used only for STM32F42xxx/STM32F43xxx/STM32F401xx/STM32F411xx/STM32F446xx/
00458   *         STM32F469xx/STM32F479xx/STM32F412xx/STM32F413xx devices.
00459   *
00460   * @retval HAL Status
00461   */
00462 HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void)
00463 {
00464   uint8_t optiontmp = 0xFF;
00465 
00466   /* Mask SPRMOD bit */
00467   optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE3_ADDRESS) & (uint8_t)0x7F);
00468 
00469   /* Update Option Byte */
00470   *(__IO uint8_t *)OPTCR_BYTE3_ADDRESS = (uint8_t)(OB_PCROP_SELECTED | optiontmp);
00471 
00472   return HAL_OK;
00473 }
00474 
00475 /**
00476   * @brief  Deselect the Protection Mode
00477   *
00478   * @note   After PCROP activated Option Byte modification NOT POSSIBLE! excepted
00479   *         Global Read Out Protection modification (from level1 to level0)
00480   * @note   Once SPRMOD bit is active unprotection of a protected sector is not possible
00481   * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
00482   * @note   This function can be used only for STM32F42xxx/STM32F43xxx/STM32F401xx/STM32F411xx/STM32F446xx/
00483   *         STM32F469xx/STM32F479xx/STM32F412xx/STM32F413xx devices.
00484   *
00485   * @retval HAL Status
00486   */
00487 HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void)
00488 {
00489   uint8_t optiontmp = 0xFF;
00490 
00491   /* Mask SPRMOD bit */
00492   optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE3_ADDRESS) & (uint8_t)0x7F);
00493 
00494   /* Update Option Byte */
00495   *(__IO uint8_t *)OPTCR_BYTE3_ADDRESS = (uint8_t)(OB_PCROP_DESELECTED | optiontmp);
00496 
00497   return HAL_OK;
00498 }
00499 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F401xC || STM32F401xE || STM32F410xx ||\
00500           STM32F411xE || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx ||
00501           STM32F413xx || STM32F423xx */
00502 
00503 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
00504 /**
00505   * @brief  Returns the FLASH Write Protection Option Bytes value for Bank 2
00506   * @note   This function can be used only for STM32F42xxx/STM32F43xxx/STM32F469xx/STM32F479xx devices.
00507   * @retval The FLASH Write Protection  Option Bytes value
00508   */
00509 uint16_t HAL_FLASHEx_OB_GetBank2WRP(void)
00510 {
00511   /* Return the FLASH write protection Register value */
00512   return (*(__IO uint16_t *)(OPTCR1_BYTE2_ADDRESS));
00513 }
00514 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
00515 
00516 /**
00517   * @}
00518   */
00519 
00520 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
00521 /**
00522   * @brief  Full erase of FLASH memory sectors
00523   * @param  VoltageRange The device voltage range which defines the erase parallelism.
00524   *          This parameter can be one of the following values:
00525   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
00526   *                                  the operation will be done by byte (8-bit)
00527   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
00528   *                                  the operation will be done by half word (16-bit)
00529   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
00530   *                                  the operation will be done by word (32-bit)
00531   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
00532   *                                  the operation will be done by double word (64-bit)
00533   *
00534   * @param  Banks Banks to be erased
00535   *          This parameter can be one of the following values:
00536   *            @arg FLASH_BANK_1: Bank1 to be erased
00537   *            @arg FLASH_BANK_2: Bank2 to be erased
00538   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
00539   *
00540   * @retval HAL Status
00541   */
00542 static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks)
00543 {
00544   /* Check the parameters */
00545   assert_param(IS_VOLTAGERANGE(VoltageRange));
00546   assert_param(IS_FLASH_BANK(Banks));
00547 
00548   /* if the previous operation is completed, proceed to erase all sectors */
00549   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00550 
00551   if (Banks == FLASH_BANK_BOTH)
00552   {
00553     /* bank1 & bank2 will be erased*/
00554     FLASH->CR |= FLASH_MER_BIT;
00555   }
00556   else if (Banks == FLASH_BANK_1)
00557   {
00558     /*Only bank1 will be erased*/
00559     FLASH->CR |= FLASH_CR_MER1;
00560   }
00561   else
00562   {
00563     /*Only bank2 will be erased*/
00564     FLASH->CR |= FLASH_CR_MER2;
00565   }
00566   FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange << 8U);
00567 }
00568 
00569 /**
00570   * @brief  Erase the specified FLASH memory sector
00571   * @param  Sector FLASH sector to erase
00572   *         The value of this parameter depend on device used within the same series
00573   * @param  VoltageRange The device voltage range which defines the erase parallelism.
00574   *          This parameter can be one of the following values:
00575   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
00576   *                                  the operation will be done by byte (8-bit)
00577   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
00578   *                                  the operation will be done by half word (16-bit)
00579   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
00580   *                                  the operation will be done by word (32-bit)
00581   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
00582   *                                  the operation will be done by double word (64-bit)
00583   *
00584   * @retval None
00585   */
00586 void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
00587 {
00588   uint32_t tmp_psize = 0U;
00589 
00590   /* Check the parameters */
00591   assert_param(IS_FLASH_SECTOR(Sector));
00592   assert_param(IS_VOLTAGERANGE(VoltageRange));
00593 
00594   if (VoltageRange == FLASH_VOLTAGE_RANGE_1)
00595   {
00596     tmp_psize = FLASH_PSIZE_BYTE;
00597   }
00598   else if (VoltageRange == FLASH_VOLTAGE_RANGE_2)
00599   {
00600     tmp_psize = FLASH_PSIZE_HALF_WORD;
00601   }
00602   else if (VoltageRange == FLASH_VOLTAGE_RANGE_3)
00603   {
00604     tmp_psize = FLASH_PSIZE_WORD;
00605   }
00606   else
00607   {
00608     tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
00609   }
00610 
00611   /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */
00612   if (Sector > FLASH_SECTOR_11)
00613   {
00614     Sector += 4U;
00615   }
00616   /* If the previous operation is completed, proceed to erase the sector */
00617   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00618   FLASH->CR |= tmp_psize;
00619   CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
00620   FLASH->CR |= FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos);
00621   FLASH->CR |= FLASH_CR_STRT;
00622 }
00623 
00624 /**
00625   * @brief  Enable the write protection of the desired bank1 or bank 2 sectors
00626   *
00627   * @note   When the memory read protection level is selected (RDP level = 1),
00628   *         it is not possible to program or erase the flash sector i if CortexM4
00629   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
00630   * @note   Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1).
00631   *
00632   * @param  WRPSector specifies the sector(s) to be write protected.
00633   *          This parameter can be one of the following values:
00634   *            @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_23
00635   *            @arg OB_WRP_SECTOR_All
00636   * @note   BANK2 starts from OB_WRP_SECTOR_12
00637   *
00638   * @param  Banks Enable write protection on all the sectors for the specific bank
00639   *          This parameter can be one of the following values:
00640   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
00641   *            @arg FLASH_BANK_2: WRP on all sectors of bank2
00642   *            @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2
00643   *
00644   * @retval HAL FLASH State
00645   */
00646 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
00647 {
00648   HAL_StatusTypeDef status = HAL_OK;
00649 
00650   /* Check the parameters */
00651   assert_param(IS_OB_WRP_SECTOR(WRPSector));
00652   assert_param(IS_FLASH_BANK(Banks));
00653 
00654   /* Wait for last operation to be completed */
00655   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00656 
00657   if (status == HAL_OK)
00658   {
00659     if (((WRPSector == OB_WRP_SECTOR_All) && ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))) ||
00660         (WRPSector < OB_WRP_SECTOR_12))
00661     {
00662       if (WRPSector == OB_WRP_SECTOR_All)
00663       {
00664         /*Write protection on all sector of BANK1*/
00665         *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS &= (~(WRPSector >> 12));
00666       }
00667       else
00668       {
00669         /*Write protection done on sectors of BANK1*/
00670         *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS &= (~WRPSector);
00671       }
00672     }
00673     else
00674     {
00675       /*Write protection done on sectors of BANK2*/
00676       *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS &= (~(WRPSector >> 12));
00677     }
00678 
00679     /*Write protection on all sector of BANK2*/
00680     if ((WRPSector == OB_WRP_SECTOR_All) && (Banks == FLASH_BANK_BOTH))
00681     {
00682       /* Wait for last operation to be completed */
00683       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00684 
00685       if (status == HAL_OK)
00686       {
00687         *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS &= (~(WRPSector >> 12));
00688       }
00689     }
00690 
00691   }
00692   return status;
00693 }
00694 
00695 /**
00696   * @brief  Disable the write protection of the desired bank1 or bank 2 sectors
00697   *
00698   * @note   When the memory read protection level is selected (RDP level = 1),
00699   *         it is not possible to program or erase the flash sector i if CortexM4
00700   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
00701   * @note   Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1).
00702   *
00703   * @param  WRPSector specifies the sector(s) to be write protected.
00704   *          This parameter can be one of the following values:
00705   *            @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_23
00706   *            @arg OB_WRP_Sector_All
00707   * @note   BANK2 starts from OB_WRP_SECTOR_12
00708   *
00709   * @param  Banks Disable write protection on all the sectors for the specific bank
00710   *          This parameter can be one of the following values:
00711   *            @arg FLASH_BANK_1: Bank1 to be erased
00712   *            @arg FLASH_BANK_2: Bank2 to be erased
00713   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
00714   *
00715   * @retval HAL Status
00716   */
00717 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
00718 {
00719   HAL_StatusTypeDef status = HAL_OK;
00720 
00721   /* Check the parameters */
00722   assert_param(IS_OB_WRP_SECTOR(WRPSector));
00723   assert_param(IS_FLASH_BANK(Banks));
00724 
00725   /* Wait for last operation to be completed */
00726   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00727 
00728   if (status == HAL_OK)
00729   {
00730     if (((WRPSector == OB_WRP_SECTOR_All) && ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))) ||
00731         (WRPSector < OB_WRP_SECTOR_12))
00732     {
00733       if (WRPSector == OB_WRP_SECTOR_All)
00734       {
00735         /*Write protection on all sector of BANK1*/
00736         *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS |= (uint16_t)(WRPSector >> 12);
00737       }
00738       else
00739       {
00740         /*Write protection done on sectors of BANK1*/
00741         *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector;
00742       }
00743     }
00744     else
00745     {
00746       /*Write protection done on sectors of BANK2*/
00747       *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS |= (uint16_t)(WRPSector >> 12);
00748     }
00749 
00750     /*Write protection on all sector  of BANK2*/
00751     if ((WRPSector == OB_WRP_SECTOR_All) && (Banks == FLASH_BANK_BOTH))
00752     {
00753       /* Wait for last operation to be completed */
00754       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00755 
00756       if (status == HAL_OK)
00757       {
00758         *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS |= (uint16_t)(WRPSector >> 12);
00759       }
00760     }
00761 
00762   }
00763 
00764   return status;
00765 }
00766 
00767 /**
00768   * @brief  Configure the Dual Bank Boot.
00769   *
00770   * @note   This function can be used only for STM32F42xxx/43xxx devices.
00771   *
00772   * @param  BootConfig specifies the Dual Bank Boot Option byte.
00773   *          This parameter can be one of the following values:
00774   *            @arg OB_Dual_BootEnabled: Dual Bank Boot Enable
00775   *            @arg OB_Dual_BootDisabled: Dual Bank Boot Disabled
00776   * @retval None
00777   */
00778 static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t BootConfig)
00779 {
00780   HAL_StatusTypeDef status = HAL_OK;
00781 
00782   /* Check the parameters */
00783   assert_param(IS_OB_BOOT(BootConfig));
00784 
00785   /* Wait for last operation to be completed */
00786   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00787 
00788   if (status == HAL_OK)
00789   {
00790     /* Set Dual Bank Boot */
00791     *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BFB2);
00792     *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= BootConfig;
00793   }
00794 
00795   return status;
00796 }
00797 
00798 /**
00799   * @brief  Enable the read/write protection (PCROP) of the desired
00800   *         sectors of Bank 1 and/or Bank 2.
00801   * @note   This function can be used only for STM32F42xxx/43xxx devices.
00802   * @param  SectorBank1 Specifies the sector(s) to be read/write protected or unprotected for bank1.
00803   *          This parameter can be one of the following values:
00804   *            @arg OB_PCROP: A value between OB_PCROP_SECTOR_0 and OB_PCROP_SECTOR_11
00805   *            @arg OB_PCROP_SECTOR__All
00806   * @param  SectorBank2 Specifies the sector(s) to be read/write protected or unprotected for bank2.
00807   *          This parameter can be one of the following values:
00808   *            @arg OB_PCROP: A value between OB_PCROP_SECTOR_12 and OB_PCROP_SECTOR_23
00809   *            @arg OB_PCROP_SECTOR__All
00810   * @param  Banks Enable PCROP protection on all the sectors for the specific bank
00811   *          This parameter can be one of the following values:
00812   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
00813   *            @arg FLASH_BANK_2: WRP on all sectors of bank2
00814   *            @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2
00815   *
00816   * @retval HAL Status
00817   */
00818 static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks)
00819 {
00820   HAL_StatusTypeDef status = HAL_OK;
00821 
00822   assert_param(IS_FLASH_BANK(Banks));
00823 
00824   /* Wait for last operation to be completed */
00825   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00826 
00827   if (status == HAL_OK)
00828   {
00829     if ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))
00830     {
00831       assert_param(IS_OB_PCROP(SectorBank1));
00832       /*Write protection done on sectors of BANK1*/
00833       *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS |= (uint16_t)SectorBank1;
00834     }
00835     else
00836     {
00837       assert_param(IS_OB_PCROP(SectorBank2));
00838       /*Write protection done on sectors of BANK2*/
00839       *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS |= (uint16_t)SectorBank2;
00840     }
00841 
00842     /*Write protection on all sector  of BANK2*/
00843     if (Banks == FLASH_BANK_BOTH)
00844     {
00845       assert_param(IS_OB_PCROP(SectorBank2));
00846       /* Wait for last operation to be completed */
00847       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00848 
00849       if (status == HAL_OK)
00850       {
00851         /*Write protection done on sectors of BANK2*/
00852         *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS |= (uint16_t)SectorBank2;
00853       }
00854     }
00855 
00856   }
00857 
00858   return status;
00859 }
00860 
00861 
00862 /**
00863   * @brief  Disable the read/write protection (PCROP) of the desired
00864   *         sectors  of Bank 1 and/or Bank 2.
00865   * @note   This function can be used only for STM32F42xxx/43xxx devices.
00866   * @param  SectorBank1 specifies the sector(s) to be read/write protected or unprotected for bank1.
00867   *          This parameter can be one of the following values:
00868   *            @arg OB_PCROP: A value between OB_PCROP_SECTOR_0 and OB_PCROP_SECTOR_11
00869   *            @arg OB_PCROP_SECTOR__All
00870   * @param  SectorBank2 Specifies the sector(s) to be read/write protected or unprotected for bank2.
00871   *          This parameter can be one of the following values:
00872   *            @arg OB_PCROP: A value between OB_PCROP_SECTOR_12 and OB_PCROP_SECTOR_23
00873   *            @arg OB_PCROP_SECTOR__All
00874   * @param  Banks Disable PCROP protection on all the sectors for the specific bank
00875   *          This parameter can be one of the following values:
00876   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
00877   *            @arg FLASH_BANK_2: WRP on all sectors of bank2
00878   *            @arg FLASH_BANK_BOTH: WRP on all sectors of bank1 & bank2
00879   *
00880   * @retval HAL Status
00881   */
00882 static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t SectorBank1, uint32_t SectorBank2, uint32_t Banks)
00883 {
00884   HAL_StatusTypeDef status = HAL_OK;
00885 
00886   /* Check the parameters */
00887   assert_param(IS_FLASH_BANK(Banks));
00888 
00889   /* Wait for last operation to be completed */
00890   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00891 
00892   if (status == HAL_OK)
00893   {
00894     if ((Banks == FLASH_BANK_1) || (Banks == FLASH_BANK_BOTH))
00895     {
00896       assert_param(IS_OB_PCROP(SectorBank1));
00897       /*Write protection done on sectors of BANK1*/
00898       *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS &= (~SectorBank1);
00899     }
00900     else
00901     {
00902       /*Write protection done on sectors of BANK2*/
00903       assert_param(IS_OB_PCROP(SectorBank2));
00904       *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS &= (~SectorBank2);
00905     }
00906 
00907     /*Write protection on all sector  of BANK2*/
00908     if (Banks == FLASH_BANK_BOTH)
00909     {
00910       assert_param(IS_OB_PCROP(SectorBank2));
00911       /* Wait for last operation to be completed */
00912       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00913 
00914       if (status == HAL_OK)
00915       {
00916         /*Write protection done on sectors of BANK2*/
00917         *(__IO uint16_t *)OPTCR1_BYTE2_ADDRESS &= (~SectorBank2);
00918       }
00919     }
00920 
00921   }
00922 
00923   return status;
00924 
00925 }
00926 
00927 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
00928 
00929 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) ||\
00930     defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) ||\
00931     defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) ||\
00932     defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) ||\
00933     defined(STM32F423xx)
00934 /**
00935   * @brief  Mass erase of FLASH memory
00936   * @param  VoltageRange The device voltage range which defines the erase parallelism.
00937   *          This parameter can be one of the following values:
00938   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
00939   *                                  the operation will be done by byte (8-bit)
00940   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
00941   *                                  the operation will be done by half word (16-bit)
00942   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
00943   *                                  the operation will be done by word (32-bit)
00944   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
00945   *                                  the operation will be done by double word (64-bit)
00946   *
00947   * @param  Banks Banks to be erased
00948   *          This parameter can be one of the following values:
00949   *            @arg FLASH_BANK_1: Bank1 to be erased
00950   *
00951   * @retval None
00952   */
00953 static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks)
00954 {
00955   /* Check the parameters */
00956   assert_param(IS_VOLTAGERANGE(VoltageRange));
00957   assert_param(IS_FLASH_BANK(Banks));
00958 
00959   /* If the previous operation is completed, proceed to erase all sectors */
00960   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00961   FLASH->CR |= FLASH_CR_MER;
00962   FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange << 8U);
00963 }
00964 
00965 /**
00966   * @brief  Erase the specified FLASH memory sector
00967   * @param  Sector FLASH sector to erase
00968   *         The value of this parameter depend on device used within the same series
00969   * @param  VoltageRange The device voltage range which defines the erase parallelism.
00970   *          This parameter can be one of the following values:
00971   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
00972   *                                  the operation will be done by byte (8-bit)
00973   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
00974   *                                  the operation will be done by half word (16-bit)
00975   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
00976   *                                  the operation will be done by word (32-bit)
00977   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
00978   *                                  the operation will be done by double word (64-bit)
00979   *
00980   * @retval None
00981   */
00982 void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
00983 {
00984   uint32_t tmp_psize = 0U;
00985 
00986   /* Check the parameters */
00987   assert_param(IS_FLASH_SECTOR(Sector));
00988   assert_param(IS_VOLTAGERANGE(VoltageRange));
00989 
00990   if (VoltageRange == FLASH_VOLTAGE_RANGE_1)
00991   {
00992     tmp_psize = FLASH_PSIZE_BYTE;
00993   }
00994   else if (VoltageRange == FLASH_VOLTAGE_RANGE_2)
00995   {
00996     tmp_psize = FLASH_PSIZE_HALF_WORD;
00997   }
00998   else if (VoltageRange == FLASH_VOLTAGE_RANGE_3)
00999   {
01000     tmp_psize = FLASH_PSIZE_WORD;
01001   }
01002   else
01003   {
01004     tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
01005   }
01006 
01007   /* If the previous operation is completed, proceed to erase the sector */
01008   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
01009   FLASH->CR |= tmp_psize;
01010   CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
01011   FLASH->CR |= FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos);
01012   FLASH->CR |= FLASH_CR_STRT;
01013 }
01014 
01015 /**
01016   * @brief  Enable the write protection of the desired bank 1 sectors
01017   *
01018   * @note   When the memory read protection level is selected (RDP level = 1),
01019   *         it is not possible to program or erase the flash sector i if CortexM4
01020   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
01021   * @note   Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1).
01022   *
01023   * @param  WRPSector specifies the sector(s) to be write protected.
01024   *         The value of this parameter depend on device used within the same series
01025   *
01026   * @param  Banks Enable write protection on all the sectors for the specific bank
01027   *          This parameter can be one of the following values:
01028   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
01029   *
01030   * @retval HAL Status
01031   */
01032 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
01033 {
01034   HAL_StatusTypeDef status = HAL_OK;
01035 
01036   /* Check the parameters */
01037   assert_param(IS_OB_WRP_SECTOR(WRPSector));
01038   assert_param(IS_FLASH_BANK(Banks));
01039 
01040   /* Wait for last operation to be completed */
01041   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01042 
01043   if (status == HAL_OK)
01044   {
01045     *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS &= (~WRPSector);
01046   }
01047 
01048   return status;
01049 }
01050 
01051 /**
01052   * @brief  Disable the write protection of the desired bank 1 sectors
01053   *
01054   * @note   When the memory read protection level is selected (RDP level = 1),
01055   *         it is not possible to program or erase the flash sector i if CortexM4
01056   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
01057   * @note   Active value of nWRPi bits is inverted when PCROP mode is active (SPRMOD =1).
01058   *
01059   * @param  WRPSector specifies the sector(s) to be write protected.
01060   *         The value of this parameter depend on device used within the same series
01061   *
01062   * @param  Banks Enable write protection on all the sectors for the specific bank
01063   *          This parameter can be one of the following values:
01064   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
01065   *
01066   * @retval HAL Status
01067   */
01068 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
01069 {
01070   HAL_StatusTypeDef status = HAL_OK;
01071 
01072   /* Check the parameters */
01073   assert_param(IS_OB_WRP_SECTOR(WRPSector));
01074   assert_param(IS_FLASH_BANK(Banks));
01075 
01076   /* Wait for last operation to be completed */
01077   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01078 
01079   if (status == HAL_OK)
01080   {
01081     *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector;
01082   }
01083 
01084   return status;
01085 }
01086 #endif /* STM32F40xxx || STM32F41xxx || STM32F401xx || STM32F410xx || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx
01087           STM32F413xx || STM32F423xx */
01088 
01089 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
01090     defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) ||\
01091     defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
01092 /**
01093   * @brief  Enable the read/write protection (PCROP) of the desired sectors.
01094   * @note   This function can be used only for STM32F401xx devices.
01095   * @param  Sector specifies the sector(s) to be read/write protected or unprotected.
01096   *          This parameter can be one of the following values:
01097   *            @arg OB_PCROP: A value between OB_PCROP_Sector0 and OB_PCROP_Sector5
01098   *            @arg OB_PCROP_Sector_All
01099   * @retval HAL Status
01100   */
01101 static HAL_StatusTypeDef FLASH_OB_EnablePCROP(uint32_t Sector)
01102 {
01103   HAL_StatusTypeDef status = HAL_OK;
01104 
01105   /* Check the parameters */
01106   assert_param(IS_OB_PCROP(Sector));
01107 
01108   /* Wait for last operation to be completed */
01109   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01110 
01111   if (status == HAL_OK)
01112   {
01113     *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS |= (uint16_t)Sector;
01114   }
01115 
01116   return status;
01117 }
01118 
01119 
01120 /**
01121   * @brief  Disable the read/write protection (PCROP) of the desired sectors.
01122   * @note   This function can be used only for STM32F401xx devices.
01123   * @param  Sector specifies the sector(s) to be read/write protected or unprotected.
01124   *          This parameter can be one of the following values:
01125   *            @arg OB_PCROP: A value between OB_PCROP_Sector0 and OB_PCROP_Sector5
01126   *            @arg OB_PCROP_Sector_All
01127   * @retval HAL Status
01128   */
01129 static HAL_StatusTypeDef FLASH_OB_DisablePCROP(uint32_t Sector)
01130 {
01131   HAL_StatusTypeDef status = HAL_OK;
01132 
01133   /* Check the parameters */
01134   assert_param(IS_OB_PCROP(Sector));
01135 
01136   /* Wait for last operation to be completed */
01137   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01138 
01139   if (status == HAL_OK)
01140   {
01141     *(__IO uint16_t *)OPTCR_BYTE2_ADDRESS &= (~Sector);
01142   }
01143 
01144   return status;
01145 
01146 }
01147 #endif /* STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx
01148           STM32F413xx || STM32F423xx */
01149 
01150 /**
01151   * @brief  Set the read protection level.
01152   * @param  Level specifies the read protection level.
01153   *          This parameter can be one of the following values:
01154   *            @arg OB_RDP_LEVEL_0: No protection
01155   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
01156   *            @arg OB_RDP_LEVEL_2: Full chip protection
01157   *
01158   * @note WARNING: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
01159   *
01160   * @retval HAL Status
01161   */
01162 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level)
01163 {
01164   HAL_StatusTypeDef status = HAL_OK;
01165 
01166   /* Check the parameters */
01167   assert_param(IS_OB_RDP_LEVEL(Level));
01168 
01169   /* Wait for last operation to be completed */
01170   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01171 
01172   if (status == HAL_OK)
01173   {
01174     *(__IO uint8_t *)OPTCR_BYTE1_ADDRESS = Level;
01175   }
01176 
01177   return status;
01178 }
01179 
01180 /**
01181   * @brief  Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
01182   * @param  Iwdg Selects the IWDG mode
01183   *          This parameter can be one of the following values:
01184   *            @arg OB_IWDG_SW: Software IWDG selected
01185   *            @arg OB_IWDG_HW: Hardware IWDG selected
01186   * @param  Stop Reset event when entering STOP mode.
01187   *          This parameter  can be one of the following values:
01188   *            @arg OB_STOP_NO_RST: No reset generated when entering in STOP
01189   *            @arg OB_STOP_RST: Reset generated when entering in STOP
01190   * @param  Stdby Reset event when entering Standby mode.
01191   *          This parameter  can be one of the following values:
01192   *            @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY
01193   *            @arg OB_STDBY_RST: Reset generated when entering in STANDBY
01194   * @retval HAL Status
01195   */
01196 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t Iwdg, uint8_t Stop, uint8_t Stdby)
01197 {
01198   uint8_t optiontmp = 0xFF;
01199   HAL_StatusTypeDef status = HAL_OK;
01200 
01201   /* Check the parameters */
01202   assert_param(IS_OB_IWDG_SOURCE(Iwdg));
01203   assert_param(IS_OB_STOP_SOURCE(Stop));
01204   assert_param(IS_OB_STDBY_SOURCE(Stdby));
01205 
01206   /* Wait for last operation to be completed */
01207   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01208 
01209   if (status == HAL_OK)
01210   {
01211     /* Mask OPTLOCK, OPTSTRT, BOR_LEV and BFB2 bits */
01212     optiontmp = (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE0_ADDRESS) & (uint8_t)0x1F);
01213 
01214     /* Update User Option Byte */
01215     *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS = Iwdg | (uint8_t)(Stdby | (uint8_t)(Stop | ((uint8_t)optiontmp)));
01216   }
01217 
01218   return status;
01219 }
01220 
01221 /**
01222   * @brief  Set the BOR Level.
01223   * @param  Level specifies the Option Bytes BOR Reset Level.
01224   *          This parameter can be one of the following values:
01225   *            @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
01226   *            @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
01227   *            @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
01228   *            @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V
01229   * @retval HAL Status
01230   */
01231 static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level)
01232 {
01233   /* Check the parameters */
01234   assert_param(IS_OB_BOR_LEVEL(Level));
01235 
01236   /* Set the BOR Level */
01237   *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BOR_LEV);
01238   *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= Level;
01239 
01240   return HAL_OK;
01241 
01242 }
01243 
01244 /**
01245   * @brief  Return the FLASH User Option Byte value.
01246   * @retval uint8_t FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1)
01247   *         and RST_STDBY(Bit2).
01248   */
01249 static uint8_t FLASH_OB_GetUser(void)
01250 {
01251   /* Return the User Option Byte */
01252   return ((uint8_t)(FLASH->OPTCR & 0xE0));
01253 }
01254 
01255 /**
01256   * @brief  Return the FLASH Write Protection Option Bytes value.
01257   * @retval uint16_t FLASH Write Protection Option Bytes value
01258   */
01259 static uint16_t FLASH_OB_GetWRP(void)
01260 {
01261   /* Return the FLASH write protection Register value */
01262   return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
01263 }
01264 
01265 /**
01266   * @brief  Returns the FLASH Read Protection level.
01267   * @retval FLASH ReadOut Protection Status:
01268   *         This parameter can be one of the following values:
01269   *            @arg OB_RDP_LEVEL_0: No protection
01270   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
01271   *            @arg OB_RDP_LEVEL_2: Full chip protection
01272   */
01273 static uint8_t FLASH_OB_GetRDP(void)
01274 {
01275   uint8_t readstatus = OB_RDP_LEVEL_0;
01276 
01277   if (*(__IO uint8_t *)(OPTCR_BYTE1_ADDRESS) == (uint8_t)OB_RDP_LEVEL_2)
01278   {
01279     readstatus = OB_RDP_LEVEL_2;
01280   }
01281   else if (*(__IO uint8_t *)(OPTCR_BYTE1_ADDRESS) == (uint8_t)OB_RDP_LEVEL_0)
01282   {
01283     readstatus = OB_RDP_LEVEL_0;
01284   }
01285   else
01286   {
01287     readstatus = OB_RDP_LEVEL_1;
01288   }
01289 
01290   return readstatus;
01291 }
01292 
01293 /**
01294   * @brief  Returns the FLASH BOR level.
01295   * @retval uint8_t The FLASH BOR level:
01296   *           - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
01297   *           - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
01298   *           - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
01299   *           - OB_BOR_OFF   : Supply voltage ranges from 1.62 to 2.1 V
01300   */
01301 static uint8_t FLASH_OB_GetBOR(void)
01302 {
01303   /* Return the FLASH BOR level */
01304   return (uint8_t)(*(__IO uint8_t *)(OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0C);
01305 }
01306 
01307 /**
01308   * @brief  Flush the instruction and data caches
01309   * @retval None
01310   */
01311 void FLASH_FlushCaches(void)
01312 {
01313   /* Flush instruction cache  */
01314   if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != RESET)
01315   {
01316     /* Disable instruction cache  */
01317     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
01318     /* Reset instruction cache */
01319     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
01320     /* Enable instruction cache */
01321     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
01322   }
01323 
01324   /* Flush data cache */
01325   if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
01326   {
01327     /* Disable data cache  */
01328     __HAL_FLASH_DATA_CACHE_DISABLE();
01329     /* Reset data cache */
01330     __HAL_FLASH_DATA_CACHE_RESET();
01331     /* Enable data cache */
01332     __HAL_FLASH_DATA_CACHE_ENABLE();
01333   }
01334 }
01335 
01336 /**
01337   * @}
01338   */
01339 
01340 #endif /* HAL_FLASH_MODULE_ENABLED */
01341 
01342 /**
01343   * @}
01344   */
01345 
01346 /**
01347   * @}
01348   */
01349 
01350 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/