STM32H735xx HAL User Manual
stm32h7xx_hal_flash_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_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 STM32H7xx
00016        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        (+) Global readout protection (RDP)
00023        (+) Write protection
00024        (+) Secure access only protection
00025        (+) Bank / register swapping (when Dual-Bank)
00026        (+) Cyclic Redundancy Check (CRC)
00027 
00028                         ##### How to use this driver #####
00029  ==============================================================================
00030   [..] This driver provides functions to configure and program the FLASH memory
00031        of all STM32H7xx devices. It includes
00032       (#) FLASH Memory Erase functions:
00033            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
00034                 HAL_FLASH_Lock() functions
00035            (++) Erase function: Sector erase, bank erase and dual-bank mass erase
00036            (++) There are two modes of erase :
00037              (+++) Polling Mode using HAL_FLASHEx_Erase()
00038              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
00039 
00040       (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to:
00041         (++) Set/Reset the write protection per bank
00042         (++) Set the Read protection Level
00043         (++) Set the BOR level
00044         (++) Program the user Option Bytes
00045         (++) PCROP protection configuration and control per bank
00046         (++) Secure area configuration and control per bank
00047         (++) Core Boot address configuration
00048         (++) TCM / AXI shared RAM configuration
00049         (++) CPU Frequency Boost configuration
00050 
00051       (#) FLASH Memory Lock and unlock per Bank: HAL_FLASHEx_Lock_Bank1(), HAL_FLASHEx_Unlock_Bank1(),
00052           HAL_FLASHEx_Lock_Bank2() and HAL_FLASHEx_Unlock_Bank2() functions
00053 
00054       (#) FLASH CRC computation function: Use HAL_FLASHEx_ComputeCRC() to:
00055           (++) Enable CRC feature
00056           (++) Program the desired burst size
00057           (++) Define the user Flash Area on which the CRC has be computed
00058           (++) Perform the CRC computation
00059           (++) Disable CRC feature
00060 
00061  @endverbatim
00062   ******************************************************************************
00063   * @attention
00064   *
00065   * Copyright (c) 2017 STMicroelectronics.
00066   * All rights reserved.
00067   *
00068   * This software is licensed under terms that can be found in the LICENSE file in
00069   * the root directory of this software component.
00070   * If no LICENSE file comes with this software, it is provided AS-IS.
00071   ******************************************************************************
00072   */
00073 
00074 /* Includes ------------------------------------------------------------------*/
00075 #include "stm32h7xx_hal.h"
00076 
00077 /** @addtogroup STM32H7xx_HAL_Driver
00078   * @{
00079   */
00080 
00081 /** @defgroup FLASHEx  FLASHEx
00082   * @brief FLASH HAL Extension module driver
00083   * @{
00084   */
00085 
00086 #ifdef HAL_FLASH_MODULE_ENABLED
00087 
00088 /* Private typedef -----------------------------------------------------------*/
00089 /* Private define ------------------------------------------------------------*/
00090 /** @addtogroup FLASHEx_Private_Constants
00091   * @{
00092   */
00093 #define FLASH_TIMEOUT_VALUE       50000U /* 50 s */
00094 
00095 /**
00096   * @}
00097   */
00098 /* Private macro -------------------------------------------------------------*/
00099 /* Private variables ---------------------------------------------------------*/
00100 /* Private function prototypes -----------------------------------------------*/
00101 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
00102   * @{
00103   */
00104 static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks);
00105 static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks);
00106 static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank);
00107 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank);
00108 static void FLASH_OB_RDPConfig(uint32_t RDPLevel);
00109 static uint32_t FLASH_OB_GetRDP(void);
00110 static void FLASH_OB_PCROPConfig(uint32_t PCROConfigRDP, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks);
00111 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr,uint32_t *PCROPEndAddr, uint32_t Bank);
00112 static void FLASH_OB_BOR_LevelConfig(uint32_t Level);
00113 static uint32_t FLASH_OB_GetBOR(void);
00114 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
00115 static uint32_t FLASH_OB_GetUser(void);
00116 static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
00117 static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
00118 static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks);
00119 static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank);
00120 static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank);
00121 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank);
00122 
00123 #if defined (DUAL_CORE)
00124 static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
00125 static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
00126 #endif /*DUAL_CORE*/
00127 
00128 #if defined (FLASH_OTPBL_LOCKBL)
00129 static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block);
00130 static uint32_t FLASH_OB_OTP_GetLock(void);
00131 #endif /* FLASH_OTPBL_LOCKBL */
00132 
00133 #if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
00134 static void FLASH_OB_SharedRAM_Config(uint32_t SharedRamConfig);
00135 static uint32_t FLASH_OB_SharedRAM_GetConfig(void);
00136 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
00137 
00138 #if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
00139 static void FLASH_OB_CPUFreq_BoostConfig(uint32_t FreqBoost);
00140 static uint32_t FLASH_OB_CPUFreq_GetBoost(void);
00141 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
00142 /**
00143   * @}
00144   */
00145 
00146 /* Exported functions ---------------------------------------------------------*/
00147 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
00148   * @{
00149   */
00150 
00151 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
00152  *  @brief   Extended IO operation functions
00153  *
00154 @verbatim
00155  ===============================================================================
00156                 ##### Extended programming operation functions #####
00157  ===============================================================================
00158     [..]
00159     This subsection provides a set of functions allowing to manage the Extension FLASH
00160     programming operations Operations.
00161 
00162 @endverbatim
00163   * @{
00164   */
00165 /**
00166   * @brief  Perform a mass erase or erase the specified FLASH memory sectors
00167   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
00168   *         contains the configuration information for the erasing.
00169   *
00170   * @param[out]  SectorError pointer to variable  that contains the configuration
00171   *          information on faulty sector in case of error (0xFFFFFFFF means that all
00172   *          the sectors have been correctly erased)
00173   *
00174   * @retval HAL Status
00175   */
00176 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
00177 {
00178   HAL_StatusTypeDef status = HAL_OK;
00179   uint32_t sector_index;
00180 
00181   /* Check the parameters */
00182   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
00183   assert_param(IS_FLASH_BANK(pEraseInit->Banks));
00184 
00185   /* Process Locked */
00186   __HAL_LOCK(&pFlash);
00187 
00188   /* Reset error code */
00189   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00190 
00191   /* Wait for last operation to be completed on Bank1 */
00192   if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
00193   {
00194     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
00195     {
00196       status = HAL_ERROR;
00197     }
00198   }
00199 
00200 #if defined (DUAL_BANK)
00201   /* Wait for last operation to be completed on Bank2 */
00202   if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
00203   {
00204     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
00205     {
00206       status = HAL_ERROR;
00207     }
00208   }
00209 #endif /* DUAL_BANK */
00210 
00211   if(status == HAL_OK)
00212   {
00213     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
00214     {
00215       /* Mass erase to be done */
00216       FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
00217 
00218       /* Wait for last operation to be completed on Bank 1 */
00219       if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
00220       {
00221         if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
00222         {
00223           status = HAL_ERROR;
00224         }
00225         /* if the erase operation is completed, disable the Bank1 BER Bit */
00226         FLASH->CR1 &= (~FLASH_CR_BER);
00227       }
00228 #if defined (DUAL_BANK)
00229       /* Wait for last operation to be completed on Bank 2 */
00230       if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
00231       {
00232         if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
00233         {
00234           status = HAL_ERROR;
00235         }
00236         /* if the erase operation is completed, disable the Bank2 BER Bit */
00237         FLASH->CR2 &= (~FLASH_CR_BER);
00238       }
00239 #endif /* DUAL_BANK */
00240     }
00241     else
00242     {
00243       /*Initialization of SectorError variable*/
00244       *SectorError = 0xFFFFFFFFU;
00245 
00246       /* Erase by sector by sector to be done*/
00247       for(sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); sector_index++)
00248       {
00249         FLASH_Erase_Sector(sector_index, pEraseInit->Banks, pEraseInit->VoltageRange);
00250 
00251         if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
00252         {
00253           /* Wait for last operation to be completed */
00254           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
00255 
00256           /* If the erase operation is completed, disable the SER Bit */
00257           FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
00258         }
00259 #if defined (DUAL_BANK)
00260         if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
00261         {
00262           /* Wait for last operation to be completed */
00263           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
00264 
00265           /* If the erase operation is completed, disable the SER Bit */
00266           FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
00267         }
00268 #endif /* DUAL_BANK */
00269 
00270         if(status != HAL_OK)
00271         {
00272           /* In case of error, stop erase procedure and return the faulty sector */
00273           *SectorError = sector_index;
00274           break;
00275         }
00276       }
00277     }
00278   }
00279 
00280   /* Process Unlocked */
00281   __HAL_UNLOCK(&pFlash);
00282 
00283   return status;
00284 }
00285 
00286 /**
00287   * @brief  Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled
00288   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
00289   *         contains the configuration information for the erasing.
00290   *
00291   * @retval HAL Status
00292   */
00293 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
00294 {
00295   HAL_StatusTypeDef status = HAL_OK;
00296 
00297   /* Check the parameters */
00298   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
00299   assert_param(IS_FLASH_BANK(pEraseInit->Banks));
00300 
00301   /* Process Locked */
00302   __HAL_LOCK(&pFlash);
00303 
00304   /* Reset error code */
00305   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00306 
00307   /* Wait for last operation to be completed on Bank 1 */
00308   if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
00309   {
00310     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
00311     {
00312       status = HAL_ERROR;
00313     }
00314   }
00315 
00316 #if defined (DUAL_BANK)
00317   /* Wait for last operation to be completed on Bank 2 */
00318   if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
00319   {
00320     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
00321     {
00322       status = HAL_ERROR;
00323     }
00324   }
00325 #endif /* DUAL_BANK */
00326 
00327   if (status != HAL_OK)
00328   {
00329     /* Process Unlocked */
00330     __HAL_UNLOCK(&pFlash);
00331   }
00332   else
00333   {
00334     if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
00335     {
00336       /* Enable End of Operation and Error interrupts for Bank 1 */
00337 #if defined (FLASH_CR_OPERRIE)
00338       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00339                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
00340 #else
00341       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00342                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
00343 #endif /* FLASH_CR_OPERRIE */
00344     }
00345 #if defined (DUAL_BANK)
00346     if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
00347     {
00348       /* Enable End of Operation and Error interrupts for Bank 2 */
00349 #if defined (FLASH_CR_OPERRIE)
00350       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
00351                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
00352 #else
00353       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
00354                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
00355 #endif /* FLASH_CR_OPERRIE */
00356     }
00357 #endif /* DUAL_BANK */
00358 
00359     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
00360     {
00361       /*Mass erase to be done*/
00362       if(pEraseInit->Banks == FLASH_BANK_1)
00363       {
00364         pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1;
00365       }
00366 #if defined (DUAL_BANK)
00367       else if(pEraseInit->Banks == FLASH_BANK_2)
00368       {
00369         pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2;
00370       }
00371 #endif /* DUAL_BANK */
00372       else
00373       {
00374         pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE;
00375       }
00376 
00377       FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
00378     }
00379     else
00380     {
00381       /* Erase by sector to be done */
00382 #if defined (DUAL_BANK)
00383       if(pEraseInit->Banks == FLASH_BANK_1)
00384       {
00385         pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
00386       }
00387       else
00388       {
00389         pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2;
00390       }
00391 #else
00392       pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
00393 #endif /* DUAL_BANK */
00394 
00395       pFlash.NbSectorsToErase = pEraseInit->NbSectors;
00396       pFlash.Sector = pEraseInit->Sector;
00397       pFlash.VoltageForErase = pEraseInit->VoltageRange;
00398 
00399       /* Erase first sector and wait for IT */
00400       FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange);
00401     }
00402   }
00403 
00404   return status;
00405 }
00406 
00407 /**
00408   * @brief  Program option bytes
00409   * @param  pOBInit pointer to an FLASH_OBProgramInitTypeDef structure that
00410   *         contains the configuration information for the programming.
00411   *
00412   * @retval HAL Status
00413   */
00414 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
00415 {
00416   HAL_StatusTypeDef status;
00417 
00418   /* Check the parameters */
00419   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
00420 
00421   /* Process Locked */
00422   __HAL_LOCK(&pFlash);
00423 
00424   /* Reset Error Code */
00425   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00426 
00427   /* Wait for last operation to be completed */
00428   if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
00429   {
00430     status = HAL_ERROR;
00431   }
00432 #if defined (DUAL_BANK)
00433   else if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
00434   {
00435     status = HAL_ERROR;
00436   }
00437 #endif /* DUAL_BANK */
00438   else
00439   {
00440     status = HAL_OK;
00441   }
00442 
00443   if(status == HAL_OK)
00444   {
00445     /*Write protection configuration*/
00446     if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
00447     {
00448       assert_param(IS_WRPSTATE(pOBInit->WRPState));
00449 
00450       if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)
00451       {
00452         /*Enable of Write protection on the selected Sector*/
00453         FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks);
00454       }
00455       else
00456       {
00457         /*Disable of Write protection on the selected Sector*/
00458         FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks);
00459       }
00460     }
00461 
00462     /* Read protection configuration */
00463     if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
00464     {
00465       /* Configure the Read protection level */
00466       FLASH_OB_RDPConfig(pOBInit->RDPLevel);
00467     }
00468 
00469     /* User Configuration */
00470     if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
00471     {
00472       /* Configure the user option bytes */
00473       FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig);
00474     }
00475 
00476     /* PCROP Configuration */
00477     if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
00478     {
00479       assert_param(IS_FLASH_BANK(pOBInit->Banks));
00480 
00481       /*Configure the Proprietary code readout protection */
00482       FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks);
00483     }
00484 
00485     /* BOR Level configuration */
00486     if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
00487     {
00488       FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
00489     }
00490 
00491 #if defined(DUAL_CORE)
00492     /* CM7 Boot Address  configuration */
00493     if((pOBInit->OptionType & OPTIONBYTE_CM7_BOOTADD) == OPTIONBYTE_CM7_BOOTADD)
00494     {
00495       FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
00496     }
00497 
00498     /* CM4 Boot Address  configuration */
00499     if((pOBInit->OptionType & OPTIONBYTE_CM4_BOOTADD) == OPTIONBYTE_CM4_BOOTADD)
00500     {
00501       FLASH_OB_CM4BootAddConfig(pOBInit->CM4BootConfig, pOBInit->CM4BootAddr0, pOBInit->CM4BootAddr1);
00502     }
00503 #else /* Single Core*/
00504     /* Boot Address  configuration */
00505     if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD)
00506     {
00507       FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
00508     }
00509 #endif /*DUAL_CORE*/
00510 
00511     /* Secure area configuration */
00512     if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA)
00513     {
00514       FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks);
00515     }
00516 
00517 #if defined(FLASH_OTPBL_LOCKBL)
00518     /* OTP Block Lock configuration */
00519     if((pOBInit->OptionType & OPTIONBYTE_OTP_LOCK) == OPTIONBYTE_OTP_LOCK)
00520     {
00521       FLASH_OB_OTP_LockConfig(pOBInit->OTPBlockLock);
00522     }
00523 #endif /* FLASH_OTPBL_LOCKBL */
00524 
00525 #if defined(FLASH_OPTSR2_TCM_AXI_SHARED)
00526     /* TCM / AXI Shared RAM configuration */
00527     if((pOBInit->OptionType & OPTIONBYTE_SHARED_RAM) == OPTIONBYTE_SHARED_RAM)
00528     {
00529       FLASH_OB_SharedRAM_Config(pOBInit->SharedRamConfig);
00530     }
00531 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
00532 
00533 #if defined(FLASH_OPTSR2_CPUFREQ_BOOST)
00534     /* CPU Frequency Boost configuration */
00535     if((pOBInit->OptionType & OPTIONBYTE_FREQ_BOOST) == OPTIONBYTE_FREQ_BOOST)
00536     {
00537       FLASH_OB_CPUFreq_BoostConfig(pOBInit->FreqBoostState);
00538     }
00539 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
00540   }
00541 
00542   /* Process Unlocked */
00543   __HAL_UNLOCK(&pFlash);
00544 
00545   return status;
00546 }
00547 
00548 /**
00549   * @brief Get the Option byte configuration
00550   * @param  pOBInit pointer to an FLASH_OBProgramInitTypeDef structure that
00551   *         contains the configuration information for the programming.
00552   * @note   The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2,
00553   *         as this parameter is use to get the given Bank WRP, PCROP and secured area configuration.
00554   *
00555   * @retval None
00556   */
00557 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
00558 {
00559   pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP | OPTIONBYTE_BOR);
00560 
00561   /* Get Read protection level */
00562   pOBInit->RDPLevel = FLASH_OB_GetRDP();
00563 
00564   /* Get the user option bytes */
00565   pOBInit->USERConfig = FLASH_OB_GetUser();
00566 
00567   /*Get BOR Level*/
00568   pOBInit->BORLevel = FLASH_OB_GetBOR();
00569 
00570 #if defined (DUAL_BANK)
00571   if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2))
00572 #else
00573   if (pOBInit->Banks == FLASH_BANK_1)
00574 #endif /* DUAL_BANK */
00575   {
00576     pOBInit->OptionType |= (OPTIONBYTE_WRP | OPTIONBYTE_PCROP | OPTIONBYTE_SECURE_AREA);
00577 
00578     /* Get write protection on the selected area */
00579     FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector), pOBInit->Banks);
00580 
00581     /* Get the Proprietary code readout protection */
00582     FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr), pOBInit->Banks);
00583 
00584     /*Get Bank Secure area*/
00585     FLASH_OB_GetSecureArea(&(pOBInit->SecureAreaConfig), &(pOBInit->SecureAreaStartAddr), &(pOBInit->SecureAreaEndAddr), pOBInit->Banks);
00586   }
00587 
00588   /*Get Boot Address*/
00589   FLASH_OB_GetBootAdd(&(pOBInit->BootAddr0), &(pOBInit->BootAddr1));
00590 #if defined(DUAL_CORE)
00591   pOBInit->OptionType |= OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD;
00592 
00593   /*Get CM4 Boot Address*/
00594   FLASH_OB_GetCM4BootAdd(&(pOBInit->CM4BootAddr0), &(pOBInit->CM4BootAddr1));
00595 #else
00596   pOBInit->OptionType |= OPTIONBYTE_BOOTADD;
00597 #endif /*DUAL_CORE*/
00598 
00599 #if defined (FLASH_OTPBL_LOCKBL)
00600   pOBInit->OptionType |= OPTIONBYTE_OTP_LOCK;
00601 
00602   /* Get OTP Block Lock */
00603   pOBInit->OTPBlockLock = FLASH_OB_OTP_GetLock();
00604 #endif /* FLASH_OTPBL_LOCKBL */
00605 
00606 #if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
00607   pOBInit->OptionType |= OPTIONBYTE_SHARED_RAM;
00608 
00609   /* Get TCM / AXI Shared RAM */
00610   pOBInit->SharedRamConfig = FLASH_OB_SharedRAM_GetConfig();
00611 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
00612 
00613 #if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
00614   pOBInit->OptionType |= OPTIONBYTE_FREQ_BOOST;
00615 
00616   /* Get CPU Frequency Boost */
00617   pOBInit->FreqBoostState = FLASH_OB_CPUFreq_GetBoost();
00618 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
00619 }
00620 
00621 /**
00622   * @brief  Unlock the FLASH Bank1 control registers access
00623   * @retval HAL Status
00624   */
00625 HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void)
00626 {
00627   if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
00628   {
00629     /* Authorize the FLASH Bank1 Registers access */
00630     WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
00631     WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
00632 
00633     /* Verify Flash Bank1 is unlocked */
00634     if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
00635     {
00636       return HAL_ERROR;
00637     }
00638   }
00639 
00640   return HAL_OK;
00641 }
00642 
00643 /**
00644   * @brief  Locks the FLASH Bank1 control registers access
00645   * @retval HAL Status
00646   */
00647 HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void)
00648 {
00649   /* Set the LOCK Bit to lock the FLASH Bank1 Registers access */
00650   SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
00651   return HAL_OK;
00652 }
00653 
00654 #if defined (DUAL_BANK)
00655 /**
00656   * @brief  Unlock the FLASH Bank2 control registers access
00657   * @retval HAL Status
00658   */
00659 HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void)
00660 {
00661   if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
00662   {
00663     /* Authorize the FLASH Bank2 Registers access */
00664     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
00665     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
00666 
00667     /* Verify Flash Bank1 is unlocked */
00668     if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
00669     {
00670       return HAL_ERROR;
00671     }
00672   }
00673 
00674   return HAL_OK;
00675 }
00676 
00677 /**
00678   * @brief  Locks the FLASH Bank2 control registers access
00679   * @retval HAL Status
00680   */
00681 HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void)
00682 {
00683   /* Set the LOCK Bit to lock the FLASH Bank2 Registers access */
00684   SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
00685   return HAL_OK;
00686 }
00687 #endif /* DUAL_BANK */
00688 
00689 /*
00690   * @brief  Perform a CRC computation on the specified FLASH memory area
00691   * @param  pCRCInit pointer to an FLASH_CRCInitTypeDef structure that
00692   *         contains the configuration information for the CRC computation.
00693   * @note   CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7
00694   * @note   The application should avoid running a CRC on PCROP or secure-only
00695   *         user Flash memory area since it may alter the expected CRC value.
00696   *         A special error flag (CRC read error: CRCRDERR) can be used to
00697   *         detect such a case.
00698   * @retval HAL Status
00699 */
00700 HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result)
00701 {
00702   HAL_StatusTypeDef status;
00703   uint32_t sector_index;
00704 
00705   /* Check the parameters */
00706   assert_param(IS_FLASH_BANK_EXCLUSIVE(pCRCInit->Bank));
00707   assert_param(IS_FLASH_TYPECRC(pCRCInit->TypeCRC));
00708 
00709   /* Wait for OB change operation to be completed */
00710   status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00711 
00712   if (status == HAL_OK)
00713   {
00714     if (pCRCInit->Bank == FLASH_BANK_1)
00715     {
00716       /* Enable CRC feature */
00717       FLASH->CR1 |= FLASH_CR_CRC_EN;
00718 
00719       /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
00720       FLASH->CCR1 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
00721 
00722       /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
00723       FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
00724 
00725       if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
00726       {
00727         /* Clear sectors list */
00728         FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_SECT;
00729 
00730         /* Select CRC sectors */
00731         for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
00732         {
00733           FLASH_CRC_AddSector(sector_index, FLASH_BANK_1);
00734         }
00735       }
00736       else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
00737       {
00738         /* Enable Bank 1 CRC select bit */
00739         FLASH->CRCCR1 |= FLASH_CRCCR_ALL_BANK;
00740       }
00741       else
00742       {
00743         /* Select CRC start and end addresses */
00744         FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_1);
00745       }
00746 
00747       /* Start the CRC calculation */
00748       FLASH->CRCCR1 |= FLASH_CRCCR_START_CRC;
00749 
00750       /* Wait on CRC busy flag */
00751       status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
00752 
00753       /* Return CRC result */
00754       (*CRC_Result) = FLASH->CRCDATA;
00755 
00756       /* Disable CRC feature */
00757       FLASH->CR1 &= (~FLASH_CR_CRC_EN);
00758 
00759       /* Clear CRC flags */
00760       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCEND_BANK1 | FLASH_FLAG_CRCRDERR_BANK1);
00761     }
00762 #if defined (DUAL_BANK)
00763     else
00764     {
00765       /* Enable CRC feature */
00766       FLASH->CR2 |= FLASH_CR_CRC_EN;
00767 
00768       /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
00769       FLASH->CCR2 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
00770 
00771       /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
00772       FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
00773 
00774       if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
00775       {
00776         /* Clear sectors list */
00777         FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_SECT;
00778 
00779         /* Add CRC sectors */
00780         for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
00781         {
00782           FLASH_CRC_AddSector(sector_index, FLASH_BANK_2);
00783         }
00784       }
00785       else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
00786       {
00787         /* Enable Bank 2 CRC select bit */
00788         FLASH->CRCCR2 |= FLASH_CRCCR_ALL_BANK;
00789       }
00790       else
00791       {
00792         /* Select CRC start and end addresses */
00793         FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_2);
00794       }
00795 
00796       /* Start the CRC calculation */
00797       FLASH->CRCCR2 |= FLASH_CRCCR_START_CRC;
00798 
00799       /* Wait on CRC busy flag */
00800       status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
00801 
00802       /* Return CRC result */
00803       (*CRC_Result) = FLASH->CRCDATA;
00804 
00805       /* Disable CRC feature */
00806       FLASH->CR2 &= (~FLASH_CR_CRC_EN);
00807 
00808       /* Clear CRC flags */
00809       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCEND_BANK2 | FLASH_FLAG_CRCRDERR_BANK2);
00810     }
00811 #endif /* DUAL_BANK */
00812   }
00813 
00814   return status;
00815 }
00816 
00817 /**
00818   * @}
00819   */
00820 
00821 /**
00822   * @}
00823   */
00824 
00825 /* Private functions ---------------------------------------------------------*/
00826 
00827 /** @addtogroup FLASHEx_Private_Functions
00828   * @{
00829   */
00830 
00831 /**
00832   * @brief  Mass erase of FLASH memory
00833   * @param  VoltageRange The device program/erase parallelism.
00834   *          This parameter can be one of the following values:
00835   *            @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
00836   *            @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
00837   *            @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
00838   *            @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
00839   *
00840   * @param  Banks Banks to be erased
00841   *          This parameter can be one of the following values:
00842   *            @arg FLASH_BANK_1: Bank1 to be erased
00843   *            @arg FLASH_BANK_2: Bank2 to be erased
00844   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
00845   *
00846   * @retval HAL Status
00847   */
00848 static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks)
00849 {
00850   /* Check the parameters */
00851 #if defined (FLASH_CR_PSIZE)
00852   assert_param(IS_VOLTAGERANGE(VoltageRange));
00853 #else
00854   UNUSED(VoltageRange);
00855 #endif /* FLASH_CR_PSIZE */
00856   assert_param(IS_FLASH_BANK(Banks));
00857 
00858 #if defined (DUAL_BANK)
00859   /* Flash Mass Erase */
00860   if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH)
00861   {
00862 #if defined (FLASH_CR_PSIZE)
00863     /* Reset Program/erase VoltageRange for Bank1 and Bank2 */
00864     FLASH->CR1 &= (~FLASH_CR_PSIZE);
00865     FLASH->CR2 &= (~FLASH_CR_PSIZE);
00866 
00867     /* Set voltage range */
00868     FLASH->CR1 |= VoltageRange;
00869     FLASH->CR2 |= VoltageRange;
00870 #endif /* FLASH_CR_PSIZE */
00871 
00872     /* Set Mass Erase Bit */
00873     FLASH->OPTCR |= FLASH_OPTCR_MER;
00874   }
00875   else
00876 #endif /* DUAL_BANK */
00877   {
00878     /* Proceed to erase Flash Bank  */
00879     if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
00880     {
00881 #if defined (FLASH_CR_PSIZE)
00882       /* Set Program/erase VoltageRange for Bank1 */
00883       FLASH->CR1 &= (~FLASH_CR_PSIZE);
00884       FLASH->CR1 |=  VoltageRange;
00885 #endif /* FLASH_CR_PSIZE */
00886 
00887       /* Erase Bank1 */
00888       FLASH->CR1 |= (FLASH_CR_BER | FLASH_CR_START);
00889     }
00890 
00891 #if defined (DUAL_BANK)
00892     if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
00893     {
00894 #if defined (FLASH_CR_PSIZE)
00895       /* Set Program/erase VoltageRange for Bank2 */
00896       FLASH->CR2 &= (~FLASH_CR_PSIZE);
00897       FLASH->CR2 |= VoltageRange;
00898 #endif /* FLASH_CR_PSIZE */
00899 
00900       /* Erase Bank2 */
00901       FLASH->CR2 |= (FLASH_CR_BER | FLASH_CR_START);
00902     }
00903 #endif /* DUAL_BANK */
00904   }
00905 }
00906 
00907 /**
00908   * @brief  Erase the specified FLASH memory sector
00909   * @param  Sector FLASH sector to erase
00910   *          This parameter can be a value of @ref FLASH_Sectors
00911   * @param  Banks Banks to be erased
00912   *          This parameter can be one of the following values:
00913   *            @arg FLASH_BANK_1: Bank1 to be erased
00914   *            @arg FLASH_BANK_2: Bank2 to be erased
00915   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
00916   * @param  VoltageRange The device program/erase parallelism.
00917   *          This parameter can be one of the following values:
00918   *            @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
00919   *            @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
00920   *            @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
00921   *            @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
00922   *
00923   * @retval None
00924   */
00925 void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange)
00926 {
00927   assert_param(IS_FLASH_SECTOR(Sector));
00928   assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
00929 #if defined (FLASH_CR_PSIZE)
00930   assert_param(IS_VOLTAGERANGE(VoltageRange));
00931 #else
00932   UNUSED(VoltageRange);
00933 #endif /* FLASH_CR_PSIZE */
00934 
00935   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
00936   {
00937 #if defined (FLASH_CR_PSIZE)
00938     /* Reset Program/erase VoltageRange and Sector Number for Bank1 */
00939     FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
00940 
00941     FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
00942 #else
00943     /* Reset Sector Number for Bank1 */
00944     FLASH->CR1 &= ~(FLASH_CR_SNB);
00945 
00946     FLASH->CR1 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
00947 #endif /* FLASH_CR_PSIZE */
00948   }
00949 
00950 #if defined (DUAL_BANK)
00951   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
00952   {
00953 #if defined (FLASH_CR_PSIZE)
00954     /* Reset Program/erase VoltageRange and Sector Number for Bank2 */
00955     FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
00956 
00957     FLASH->CR2 |= (FLASH_CR_SER | VoltageRange  | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
00958 #else
00959     /* Reset Sector Number for Bank2 */
00960     FLASH->CR2 &= ~(FLASH_CR_SNB);
00961 
00962     FLASH->CR2 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
00963 #endif /* FLASH_CR_PSIZE */
00964   }
00965 #endif /* DUAL_BANK */
00966 }
00967 
00968 /**
00969   * @brief  Enable the write protection of the desired bank1 or bank 2 sectors
00970   * @param  WRPSector specifies the sector(s) to be write protected.
00971   *          This parameter can be one of the following values:
00972   *            @arg WRPSector:  A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_7 or OB_WRP_SECTOR_ALL
00973   *
00974   * @param  Banks the specific bank to apply WRP sectors
00975   *          This parameter can be one of the following values:
00976   *            @arg FLASH_BANK_1: enable WRP on specified bank1 sectors
00977   *            @arg FLASH_BANK_2: enable WRP on specified bank2 sectors
00978   *            @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors
00979   *
00980   * @retval HAL FLASH State
00981   */
00982 static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
00983 {
00984   /* Check the parameters */
00985   assert_param(IS_OB_WRP_SECTOR(WRPSector));
00986   assert_param(IS_FLASH_BANK(Banks));
00987 
00988   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
00989   {
00990     /* Enable Write Protection for bank 1 */
00991     FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN));
00992   }
00993 
00994 #if defined (DUAL_BANK)
00995   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
00996   {
00997     /* Enable Write Protection for bank 2 */
00998     FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN));
00999   }
01000 #endif /* DUAL_BANK */
01001 }
01002 
01003 /**
01004   * @brief  Disable the write protection of the desired bank1 or bank 2 sectors
01005   * @param  WRPSector specifies the sector(s) to disable write protection.
01006   *          This parameter can be one of the following values:
01007   *            @arg WRPSector:  A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_ALL
01008   *
01009   * @param  Banks the specific bank to apply WRP sectors
01010   *          This parameter can be one of the following values:
01011   *            @arg FLASH_BANK_1: disable WRP on specified bank1 sectors
01012   *            @arg FLASH_BANK_2: disable WRP on specified bank2 sectors
01013   *            @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors
01014   *
01015   * @retval HAL FLASH State
01016   */
01017 static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
01018 {
01019   /* Check the parameters */
01020   assert_param(IS_OB_WRP_SECTOR(WRPSector));
01021   assert_param(IS_FLASH_BANK(Banks));
01022 
01023   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
01024   {
01025     /* Disable Write Protection for bank 1 */
01026     FLASH->WPSN_PRG1 |= (WRPSector & FLASH_WPSN_WRPSN);
01027   }
01028 
01029 #if defined (DUAL_BANK)
01030   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
01031   {
01032     /* Disable Write Protection for bank 2 */
01033     FLASH->WPSN_PRG2 |= (WRPSector & FLASH_WPSN_WRPSN);
01034   }
01035 #endif /* DUAL_BANK */
01036 }
01037 
01038 /**
01039   * @brief  Get the write protection of the given bank 1 or bank 2 sectors
01040   * @param  WRPState gives the write protection state on the given bank.
01041   *          This parameter can be one of the following values:
01042   *          @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE
01043 
01044   * @param  WRPSector gives the write protected sector(s) on the given bank .
01045   *          This parameter can be one of the following values:
01046   *          @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_ALL
01047   *
01048   * @param  Bank the specific bank to apply WRP sectors
01049   *          This parameter can be exclusively one of the following values:
01050   *            @arg FLASH_BANK_1: Get bank1 WRP sectors
01051   *            @arg FLASH_BANK_2: Get bank2 WRP sectors
01052   *            @arg FLASH_BANK_BOTH: note allowed in this functions
01053   *
01054   * @retval HAL FLASH State
01055   */
01056 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank)
01057 {
01058   uint32_t regvalue = 0U;
01059 
01060   if(Bank == FLASH_BANK_1)
01061   {
01062     regvalue = FLASH->WPSN_CUR1;
01063   }
01064 
01065 #if defined (DUAL_BANK)
01066   if(Bank == FLASH_BANK_2)
01067   {
01068     regvalue = FLASH->WPSN_CUR2;
01069   }
01070 #endif /* DUAL_BANK */
01071 
01072   (*WRPSector) = (~regvalue) & FLASH_WPSN_WRPSN;
01073 
01074   if(*WRPSector == 0U)
01075   {
01076     (*WRPState) = OB_WRPSTATE_DISABLE;
01077   }
01078   else
01079   {
01080     (*WRPState) = OB_WRPSTATE_ENABLE;
01081   }
01082 }
01083 
01084 /**
01085   * @brief  Set the read protection level.
01086   *
01087   * @note   To configure the RDP level, the option lock bit OPTLOCK must be
01088   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
01089   * @note   To validate the RDP level, the option bytes must be reloaded
01090   *         through the call of the HAL_FLASH_OB_Launch() function.
01091   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
01092   *         to go back to level 1 or 0 !!!
01093   *
01094   * @param  RDPLevel specifies the read protection level.
01095   *         This parameter can be one of the following values:
01096   *            @arg OB_RDP_LEVEL_0: No protection
01097   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
01098   *            @arg OB_RDP_LEVEL_2: Full chip protection
01099   *
01100   * @retval HAL status
01101   */
01102 static void FLASH_OB_RDPConfig(uint32_t RDPLevel)
01103 {
01104   /* Check the parameters */
01105   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
01106 
01107   /* Configure the RDP level in the option bytes register */
01108   MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_RDP, RDPLevel);
01109 }
01110 
01111 /**
01112   * @brief  Get the read protection level.
01113   * @retval RDPLevel specifies the read protection level.
01114   *         This return value can be one of the following values:
01115   *            @arg OB_RDP_LEVEL_0: No protection
01116   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
01117   *            @arg OB_RDP_LEVEL_2: Full chip protection
01118   */
01119 static uint32_t FLASH_OB_GetRDP(void)
01120 {
01121   uint32_t rdp_level = READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_RDP);
01122   
01123   if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
01124   {
01125     return (OB_RDP_LEVEL_1);
01126   }
01127   else
01128   {
01129     return rdp_level;
01130   }
01131 }
01132 
01133 #if defined(DUAL_CORE)
01134 /**
01135   * @brief  Program the FLASH User Option Byte.
01136   *
01137   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
01138   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
01139   *
01140   * @note   To validate the user option bytes, the option bytes must be reloaded
01141   *         through the call of the HAL_FLASH_OB_Launch() function.
01142   *
01143   * @param  UserType The FLASH User Option Bytes to be modified :
01144   *                   a combination of @ref FLASHEx_OB_USER_Type
01145   *
01146   * @param  UserConfig The FLASH User Option Bytes values:
01147   *         IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
01148   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
01149   *         SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
01150   *         nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
01151   *
01152   * @retval HAL status
01153   */
01154 #else
01155 /**
01156   * @brief  Program the FLASH User Option Byte.
01157   *
01158   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
01159   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
01160   *
01161   * @note   To validate the user option bytes, the option bytes must be reloaded
01162   *         through the call of the HAL_FLASH_OB_Launch() function.
01163   *
01164   * @param  UserType The FLASH User Option Bytes to be modified :
01165   *                   a combination of @arg FLASHEx_OB_USER_Type
01166   *
01167   * @param  UserConfig The FLASH User Option Bytes values:
01168   *         IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
01169   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
01170   *         SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
01171   *
01172   * @retval HAL status
01173   */
01174 #endif /*DUAL_CORE*/
01175 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
01176 {
01177   uint32_t optr_reg_val = 0;
01178   uint32_t optr_reg_mask = 0;
01179 
01180   /* Check the parameters */
01181   assert_param(IS_OB_USER_TYPE(UserType));
01182 
01183   if((UserType & OB_USER_IWDG1_SW) != 0U)
01184   {
01185     /* IWDG_HW option byte should be modified */
01186     assert_param(IS_OB_IWDG1_SOURCE(UserConfig & FLASH_OPTSR_IWDG1_SW));
01187 
01188     /* Set value and mask for IWDG_HW option byte */
01189     optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG1_SW);
01190     optr_reg_mask |= FLASH_OPTSR_IWDG1_SW;
01191   }
01192 #if defined(DUAL_CORE)
01193   if((UserType & OB_USER_IWDG2_SW) != 0U)
01194   {
01195     /* IWDG2_SW option byte should be modified */
01196     assert_param(IS_OB_IWDG2_SOURCE(UserConfig & FLASH_OPTSR_IWDG2_SW));
01197 
01198     /* Set value and mask for IWDG2_SW option byte */
01199     optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG2_SW);
01200     optr_reg_mask |= FLASH_OPTSR_IWDG2_SW;
01201   }
01202 #endif /*DUAL_CORE*/
01203   if((UserType & OB_USER_NRST_STOP_D1) != 0U)
01204   {
01205     /* NRST_STOP option byte should be modified */
01206     assert_param(IS_OB_STOP_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D1));
01207 
01208     /* Set value and mask for NRST_STOP option byte */
01209     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D1);
01210     optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D1;
01211   }
01212 
01213   if((UserType & OB_USER_NRST_STDBY_D1) != 0U)
01214   {
01215     /* NRST_STDBY option byte should be modified */
01216     assert_param(IS_OB_STDBY_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D1));
01217 
01218     /* Set value and mask for NRST_STDBY option byte */
01219     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D1);
01220     optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D1;
01221   }
01222 
01223   if((UserType & OB_USER_IWDG_STOP) != 0U)
01224   {
01225     /* IWDG_STOP option byte should be modified */
01226     assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTSR_FZ_IWDG_STOP));
01227 
01228     /* Set value and mask for IWDG_STOP option byte */
01229     optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_STOP);
01230     optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_STOP;
01231   }
01232 
01233   if((UserType & OB_USER_IWDG_STDBY) != 0U)
01234   {
01235     /* IWDG_STDBY option byte should be modified */
01236     assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY));
01237 
01238     /* Set value and mask for IWDG_STDBY option byte */
01239     optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY);
01240     optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_SDBY;
01241   }
01242 
01243   if((UserType & OB_USER_ST_RAM_SIZE) != 0U)
01244   {
01245     /* ST_RAM_SIZE option byte should be modified */
01246     assert_param(IS_OB_USER_ST_RAM_SIZE(UserConfig & FLASH_OPTSR_ST_RAM_SIZE));
01247 
01248     /* Set value and mask for ST_RAM_SIZE option byte */
01249     optr_reg_val |= (UserConfig & FLASH_OPTSR_ST_RAM_SIZE);
01250     optr_reg_mask |= FLASH_OPTSR_ST_RAM_SIZE;
01251   }
01252 
01253   if((UserType & OB_USER_SECURITY) != 0U)
01254   {
01255     /* SECURITY option byte should be modified */
01256     assert_param(IS_OB_USER_SECURITY(UserConfig & FLASH_OPTSR_SECURITY));
01257 
01258     /* Set value and mask for SECURITY option byte */
01259     optr_reg_val |= (UserConfig & FLASH_OPTSR_SECURITY);
01260     optr_reg_mask |= FLASH_OPTSR_SECURITY;
01261   }
01262 
01263 #if defined(DUAL_CORE)
01264   if((UserType & OB_USER_BCM4) != 0U)
01265   {
01266     /* BCM4 option byte should be modified */
01267     assert_param(IS_OB_USER_BCM4(UserConfig & FLASH_OPTSR_BCM4));
01268 
01269     /* Set value and mask for BCM4 option byte */
01270     optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM4);
01271     optr_reg_mask |= FLASH_OPTSR_BCM4;
01272   }
01273 
01274   if((UserType & OB_USER_BCM7) != 0U)
01275   {
01276     /* BCM7 option byte should be modified */
01277     assert_param(IS_OB_USER_BCM7(UserConfig & FLASH_OPTSR_BCM7));
01278 
01279     /* Set value and mask for BCM7 option byte */
01280     optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM7);
01281     optr_reg_mask |= FLASH_OPTSR_BCM7;
01282   }
01283 #endif /* DUAL_CORE */
01284 
01285 #if defined (FLASH_OPTSR_NRST_STOP_D2)
01286   if((UserType & OB_USER_NRST_STOP_D2) != 0U)
01287   {
01288     /* NRST_STOP option byte should be modified */
01289     assert_param(IS_OB_STOP_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D2));
01290 
01291     /* Set value and mask for NRST_STOP option byte */
01292     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D2);
01293     optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D2;
01294   }
01295 
01296   if((UserType & OB_USER_NRST_STDBY_D2) != 0U)
01297   {
01298     /* NRST_STDBY option byte should be modified */
01299     assert_param(IS_OB_STDBY_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D2));
01300 
01301     /* Set value and mask for NRST_STDBY option byte */
01302     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D2);
01303     optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D2;
01304   }
01305 #endif /* FLASH_OPTSR_NRST_STOP_D2 */
01306 
01307 #if defined (DUAL_BANK)
01308   if((UserType & OB_USER_SWAP_BANK) != 0U)
01309   {
01310     /* SWAP_BANK_OPT option byte should be modified */
01311     assert_param(IS_OB_USER_SWAP_BANK(UserConfig & FLASH_OPTSR_SWAP_BANK_OPT));
01312 
01313     /* Set value and mask for SWAP_BANK_OPT option byte */
01314     optr_reg_val |= (UserConfig & FLASH_OPTSR_SWAP_BANK_OPT);
01315     optr_reg_mask |= FLASH_OPTSR_SWAP_BANK_OPT;
01316   }
01317 #endif /* DUAL_BANK */
01318 
01319   if((UserType & OB_USER_IOHSLV) != 0U)
01320   {
01321     /* IOHSLV_OPT option byte should be modified */
01322     assert_param(IS_OB_USER_IOHSLV(UserConfig & FLASH_OPTSR_IO_HSLV));
01323 
01324     /* Set value and mask for IOHSLV_OPT option byte */
01325     optr_reg_val |= (UserConfig & FLASH_OPTSR_IO_HSLV);
01326     optr_reg_mask |= FLASH_OPTSR_IO_HSLV;
01327   }
01328 
01329 #if defined (FLASH_OPTSR_VDDMMC_HSLV)
01330   if((UserType & OB_USER_VDDMMC_HSLV) != 0U)
01331   {
01332     /* VDDMMC_HSLV option byte should be modified */
01333     assert_param(IS_OB_USER_VDDMMC_HSLV(UserConfig & FLASH_OPTSR_VDDMMC_HSLV));
01334 
01335     /* Set value and mask for VDDMMC_HSLV option byte */
01336     optr_reg_val |= (UserConfig & FLASH_OPTSR_VDDMMC_HSLV);
01337     optr_reg_mask |= FLASH_OPTSR_VDDMMC_HSLV;
01338   }
01339 #endif /* FLASH_OPTSR_VDDMMC_HSLV */
01340 
01341   /* Configure the option bytes register */
01342   MODIFY_REG(FLASH->OPTSR_PRG, optr_reg_mask, optr_reg_val);
01343 }
01344 
01345 #if defined(DUAL_CORE)
01346 /**
01347   * @brief  Return the FLASH User Option Byte value.
01348   * @retval The FLASH User Option Bytes values
01349   *         IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
01350   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
01351   *         SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
01352   *         nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
01353   */
01354 #else
01355 /**
01356   * @brief  Return the FLASH User Option Byte value.
01357   * @retval The FLASH User Option Bytes values
01358   *         IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
01359   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
01360   *         SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
01361   */
01362 #endif /*DUAL_CORE*/
01363 static uint32_t FLASH_OB_GetUser(void)
01364 {
01365   uint32_t userConfig = READ_REG(FLASH->OPTSR_CUR);
01366   userConfig &= (~(FLASH_OPTSR_BOR_LEV | FLASH_OPTSR_RDP));
01367 
01368   return userConfig;
01369 }
01370 
01371 /**
01372   * @brief  Configure the Proprietary code readout protection of the desired addresses
01373   *
01374   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
01375   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
01376   * @note   To validate the PCROP options, the option bytes must be reloaded
01377   *         through the call of the HAL_FLASH_OB_Launch() function.
01378   *
01379   * @param  PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not
01380   *         when RDP level decreased from Level 1 to Level 0, or after a bank erase with protection removal
01381   *         This parameter must be a value of @arg FLASHEx_OB_PCROP_RDP enumeration
01382   *
01383   * @param  PCROPStartAddr specifies the start address of the Proprietary code readout protection
01384   *          This parameter can be an address between begin and end of the bank
01385   *
01386   * @param  PCROPEndAddr specifies the end address of the Proprietary code readout protection
01387   *          This parameter can be an address between PCROPStartAddr and end of the bank
01388   *
01389   * @param  Banks the specific bank to apply PCROP protection
01390   *          This parameter can be one of the following values:
01391   *            @arg FLASH_BANK_1: PCROP on specified bank1 area
01392   *            @arg FLASH_BANK_2: PCROP on specified bank2 area
01393   *            @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks)
01394   *
01395   * @retval None
01396   */
01397 static void FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks)
01398 {
01399   /* Check the parameters */
01400   assert_param(IS_FLASH_BANK(Banks));
01401   assert_param(IS_OB_PCROP_RDP(PCROPConfig));
01402 
01403   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
01404   {
01405     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr));
01406     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr));
01407 
01408     /* Configure the Proprietary code readout protection */
01409     FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8)                                 | \
01410                        (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
01411                        PCROPConfig;
01412   }
01413 
01414 #if defined (DUAL_BANK)
01415   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
01416   {
01417     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPStartAddr));
01418     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPEndAddr));
01419 
01420     /* Configure the Proprietary code readout protection */
01421     FLASH->PRAR_PRG2 = ((PCROPStartAddr - FLASH_BANK2_BASE) >> 8)                                 | \
01422                        (((PCROPEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
01423                        PCROPConfig;
01424   }
01425 #endif /* DUAL_BANK */
01426 }
01427 
01428 /**
01429   * @brief  Get the Proprietary code readout protection configuration on a given Bank
01430   *
01431   * @param  PCROPConfig indicates if the PCROP area for the given Bank shall be erased or not
01432   *         when RDP level decreased from Level 1 to Level 0 or after a bank erase with protection removal
01433   *
01434   * @param  PCROPStartAddr gives the start address of the Proprietary code readout protection of the bank
01435   *
01436   * @param  PCROPEndAddr gives the end address of the Proprietary code readout protection of the bank
01437   *
01438   * @param  Bank the specific bank to apply PCROP protection
01439   *          This parameter can be exclusively one of the following values:
01440   *            @arg FLASH_BANK_1: PCROP on specified bank1 area
01441   *            @arg FLASH_BANK_2: PCROP on specified bank2 area
01442   *            @arg FLASH_BANK_BOTH: is  not allowed here
01443   *
01444   * @retval None
01445   */
01446 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr, uint32_t Bank)
01447 {
01448   uint32_t regvalue = 0;
01449   uint32_t bankBase = 0;
01450 
01451   if(Bank == FLASH_BANK_1)
01452   {
01453     regvalue = FLASH->PRAR_CUR1;
01454     bankBase = FLASH_BANK1_BASE;
01455   }
01456 
01457 #if defined (DUAL_BANK)
01458   if(Bank == FLASH_BANK_2)
01459   {
01460     regvalue = FLASH->PRAR_CUR2;
01461     bankBase = FLASH_BANK2_BASE;
01462   }
01463 #endif /* DUAL_BANK */
01464 
01465   (*PCROPConfig) =  (regvalue & FLASH_PRAR_DMEP);
01466 
01467   (*PCROPStartAddr) = ((regvalue & FLASH_PRAR_PROT_AREA_START) << 8) + bankBase;
01468   (*PCROPEndAddr) = (regvalue & FLASH_PRAR_PROT_AREA_END) >> FLASH_PRAR_PROT_AREA_END_Pos;
01469   (*PCROPEndAddr) = ((*PCROPEndAddr) << 8) + bankBase;
01470 }
01471 
01472 /**
01473   * @brief  Set the BOR Level.
01474   * @param  Level specifies the Option Bytes BOR Reset Level.
01475   *          This parameter can be one of the following values:
01476   *            @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
01477   *            @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
01478   *            @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
01479   *            @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
01480   * @retval None
01481   */
01482 static void FLASH_OB_BOR_LevelConfig(uint32_t Level)
01483 {
01484   assert_param(IS_OB_BOR_LEVEL(Level));
01485 
01486   /* Configure BOR_LEV option byte */
01487   MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_BOR_LEV, Level);
01488 }
01489 
01490 /**
01491   * @brief  Get the BOR Level.
01492   * @retval The Option Bytes BOR Reset Level.
01493   *            This parameter can be one of the following values:
01494   *            @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
01495   *            @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
01496   *            @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
01497   *            @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
01498   */
01499 static uint32_t FLASH_OB_GetBOR(void)
01500 {
01501   return (FLASH->OPTSR_CUR & FLASH_OPTSR_BOR_LEV);
01502 }
01503 
01504 /**
01505   * @brief  Set Boot address
01506   * @param  BootOption Boot address option byte to be programmed,
01507   *                     This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
01508                         (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
01509   *
01510   * @param  BootAddress0 Specifies the Boot Address 0
01511   * @param  BootAddress1 Specifies the Boot Address 1
01512   * @retval HAL Status
01513   */
01514 static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
01515 {
01516   /* Check the parameters */
01517   assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
01518 
01519   if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
01520   {
01521     /* Check the parameters */
01522     assert_param(IS_BOOT_ADDRESS(BootAddress0));
01523 
01524     /* Configure CM7 BOOT ADD0 */
01525 #if defined(DUAL_CORE)
01526     MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD0, (BootAddress0 >> 16));
01527 #else /* Single Core*/
01528     MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD0, (BootAddress0 >> 16));
01529 #endif /* DUAL_CORE */
01530   }
01531 
01532   if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
01533   {
01534     /* Check the parameters */
01535     assert_param(IS_BOOT_ADDRESS(BootAddress1));
01536 
01537     /* Configure CM7 BOOT ADD1 */
01538 #if defined(DUAL_CORE)
01539     MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD1, BootAddress1);
01540 #else /* Single Core*/
01541     MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD1, BootAddress1);
01542 #endif /* DUAL_CORE */
01543   }
01544 }
01545 
01546 /**
01547   * @brief  Get Boot address
01548   * @param  BootAddress0 Specifies the Boot Address 0.
01549   * @param  BootAddress1 Specifies the Boot Address 1.
01550   * @retval HAL Status
01551   */
01552 static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
01553 {
01554   uint32_t regvalue;
01555 
01556 #if defined(DUAL_CORE)
01557   regvalue = FLASH->BOOT7_CUR;
01558 
01559   (*BootAddress0) = (regvalue & FLASH_BOOT7_BCM7_ADD0) << 16;
01560   (*BootAddress1) = (regvalue & FLASH_BOOT7_BCM7_ADD1);
01561 #else /* Single Core */
01562   regvalue = FLASH->BOOT_CUR;
01563 
01564   (*BootAddress0) = (regvalue & FLASH_BOOT_ADD0) << 16;
01565   (*BootAddress1) = (regvalue & FLASH_BOOT_ADD1);
01566 #endif /* DUAL_CORE */
01567 }
01568 
01569 #if defined(DUAL_CORE)
01570 /**
01571   * @brief  Set CM4 Boot address
01572   * @param  BootOption Boot address option byte to be programmed,
01573   *                     This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
01574                         (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
01575   *
01576   * @param  BootAddress0 Specifies the CM4 Boot Address 0.
01577   * @param  BootAddress1 Specifies the CM4 Boot Address 1.
01578   * @retval HAL Status
01579   */
01580 static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
01581 {
01582   /* Check the parameters */
01583   assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
01584 
01585   if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
01586   {
01587     /* Check the parameters */
01588     assert_param(IS_BOOT_ADDRESS(BootAddress0));
01589 
01590     /* Configure CM4 BOOT ADD0 */
01591     MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD0, (BootAddress0 >> 16));
01592 
01593   }
01594 
01595   if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
01596   {
01597     /* Check the parameters */
01598     assert_param(IS_BOOT_ADDRESS(BootAddress1));
01599 
01600     /* Configure CM4 BOOT ADD1 */
01601     MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD1, BootAddress1);
01602   }
01603 }
01604 
01605 /**
01606   * @brief  Get CM4 Boot address
01607   * @param  BootAddress0 Specifies the CM4 Boot Address 0.
01608   * @param  BootAddress1 Specifies the CM4 Boot Address 1.
01609   * @retval HAL Status
01610   */
01611 static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
01612 {
01613   uint32_t regvalue;
01614 
01615   regvalue = FLASH->BOOT4_CUR;
01616 
01617   (*BootAddress0) = (regvalue & FLASH_BOOT4_BCM4_ADD0) << 16;
01618   (*BootAddress1) = (regvalue & FLASH_BOOT4_BCM4_ADD1);
01619 }
01620 #endif /*DUAL_CORE*/
01621 
01622 /**
01623   * @brief  Set secure area configuration
01624   * @param  SecureAreaConfig specify if the secure area will be deleted or not
01625   *         when RDP level decreased from Level 1 to Level 0 or during a mass erase.
01626   *
01627   * @param  SecureAreaStartAddr Specifies the secure area start address
01628   * @param  SecureAreaEndAddr Specifies the secure area end address
01629   * @param  Banks the specific bank to apply Security protection
01630   *          This parameter can be one of the following values:
01631   *            @arg FLASH_BANK_1: Secure area on specified bank1 area
01632   *            @arg FLASH_BANK_2: Secure area on specified bank2 area
01633   *            @arg FLASH_BANK_BOTH: Secure area on specified bank1 and bank2 area (same config will be applied on both banks)
01634   * @retval None
01635   */
01636 static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks)
01637 {
01638   /* Check the parameters */
01639   assert_param(IS_FLASH_BANK(Banks));
01640   assert_param(IS_OB_SECURE_RDP(SecureAreaConfig));
01641 
01642   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
01643   {
01644     /* Check the parameters */
01645     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaStartAddr));
01646     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaEndAddr));
01647 
01648     /* Configure the secure area */
01649     FLASH->SCAR_PRG1 = ((SecureAreaStartAddr - FLASH_BANK1_BASE) >> 8)                                | \
01650                        (((SecureAreaEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
01651                        (SecureAreaConfig & FLASH_SCAR_DMES);
01652   }
01653 
01654 #if defined (DUAL_BANK)
01655   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
01656   {
01657     /* Check the parameters */
01658     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaStartAddr));
01659     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaEndAddr));
01660 
01661     /* Configure the secure area */
01662     FLASH->SCAR_PRG2 = ((SecureAreaStartAddr - FLASH_BANK2_BASE) >> 8)                                | \
01663                        (((SecureAreaEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
01664                        (SecureAreaConfig & FLASH_SCAR_DMES);
01665   }
01666 #endif /* DUAL_BANK */
01667 }
01668 
01669 /**
01670   * @brief  Get secure area configuration
01671   * @param  SecureAreaConfig indicates if the secure area will be deleted or not
01672   *         when RDP level decreased from Level 1 to Level 0 or during a mass erase.
01673   * @param  SecureAreaStartAddr gives the secure area start address
01674   * @param  SecureAreaEndAddr gives the secure area end address
01675   * @param  Bank Specifies the Bank
01676   * @retval None
01677   */
01678 static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank)
01679 {
01680   uint32_t regvalue = 0;
01681   uint32_t bankBase = 0;
01682 
01683   /* Check Bank parameter value */
01684   if(Bank == FLASH_BANK_1)
01685   {
01686     regvalue = FLASH->SCAR_CUR1;
01687     bankBase = FLASH_BANK1_BASE;
01688   }
01689 
01690 #if defined (DUAL_BANK)
01691   if(Bank == FLASH_BANK_2)
01692   {
01693     regvalue = FLASH->SCAR_CUR2;
01694     bankBase = FLASH_BANK2_BASE;
01695   }
01696 #endif /* DUAL_BANK */
01697 
01698   /* Get the secure area settings */
01699   (*SecureAreaConfig) = (regvalue & FLASH_SCAR_DMES);
01700   (*SecureAreaStartAddr) = ((regvalue & FLASH_SCAR_SEC_AREA_START) << 8) + bankBase;
01701   (*SecureAreaEndAddr) = (regvalue & FLASH_SCAR_SEC_AREA_END) >> FLASH_SCAR_SEC_AREA_END_Pos;
01702   (*SecureAreaEndAddr) = ((*SecureAreaEndAddr) << 8) + bankBase;
01703 }
01704 
01705 /**
01706   * @brief  Add a CRC sector to the list of sectors on which the CRC will be calculated
01707   * @param  Sector Specifies the CRC sector number
01708   * @param  Bank Specifies the Bank
01709   * @retval None
01710   */
01711 static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank)
01712 {
01713   /* Check the parameters */
01714   assert_param(IS_FLASH_SECTOR(Sector));
01715 
01716   if (Bank == FLASH_BANK_1)
01717   {
01718     /* Clear CRC sector */
01719     FLASH->CRCCR1 &= (~FLASH_CRCCR_CRC_SECT);
01720 
01721     /* Select CRC Sector and activate ADD_SECT bit */
01722     FLASH->CRCCR1 |= Sector | FLASH_CRCCR_ADD_SECT;
01723   }
01724 #if defined (DUAL_BANK)
01725   else
01726   {
01727     /* Clear CRC sector */
01728     FLASH->CRCCR2 &= (~FLASH_CRCCR_CRC_SECT);
01729 
01730     /* Select CRC Sector and activate ADD_SECT bit */
01731     FLASH->CRCCR2 |= Sector | FLASH_CRCCR_ADD_SECT;
01732   }
01733 #endif /* DUAL_BANK */
01734 }
01735 
01736 /**
01737   * @brief  Select CRC start and end memory addresses on which the CRC will be calculated
01738   * @param  CRCStartAddr Specifies the CRC start address
01739   * @param  CRCEndAddr Specifies the CRC end address
01740   * @param  Bank Specifies the Bank
01741   * @retval None
01742   */
01743 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank)
01744 {
01745   if (Bank == FLASH_BANK_1)
01746   {
01747     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCStartAddr));
01748     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCEndAddr));
01749 
01750     /* Write CRC Start and End addresses */
01751     FLASH->CRCSADD1 = CRCStartAddr;
01752     FLASH->CRCEADD1 = CRCEndAddr;
01753   }
01754 #if defined (DUAL_BANK)
01755   else
01756   {
01757     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCStartAddr));
01758     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCEndAddr));
01759 
01760     /* Write CRC Start and End addresses */
01761     FLASH->CRCSADD2 = CRCStartAddr;
01762     FLASH->CRCEADD2 = CRCEndAddr;
01763   }
01764 #endif /* DUAL_BANK */
01765 }
01766 /**
01767   * @}
01768   */
01769 
01770 #if defined (FLASH_OTPBL_LOCKBL)
01771 /**
01772   * @brief  Configure the OTP Block Lock.
01773   * @param  OTP_Block specifies the OTP Block to lock.
01774   *         This parameter can be a value of @ref FLASHEx_OTP_Blocks
01775   * @retval None
01776   */
01777 static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block)
01778 {
01779   /* Check the parameters */
01780   assert_param(IS_OTP_BLOCK(OTP_Block));
01781 
01782   /* Configure the OTP Block lock in the option bytes register */
01783   FLASH->OTPBL_PRG |= (OTP_Block & FLASH_OTPBL_LOCKBL);
01784 }
01785 
01786 /**
01787   * @brief  Get the OTP Block Lock.
01788   * @retval OTP_Block specifies the OTP Block to lock.
01789   *         This return value can be a value of @ref FLASHEx_OTP_Blocks
01790   */
01791 static uint32_t FLASH_OB_OTP_GetLock(void)
01792 {
01793   return (FLASH->OTPBL_CUR);
01794 }
01795 #endif /* FLASH_OTPBL_LOCKBL */
01796 
01797 #if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
01798 /**
01799   * @brief  Configure the TCM / AXI Shared RAM.
01800   * @param  SharedRamConfig specifies the Shared RAM configuration.
01801   *         This parameter can be a value of @ref FLASHEx_OB_TCM_AXI_SHARED
01802   * @retval None
01803   */
01804 static void FLASH_OB_SharedRAM_Config(uint32_t SharedRamConfig)
01805 {
01806   /* Check the parameters */
01807   assert_param(IS_OB_USER_TCM_AXI_SHARED(SharedRamConfig));
01808 
01809   /* Configure the TCM / AXI Shared RAM in the option bytes register */
01810   MODIFY_REG(FLASH->OPTSR2_PRG, FLASH_OPTSR2_TCM_AXI_SHARED, SharedRamConfig);
01811 }
01812 
01813 /**
01814   * @brief  Get the TCM / AXI Shared RAM configuration.
01815   * @retval SharedRamConfig returns the TCM / AXI Shared RAM configuration.
01816   *         This return value can be a value of @ref FLASHEx_OB_TCM_AXI_SHARED
01817   */
01818 static uint32_t FLASH_OB_SharedRAM_GetConfig(void)
01819 {
01820   return (FLASH->OPTSR2_CUR & FLASH_OPTSR2_TCM_AXI_SHARED);
01821 }
01822 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
01823 
01824 #if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
01825 /**
01826   * @brief  Configure the CPU Frequency Boost.
01827   * @param  FreqBoost specifies the CPU Frequency Boost state.
01828   *         This parameter can be a value of @ref FLASHEx_OB_CPUFREQ_BOOST
01829   * @retval None
01830   */
01831 static void FLASH_OB_CPUFreq_BoostConfig(uint32_t FreqBoost)
01832 {
01833   /* Check the parameters */
01834   assert_param(IS_OB_USER_CPUFREQ_BOOST(FreqBoost));
01835 
01836   /* Configure the CPU Frequency Boost in the option bytes register */
01837   MODIFY_REG(FLASH->OPTSR2_PRG, FLASH_OPTSR2_CPUFREQ_BOOST, FreqBoost);
01838 }
01839 
01840 /**
01841   * @brief  Get the CPU Frequency Boost state.
01842   * @retval FreqBoost returns the CPU Frequency Boost state.
01843   *         This return value can be a value of @ref FLASHEx_OB_CPUFREQ_BOOST
01844   */
01845 static uint32_t FLASH_OB_CPUFreq_GetBoost(void)
01846 {
01847   return (FLASH->OPTSR2_CUR & FLASH_OPTSR2_CPUFREQ_BOOST);
01848 }
01849 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
01850 
01851 #endif /* HAL_FLASH_MODULE_ENABLED */
01852 
01853 /**
01854   * @}
01855   */
01856 
01857 /**
01858   * @}
01859   */
01860