Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_flash_ex.c
0004   * @author  MCD Application Team
0005   * @brief   Extended FLASH HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the FLASH extension peripheral:
0008   *           + Extended programming operations functions
0009   *
0010  @verbatim
0011  ==============================================================================
0012                    ##### Flash Extension features #####
0013   ==============================================================================
0014 
0015   [..] Comparing to other previous devices, the FLASH interface for STM32H7xx
0016        devices contains the following additional features
0017 
0018        (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write
0019            capability (RWW)
0020        (+) Dual bank memory organization
0021        (+) PCROP protection for all banks
0022        (+) Global readout protection (RDP)
0023        (+) Write protection
0024        (+) Secure access only protection
0025        (+) Bank / register swapping (when Dual-Bank)
0026        (+) Cyclic Redundancy Check (CRC)
0027 
0028                         ##### How to use this driver #####
0029  ==============================================================================
0030   [..] This driver provides functions to configure and program the FLASH memory
0031        of all STM32H7xx devices. It includes
0032       (#) FLASH Memory Erase functions:
0033            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
0034                 HAL_FLASH_Lock() functions
0035            (++) Erase function: Sector erase, bank erase and dual-bank mass erase
0036            (++) There are two modes of erase :
0037              (+++) Polling Mode using HAL_FLASHEx_Erase()
0038              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
0039 
0040       (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to:
0041         (++) Set/Reset the write protection per bank
0042         (++) Set the Read protection Level
0043         (++) Set the BOR level
0044         (++) Program the user Option Bytes
0045         (++) PCROP protection configuration and control per bank
0046         (++) Secure area configuration and control per bank
0047         (++) Core Boot address configuration
0048         (++) TCM / AXI shared RAM configuration
0049         (++) CPU Frequency Boost configuration
0050 
0051       (#) FLASH Memory Lock and unlock per Bank: HAL_FLASHEx_Lock_Bank1(), HAL_FLASHEx_Unlock_Bank1(),
0052           HAL_FLASHEx_Lock_Bank2() and HAL_FLASHEx_Unlock_Bank2() functions
0053 
0054       (#) FLASH CRC computation function: Use HAL_FLASHEx_ComputeCRC() to:
0055           (++) Enable CRC feature
0056           (++) Program the desired burst size
0057           (++) Define the user Flash Area on which the CRC has be computed
0058           (++) Perform the CRC computation
0059           (++) Disable CRC feature
0060 
0061       (#) Error correction code error functions:
0062           (++) Use the HAL_FLASHEx_EnableEccCorrectionInterrupt() and HAL_FLASHEx_DisableEccCorrectionInterrupt()
0063                functions to enable and disable the FLASH ECC correction interruption.
0064           (++) Use the HAL_FLASHEx_EnableEccDetectionInterrupt() and HAL_FLASHEx_DisableEccDetectionInterrupt()
0065                functions to enable and disable the FLASH ECC Detection interruption.
0066           (++) Handle ECCD interrupt by calling HAL_FLASHEx_BusFault_IRQHandler()
0067           (++) Use HAL_FLASHEx_BusFault_IRQHandler() function called under BusFault_IRQHandler() interrupt subroutine
0068                to handle the ECCD interrupt.
0069           (++) Use HAL_FLASHEx_GetEccInfo() function to get the flash ECC fail information.
0070 
0071  @endverbatim
0072   ******************************************************************************
0073   * @attention
0074   *
0075   * Copyright (c) 2017 STMicroelectronics.
0076   * All rights reserved.
0077   *
0078   * This software is licensed under terms that can be found in the LICENSE file in
0079   * the root directory of this software component.
0080   * If no LICENSE file comes with this software, it is provided AS-IS.
0081   ******************************************************************************
0082   */
0083 
0084 /* Includes ------------------------------------------------------------------*/
0085 #include "stm32h7xx_hal.h"
0086 
0087 /** @addtogroup STM32H7xx_HAL_Driver
0088   * @{
0089   */
0090 
0091 /** @defgroup FLASHEx  FLASHEx
0092   * @ingroup RTEMSBSPsARMSTM32H7
0093   * @brief FLASH HAL Extension module driver
0094   * @{
0095   */
0096 
0097 #ifdef HAL_FLASH_MODULE_ENABLED
0098 
0099 /* Private typedef -----------------------------------------------------------*/
0100 /* Private define ------------------------------------------------------------*/
0101 /** @addtogroup FLASHEx_Private_Constants
0102   * @{
0103   */
0104 #define FLASH_TIMEOUT_VALUE       50000U /* 50 s */
0105 
0106 /**
0107   * @}
0108   */
0109 /* Private macro -------------------------------------------------------------*/
0110 /* Private variables ---------------------------------------------------------*/
0111 /* Private function prototypes -----------------------------------------------*/
0112 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
0113   * @ingroup RTEMSBSPsARMSTM32H7
0114   * @{
0115   */
0116 static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks);
0117 static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks);
0118 static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank);
0119 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank);
0120 static void FLASH_OB_RDPConfig(uint32_t RDPLevel);
0121 static uint32_t FLASH_OB_GetRDP(void);
0122 static void FLASH_OB_PCROPConfig(uint32_t PCROConfigRDP, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks);
0123 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr,uint32_t *PCROPEndAddr, uint32_t Bank);
0124 static void FLASH_OB_BOR_LevelConfig(uint32_t Level);
0125 static uint32_t FLASH_OB_GetBOR(void);
0126 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
0127 static uint32_t FLASH_OB_GetUser(void);
0128 static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
0129 static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
0130 static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks);
0131 static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank);
0132 static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank);
0133 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank);
0134 
0135 #if defined (DUAL_CORE)
0136 static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
0137 static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
0138 #endif /*DUAL_CORE*/
0139 
0140 #if defined (FLASH_OTPBL_LOCKBL)
0141 static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block);
0142 static uint32_t FLASH_OB_OTP_GetLock(void);
0143 #endif /* FLASH_OTPBL_LOCKBL */
0144 
0145 #if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
0146 static void FLASH_OB_SharedRAM_Config(uint32_t SharedRamConfig);
0147 static uint32_t FLASH_OB_SharedRAM_GetConfig(void);
0148 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
0149 
0150 #if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
0151 static void FLASH_OB_CPUFreq_BoostConfig(uint32_t FreqBoost);
0152 static uint32_t FLASH_OB_CPUFreq_GetBoost(void);
0153 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
0154 /**
0155   * @}
0156   */
0157 
0158 /* Exported functions ---------------------------------------------------------*/
0159 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
0160   * @ingroup RTEMSBSPsARMSTM32H7
0161   * @{
0162   */
0163 
0164 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
0165   * @ingroup RTEMSBSPsARMSTM32H7
0166  *  @brief   Extended IO operation functions
0167  *
0168 @verbatim
0169  ===============================================================================
0170                 ##### Extended programming operation functions #####
0171  ===============================================================================
0172     [..]
0173     This subsection provides a set of functions allowing to manage the Extension FLASH
0174     programming operations Operations.
0175 
0176 @endverbatim
0177   * @{
0178   */
0179 /**
0180   * @brief  Perform a mass erase or erase the specified FLASH memory sectors
0181   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
0182   *         contains the configuration information for the erasing.
0183   *
0184   * @param[out]  SectorError pointer to variable  that contains the configuration
0185   *          information on faulty sector in case of error (0xFFFFFFFF means that all
0186   *          the sectors have been correctly erased)
0187   *
0188   * @retval HAL Status
0189   */
0190 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
0191 {
0192   HAL_StatusTypeDef status = HAL_OK;
0193   uint32_t sector_index;
0194 
0195   /* Check the parameters */
0196   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
0197   assert_param(IS_FLASH_BANK(pEraseInit->Banks));
0198 
0199   /* Process Locked */
0200   __HAL_LOCK(&pFlash);
0201 
0202   /* Reset error code */
0203   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
0204 
0205   /* Wait for last operation to be completed on Bank1 */
0206   if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
0207   {
0208     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
0209     {
0210       status = HAL_ERROR;
0211     }
0212   }
0213 
0214 #if defined (DUAL_BANK)
0215   /* Wait for last operation to be completed on Bank2 */
0216   if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
0217   {
0218     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
0219     {
0220       status = HAL_ERROR;
0221     }
0222   }
0223 #endif /* DUAL_BANK */
0224 
0225   if(status == HAL_OK)
0226   {
0227     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
0228     {
0229       /* Mass erase to be done */
0230       FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
0231 
0232       /* Wait for last operation to be completed on Bank 1 */
0233       if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
0234       {
0235         if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
0236         {
0237           status = HAL_ERROR;
0238         }
0239         /* if the erase operation is completed, disable the Bank1 BER Bit */
0240         FLASH->CR1 &= (~FLASH_CR_BER);
0241       }
0242 #if defined (DUAL_BANK)
0243       /* Wait for last operation to be completed on Bank 2 */
0244       if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
0245       {
0246         if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
0247         {
0248           status = HAL_ERROR;
0249         }
0250         /* if the erase operation is completed, disable the Bank2 BER Bit */
0251         FLASH->CR2 &= (~FLASH_CR_BER);
0252       }
0253 #endif /* DUAL_BANK */
0254     }
0255     else
0256     {
0257       /*Initialization of SectorError variable*/
0258       *SectorError = 0xFFFFFFFFU;
0259 
0260       /* Erase by sector by sector to be done*/
0261       for(sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); sector_index++)
0262       {
0263         FLASH_Erase_Sector(sector_index, pEraseInit->Banks, pEraseInit->VoltageRange);
0264 
0265         if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
0266         {
0267           /* Wait for last operation to be completed */
0268           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
0269 
0270           /* If the erase operation is completed, disable the SER Bit */
0271           FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
0272         }
0273 #if defined (DUAL_BANK)
0274         if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
0275         {
0276           /* Wait for last operation to be completed */
0277           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
0278 
0279           /* If the erase operation is completed, disable the SER Bit */
0280           FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
0281         }
0282 #endif /* DUAL_BANK */
0283 
0284         if(status != HAL_OK)
0285         {
0286           /* In case of error, stop erase procedure and return the faulty sector */
0287           *SectorError = sector_index;
0288           break;
0289         }
0290       }
0291     }
0292   }
0293 
0294   /* Process Unlocked */
0295   __HAL_UNLOCK(&pFlash);
0296 
0297   return status;
0298 }
0299 
0300 /**
0301   * @brief  Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled
0302   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
0303   *         contains the configuration information for the erasing.
0304   *
0305   * @retval HAL Status
0306   */
0307 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
0308 {
0309   HAL_StatusTypeDef status = HAL_OK;
0310 
0311   /* Check the parameters */
0312   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
0313   assert_param(IS_FLASH_BANK(pEraseInit->Banks));
0314 
0315   /* Process Locked */
0316   __HAL_LOCK(&pFlash);
0317 
0318   /* Reset error code */
0319   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
0320 
0321   /* Wait for last operation to be completed on Bank 1 */
0322   if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
0323   {
0324     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
0325     {
0326       status = HAL_ERROR;
0327     }
0328   }
0329 
0330 #if defined (DUAL_BANK)
0331   /* Wait for last operation to be completed on Bank 2 */
0332   if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
0333   {
0334     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
0335     {
0336       status = HAL_ERROR;
0337     }
0338   }
0339 #endif /* DUAL_BANK */
0340 
0341   if (status != HAL_OK)
0342   {
0343     /* Process Unlocked */
0344     __HAL_UNLOCK(&pFlash);
0345   }
0346   else
0347   {
0348     if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
0349     {
0350       /* Enable End of Operation and Error interrupts for Bank 1 */
0351 #if defined (FLASH_CR_OPERRIE)
0352       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
0353                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
0354 #else
0355       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
0356                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
0357 #endif /* FLASH_CR_OPERRIE */
0358     }
0359 #if defined (DUAL_BANK)
0360     if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
0361     {
0362       /* Enable End of Operation and Error interrupts for Bank 2 */
0363 #if defined (FLASH_CR_OPERRIE)
0364       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
0365                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
0366 #else
0367       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
0368                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
0369 #endif /* FLASH_CR_OPERRIE */
0370     }
0371 #endif /* DUAL_BANK */
0372 
0373     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
0374     {
0375       /*Mass erase to be done*/
0376       if(pEraseInit->Banks == FLASH_BANK_1)
0377       {
0378         pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1;
0379       }
0380 #if defined (DUAL_BANK)
0381       else if(pEraseInit->Banks == FLASH_BANK_2)
0382       {
0383         pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2;
0384       }
0385 #endif /* DUAL_BANK */
0386       else
0387       {
0388         pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE;
0389       }
0390 
0391       FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
0392     }
0393     else
0394     {
0395       /* Erase by sector to be done */
0396 #if defined (DUAL_BANK)
0397       if(pEraseInit->Banks == FLASH_BANK_1)
0398       {
0399         pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
0400       }
0401       else
0402       {
0403         pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2;
0404       }
0405 #else
0406       pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
0407 #endif /* DUAL_BANK */
0408 
0409       pFlash.NbSectorsToErase = pEraseInit->NbSectors;
0410       pFlash.Sector = pEraseInit->Sector;
0411       pFlash.VoltageForErase = pEraseInit->VoltageRange;
0412 
0413       /* Erase first sector and wait for IT */
0414       FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange);
0415     }
0416   }
0417 
0418   return status;
0419 }
0420 
0421 /**
0422   * @brief  Program option bytes
0423   * @param  pOBInit pointer to an FLASH_OBProgramInitTypeDef structure that
0424   *         contains the configuration information for the programming.
0425   *
0426   * @retval HAL Status
0427   */
0428 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
0429 {
0430   HAL_StatusTypeDef status;
0431 
0432   /* Check the parameters */
0433   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
0434 
0435   /* Process Locked */
0436   __HAL_LOCK(&pFlash);
0437 
0438   /* Reset Error Code */
0439   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
0440 
0441   /* Wait for last operation to be completed */
0442   if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
0443   {
0444     status = HAL_ERROR;
0445   }
0446 #if defined (DUAL_BANK)
0447   else if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
0448   {
0449     status = HAL_ERROR;
0450   }
0451 #endif /* DUAL_BANK */
0452   else
0453   {
0454     status = HAL_OK;
0455   }
0456 
0457   if(status == HAL_OK)
0458   {
0459     /*Write protection configuration*/
0460     if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
0461     {
0462       assert_param(IS_WRPSTATE(pOBInit->WRPState));
0463 
0464       if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)
0465       {
0466         /*Enable of Write protection on the selected Sector*/
0467         FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks);
0468       }
0469       else
0470       {
0471         /*Disable of Write protection on the selected Sector*/
0472         FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks);
0473       }
0474     }
0475 
0476     /* Read protection configuration */
0477     if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
0478     {
0479       /* Configure the Read protection level */
0480       FLASH_OB_RDPConfig(pOBInit->RDPLevel);
0481     }
0482 
0483     /* User Configuration */
0484     if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
0485     {
0486       /* Configure the user option bytes */
0487       FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig);
0488     }
0489 
0490     /* PCROP Configuration */
0491     if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
0492     {
0493       assert_param(IS_FLASH_BANK(pOBInit->Banks));
0494 
0495       /*Configure the Proprietary code readout protection */
0496       FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks);
0497     }
0498 
0499     /* BOR Level configuration */
0500     if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
0501     {
0502       FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
0503     }
0504 
0505 #if defined(DUAL_CORE)
0506     /* CM7 Boot Address  configuration */
0507     if((pOBInit->OptionType & OPTIONBYTE_CM7_BOOTADD) == OPTIONBYTE_CM7_BOOTADD)
0508     {
0509       FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
0510     }
0511 
0512     /* CM4 Boot Address  configuration */
0513     if((pOBInit->OptionType & OPTIONBYTE_CM4_BOOTADD) == OPTIONBYTE_CM4_BOOTADD)
0514     {
0515       FLASH_OB_CM4BootAddConfig(pOBInit->CM4BootConfig, pOBInit->CM4BootAddr0, pOBInit->CM4BootAddr1);
0516     }
0517 #else /* Single Core*/
0518     /* Boot Address  configuration */
0519     if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD)
0520     {
0521       FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
0522     }
0523 #endif /*DUAL_CORE*/
0524 
0525     /* Secure area configuration */
0526     if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA)
0527     {
0528       FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks);
0529     }
0530 
0531 #if defined(FLASH_OTPBL_LOCKBL)
0532     /* OTP Block Lock configuration */
0533     if((pOBInit->OptionType & OPTIONBYTE_OTP_LOCK) == OPTIONBYTE_OTP_LOCK)
0534     {
0535       FLASH_OB_OTP_LockConfig(pOBInit->OTPBlockLock);
0536     }
0537 #endif /* FLASH_OTPBL_LOCKBL */
0538 
0539 #if defined(FLASH_OPTSR2_TCM_AXI_SHARED)
0540     /* TCM / AXI Shared RAM configuration */
0541     if((pOBInit->OptionType & OPTIONBYTE_SHARED_RAM) == OPTIONBYTE_SHARED_RAM)
0542     {
0543       FLASH_OB_SharedRAM_Config(pOBInit->SharedRamConfig);
0544     }
0545 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
0546 
0547 #if defined(FLASH_OPTSR2_CPUFREQ_BOOST)
0548     /* CPU Frequency Boost configuration */
0549     if((pOBInit->OptionType & OPTIONBYTE_FREQ_BOOST) == OPTIONBYTE_FREQ_BOOST)
0550     {
0551       FLASH_OB_CPUFreq_BoostConfig(pOBInit->FreqBoostState);
0552     }
0553 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
0554   }
0555 
0556   /* Process Unlocked */
0557   __HAL_UNLOCK(&pFlash);
0558 
0559   return status;
0560 }
0561 
0562 /**
0563   * @brief Get the Option byte configuration
0564   * @param  pOBInit pointer to an FLASH_OBProgramInitTypeDef structure that
0565   *         contains the configuration information for the programming.
0566   * @note   The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2,
0567   *         as this parameter is use to get the given Bank WRP, PCROP and secured area configuration.
0568   *
0569   * @retval None
0570   */
0571 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
0572 {
0573   pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP | OPTIONBYTE_BOR);
0574 
0575   /* Get Read protection level */
0576   pOBInit->RDPLevel = FLASH_OB_GetRDP();
0577 
0578   /* Get the user option bytes */
0579   pOBInit->USERConfig = FLASH_OB_GetUser();
0580 
0581   /*Get BOR Level*/
0582   pOBInit->BORLevel = FLASH_OB_GetBOR();
0583 
0584 #if defined (DUAL_BANK)
0585   if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2))
0586 #else
0587   if (pOBInit->Banks == FLASH_BANK_1)
0588 #endif /* DUAL_BANK */
0589   {
0590     pOBInit->OptionType |= (OPTIONBYTE_WRP | OPTIONBYTE_PCROP | OPTIONBYTE_SECURE_AREA);
0591 
0592     /* Get write protection on the selected area */
0593     FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector), pOBInit->Banks);
0594 
0595     /* Get the Proprietary code readout protection */
0596     FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr), pOBInit->Banks);
0597 
0598     /*Get Bank Secure area*/
0599     FLASH_OB_GetSecureArea(&(pOBInit->SecureAreaConfig), &(pOBInit->SecureAreaStartAddr), &(pOBInit->SecureAreaEndAddr), pOBInit->Banks);
0600   }
0601 
0602   /*Get Boot Address*/
0603   FLASH_OB_GetBootAdd(&(pOBInit->BootAddr0), &(pOBInit->BootAddr1));
0604 #if defined(DUAL_CORE)
0605   pOBInit->OptionType |= OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD;
0606 
0607   /*Get CM4 Boot Address*/
0608   FLASH_OB_GetCM4BootAdd(&(pOBInit->CM4BootAddr0), &(pOBInit->CM4BootAddr1));
0609 #else
0610   pOBInit->OptionType |= OPTIONBYTE_BOOTADD;
0611 #endif /*DUAL_CORE*/
0612 
0613 #if defined (FLASH_OTPBL_LOCKBL)
0614   pOBInit->OptionType |= OPTIONBYTE_OTP_LOCK;
0615 
0616   /* Get OTP Block Lock */
0617   pOBInit->OTPBlockLock = FLASH_OB_OTP_GetLock();
0618 #endif /* FLASH_OTPBL_LOCKBL */
0619 
0620 #if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
0621   pOBInit->OptionType |= OPTIONBYTE_SHARED_RAM;
0622 
0623   /* Get TCM / AXI Shared RAM */
0624   pOBInit->SharedRamConfig = FLASH_OB_SharedRAM_GetConfig();
0625 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
0626 
0627 #if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
0628   pOBInit->OptionType |= OPTIONBYTE_FREQ_BOOST;
0629 
0630   /* Get CPU Frequency Boost */
0631   pOBInit->FreqBoostState = FLASH_OB_CPUFreq_GetBoost();
0632 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
0633 }
0634 
0635 /**
0636   * @brief  Unlock the FLASH Bank1 control registers access
0637   * @retval HAL Status
0638   */
0639 HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void)
0640 {
0641   if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
0642   {
0643     /* Authorize the FLASH Bank1 Registers access */
0644     WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
0645     WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
0646 
0647     /* Verify Flash Bank1 is unlocked */
0648     if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
0649     {
0650       return HAL_ERROR;
0651     }
0652   }
0653 
0654   return HAL_OK;
0655 }
0656 
0657 /**
0658   * @brief  Locks the FLASH Bank1 control registers access
0659   * @retval HAL Status
0660   */
0661 HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void)
0662 {
0663   /* Set the LOCK Bit to lock the FLASH Bank1 Registers access */
0664   SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
0665   return HAL_OK;
0666 }
0667 
0668 #if defined (DUAL_BANK)
0669 /**
0670   * @brief  Unlock the FLASH Bank2 control registers access
0671   * @retval HAL Status
0672   */
0673 HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void)
0674 {
0675   if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
0676   {
0677     /* Authorize the FLASH Bank2 Registers access */
0678     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
0679     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
0680 
0681     /* Verify Flash Bank1 is unlocked */
0682     if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
0683     {
0684       return HAL_ERROR;
0685     }
0686   }
0687 
0688   return HAL_OK;
0689 }
0690 
0691 /**
0692   * @brief  Locks the FLASH Bank2 control registers access
0693   * @retval HAL Status
0694   */
0695 HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void)
0696 {
0697   /* Set the LOCK Bit to lock the FLASH Bank2 Registers access */
0698   SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
0699   return HAL_OK;
0700 }
0701 #endif /* DUAL_BANK */
0702 
0703 /*
0704   * @brief  Perform a CRC computation on the specified FLASH memory area
0705   * @param  pCRCInit pointer to an FLASH_CRCInitTypeDef structure that
0706   *         contains the configuration information for the CRC computation.
0707   * @note   CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7
0708   * @note   The application should avoid running a CRC on PCROP or secure-only
0709   *         user Flash memory area since it may alter the expected CRC value.
0710   *         A special error flag (CRC read error: CRCRDERR) can be used to
0711   *         detect such a case.
0712   * @retval HAL Status
0713 */
0714 HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result)
0715 {
0716   HAL_StatusTypeDef status;
0717   uint32_t sector_index;
0718 
0719   /* Check the parameters */
0720   assert_param(IS_FLASH_BANK_EXCLUSIVE(pCRCInit->Bank));
0721   assert_param(IS_FLASH_TYPECRC(pCRCInit->TypeCRC));
0722 
0723   /* Wait for OB change operation to be completed */
0724   status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
0725 
0726   if (status == HAL_OK)
0727   {
0728     if (pCRCInit->Bank == FLASH_BANK_1)
0729     {
0730       /* Enable CRC feature */
0731       FLASH->CR1 |= FLASH_CR_CRC_EN;
0732 
0733       /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
0734       FLASH->CCR1 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
0735 
0736       /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
0737       FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
0738 
0739       if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
0740       {
0741         /* Clear sectors list */
0742         FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_SECT;
0743 
0744         /* Select CRC sectors */
0745         for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
0746         {
0747           FLASH_CRC_AddSector(sector_index, FLASH_BANK_1);
0748         }
0749       }
0750       else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
0751       {
0752         /* Enable Bank 1 CRC select bit */
0753         FLASH->CRCCR1 |= FLASH_CRCCR_ALL_BANK;
0754       }
0755       else
0756       {
0757         /* Select CRC start and end addresses */
0758         FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_1);
0759       }
0760 
0761       /* Start the CRC calculation */
0762       FLASH->CRCCR1 |= FLASH_CRCCR_START_CRC;
0763 
0764       /* Wait on CRC busy flag */
0765       status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
0766 
0767       /* Return CRC result */
0768       (*CRC_Result) = FLASH->CRCDATA;
0769 
0770       /* Disable CRC feature */
0771       FLASH->CR1 &= (~FLASH_CR_CRC_EN);
0772 
0773       /* Clear CRC flags */
0774       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCEND_BANK1 | FLASH_FLAG_CRCRDERR_BANK1);
0775     }
0776 #if defined (DUAL_BANK)
0777     else
0778     {
0779       /* Enable CRC feature */
0780       FLASH->CR2 |= FLASH_CR_CRC_EN;
0781 
0782       /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
0783       FLASH->CCR2 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
0784 
0785       /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
0786       FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
0787 
0788       if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
0789       {
0790         /* Clear sectors list */
0791         FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_SECT;
0792 
0793         /* Add CRC sectors */
0794         for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
0795         {
0796           FLASH_CRC_AddSector(sector_index, FLASH_BANK_2);
0797         }
0798       }
0799       else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
0800       {
0801         /* Enable Bank 2 CRC select bit */
0802         FLASH->CRCCR2 |= FLASH_CRCCR_ALL_BANK;
0803       }
0804       else
0805       {
0806         /* Select CRC start and end addresses */
0807         FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_2);
0808       }
0809 
0810       /* Start the CRC calculation */
0811       FLASH->CRCCR2 |= FLASH_CRCCR_START_CRC;
0812 
0813       /* Wait on CRC busy flag */
0814       status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
0815 
0816       /* Return CRC result */
0817       (*CRC_Result) = FLASH->CRCDATA;
0818 
0819       /* Disable CRC feature */
0820       FLASH->CR2 &= (~FLASH_CR_CRC_EN);
0821 
0822       /* Clear CRC flags */
0823       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCEND_BANK2 | FLASH_FLAG_CRCRDERR_BANK2);
0824     }
0825 #endif /* DUAL_BANK */
0826   }
0827 
0828   return status;
0829 }
0830 
0831 /**
0832   * @}
0833   */
0834 
0835 #if (USE_FLASH_ECC == 1U)
0836 /** @defgroup FLASHEx_Exported_Functions_Group2 Extended ECC operation functions
0837   *  @brief   Extended ECC operation functions
0838   *
0839 @verbatim
0840  ===============================================================================
0841                   ##### Extended ECC operation functions #####
0842  ===============================================================================
0843     [..]
0844     This subsection provides a set of functions allowing to manage the Extended FLASH
0845     ECC Operations.
0846 
0847 @endverbatim
0848   * @{
0849   */
0850 
0851 /**
0852   * @brief  Enable ECC correction interrupts on FLASH BANK1 and BANK2.
0853   * @param  None
0854   * @retval None
0855   */
0856 void HAL_FLASHEx_EnableEccCorrectionInterrupt(void)
0857 {
0858   __HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR_BANK1);
0859 
0860 #if defined (DUAL_BANK)
0861   __HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR_BANK2);
0862 #endif /* DUAL_BANK */
0863 }
0864 
0865 /**
0866   * @brief  Disable ECC correction interrupts on FLASH BANK1 and BANK2.
0867   * @param  None
0868   * @retval None
0869   */
0870 void HAL_FLASHEx_DisableEccCorrectionInterrupt(void)
0871 {
0872   __HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR_BANK1);
0873 
0874 #if defined (DUAL_BANK)
0875   __HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR_BANK2);
0876 #endif /* DUAL_BANK */
0877 }
0878 
0879 /**
0880   * @brief  Enable ECC correction interrupt on FLASH BANK1.
0881   * @param  None
0882   * @retval None
0883   */
0884 void HAL_FLASHEx_EnableEccCorrectionInterrupt_Bank1(void)
0885 {
0886   __HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR_BANK1);
0887 }
0888 
0889 /**
0890   * @brief  Disable ECC correction interrupt on FLASH BANK1.
0891   * @param  None
0892   * @retval None
0893   */
0894 void HAL_FLASHEx_DisableEccCorrectionInterrupt_Bank1(void)
0895 {
0896   __HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR_BANK1);
0897 }
0898 
0899 #if defined (DUAL_BANK)
0900 /**
0901   * @brief  Enable ECC correction interrupt on FLASH BANK2.
0902   * @param  None
0903   * @retval None
0904   */
0905 void HAL_FLASHEx_EnableEccCorrectionInterrupt_Bank2(void)
0906 {
0907   __HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR_BANK2);
0908 }
0909 
0910 /**
0911   * @brief  Disable ECC correction interrupt on FLASH BANK2.
0912   * @param  None
0913   * @retval None
0914   */
0915 void HAL_FLASHEx_DisableEccCorrectionInterrupt_Bank2(void)
0916 {
0917   __HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR_BANK2);
0918 }
0919 #endif /* DUAL_BANK */
0920 
0921 /**
0922   * @brief  Enable ECC Detection interrupts on FLASH BANK1 and BANK2.
0923   * @param  None
0924   * @retval None
0925   */
0926 void HAL_FLASHEx_EnableEccDetectionInterrupt(void)
0927 {
0928   __HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR_BANK1);
0929 
0930 #if defined (DUAL_BANK)
0931   __HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR_BANK2);
0932 #endif /* DUAL_BANK */
0933 }
0934 
0935 /**
0936   * @brief  Disable ECC Detection interrupts on FLASH BANK1 and BANK2.
0937   * @param  None
0938   * @retval None
0939   */
0940 void HAL_FLASHEx_DisableEccDetectionInterrupt(void)
0941 {
0942   __HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR_BANK1);
0943 
0944 #if defined (DUAL_BANK)
0945   __HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR_BANK2);
0946 #endif /* DUAL_BANK */
0947 }
0948 
0949 /**
0950   * @brief  Enable ECC Detection interrupt on FLASH BANK1.
0951   * @param  None
0952   * @retval None
0953   */
0954 void HAL_FLASHEx_EnableEccDetectionInterrupt_Bank1(void)
0955 {
0956   __HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR_BANK1);
0957 }
0958 
0959 /**
0960   * @brief  Disable ECC correction interrupt on FLASH BANK1.
0961   * @param  None
0962   * @retval None
0963   */
0964 void HAL_FLASHEx_DisableEccDetectionInterrupt_Bank1(void)
0965 {
0966   __HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR_BANK1);
0967 }
0968 
0969 #if defined (DUAL_BANK)
0970 /**
0971   * @brief  Enable ECC Detection interrupt on FLASH BANK2.
0972   * @param  None
0973   * @retval None
0974   */
0975 void HAL_FLASHEx_EnableEccDetectionInterrupt_Bank2(void)
0976 {
0977   __HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR_BANK2);
0978 }
0979 
0980 /**
0981   * @brief  Disable ECC Detection interrupt on FLASH BANK2.
0982   * @param  None
0983   * @retval None
0984   */
0985 void HAL_FLASHEx_DisableEccDetectionInterrupt_Bank2(void)
0986 {
0987   __HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR_BANK2);
0988 }
0989 #endif /* DUAL_BANK */
0990 
0991 /**
0992   * @brief  Get the ECC error information.
0993   * @param  pData Pointer to an FLASH_EccInfoTypeDef structure that contains the
0994   *         ECC error information.
0995   * @note   This function should be called before ECC bit is cleared
0996   *         (in callback function)
0997   * @retval None
0998   */
0999 void HAL_FLASHEx_GetEccInfo(FLASH_EccInfoTypeDef *pData)
1000 {
1001   uint32_t errorflag;
1002 
1003   /* Check FLASH Bank1 ECC single correction and double detection error flags */
1004   errorflag = FLASH->SR1 & (FLASH_FLAG_SNECCERR_BANK1 | FLASH_FLAG_DBECCERR_BANK1);
1005   if(errorflag != 0U)
1006   {
1007     pData->Area = FLASH_ECC_AREA_USER_BANK1;
1008     pData->Address = ((((FLASH->ECC_FA1 & FLASH_ECC_FA_FAIL_ECC_ADDR))* FLASH_NB_32BITWORD_IN_FLASHWORD * 4) + FLASH_BANK1_BASE);
1009   }
1010 #if defined (DUAL_BANK)
1011   /* Check FLASH Bank2 ECC single correction and double detection error flags */
1012   errorflag = FLASH->SR2 & (FLASH_FLAG_SNECCERR_BANK2 | FLASH_FLAG_DBECCERR_BANK2);
1013   if(errorflag != 0U)
1014   {
1015     pData->Area = FLASH_ECC_AREA_USER_BANK2;
1016     pData->Address = ((((FLASH->ECC_FA2 & FLASH_ECC_FA_FAIL_ECC_ADDR))* FLASH_NB_32BITWORD_IN_FLASHWORD * 4) + FLASH_BANK2_BASE);
1017   }
1018 #endif /* DUAL_BANK */
1019 }
1020 
1021 /**
1022   * @brief Handle Flash ECC Detection interrupt request.
1023   * @retval None
1024   */
1025 void HAL_FLASHEx_BusFault_IRQHandler(void)
1026 {
1027   /* Check if the ECC double error occured*/
1028   if ((FLASH->SR1 & FLASH_FLAG_DBECCERR_BANK1)  != 0)
1029   {
1030     /* FLASH ECC detection user callback */
1031     HAL_FLASHEx_EccDetectionCallback();
1032 
1033     /* Clear Bank 1 ECC double detection error flag
1034     note : this step will clear all the informations related to the flash ECC detection
1035     */
1036     __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_DBECCERR_BANK1);
1037   }
1038 #if defined (DUAL_BANK)
1039   /* Check if the ECC double error occured*/
1040   if ((FLASH->SR2 & FLASH_FLAG_DBECCERR_BANK2)  != 0)
1041   {
1042     /* FLASH ECC detection user callback */
1043     HAL_FLASHEx_EccDetectionCallback();
1044 
1045     /* Clear Bank 2 ECC double detection error flag
1046     note : this step will clear all the informations related to the flash ECC detection
1047     */
1048     __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_DBECCERR_BANK2);
1049   }
1050 #endif /* DUAL_BANK */
1051 }
1052 
1053 /**
1054   * @brief  FLASH ECC Correction interrupt callback.
1055   * @retval None
1056   */
1057 __weak void HAL_FLASHEx_EccCorrectionCallback(void)
1058 {
1059   /* NOTE : This function should not be modified, when the callback is needed,
1060             the HAL_FLASHEx_EccCorrectionCallback could be implemented in the user file
1061    */
1062 }
1063 
1064 /**
1065   * @brief  FLASH ECC Detection interrupt callback.
1066   * @retval None
1067   */
1068 __weak void HAL_FLASHEx_EccDetectionCallback(void)
1069 {
1070   /* NOTE : This function should not be modified, when the callback is needed,
1071             the HAL_FLASHEx_EccDetectionCallback could be implemented in the user file
1072    */
1073 }
1074 
1075 /**
1076   * @}
1077   */
1078 #endif /* USE_FLASH_ECC */
1079 
1080 /**
1081   * @}
1082   */
1083 
1084 /* Private functions ---------------------------------------------------------*/
1085 
1086 /** @addtogroup FLASHEx_Private_Functions
1087   * @{
1088   */
1089 
1090 /**
1091   * @brief  Mass erase of FLASH memory
1092   * @param  VoltageRange The device program/erase parallelism.
1093   *          This parameter can be one of the following values:
1094   *            @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
1095   *            @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
1096   *            @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
1097   *            @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
1098   *
1099   * @param  Banks Banks to be erased
1100   *          This parameter can be one of the following values:
1101   *            @arg FLASH_BANK_1: Bank1 to be erased
1102   *            @arg FLASH_BANK_2: Bank2 to be erased
1103   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
1104   *
1105   * @retval HAL Status
1106   */
1107 static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks)
1108 {
1109   /* Check the parameters */
1110 #if defined (FLASH_CR_PSIZE)
1111   assert_param(IS_VOLTAGERANGE(VoltageRange));
1112 #else
1113   UNUSED(VoltageRange);
1114 #endif /* FLASH_CR_PSIZE */
1115   assert_param(IS_FLASH_BANK(Banks));
1116 
1117 #if defined (DUAL_BANK)
1118   /* Flash Mass Erase */
1119   if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH)
1120   {
1121 #if defined (FLASH_CR_PSIZE)
1122     /* Reset Program/erase VoltageRange for Bank1 and Bank2 */
1123     FLASH->CR1 &= (~FLASH_CR_PSIZE);
1124     FLASH->CR2 &= (~FLASH_CR_PSIZE);
1125 
1126     /* Set voltage range */
1127     FLASH->CR1 |= VoltageRange;
1128     FLASH->CR2 |= VoltageRange;
1129 #endif /* FLASH_CR_PSIZE */
1130 
1131     /* Set Mass Erase Bit */
1132     FLASH->OPTCR |= FLASH_OPTCR_MER;
1133   }
1134   else
1135 #endif /* DUAL_BANK */
1136   {
1137     /* Proceed to erase Flash Bank  */
1138     if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1139     {
1140 #if defined (FLASH_CR_PSIZE)
1141       /* Set Program/erase VoltageRange for Bank1 */
1142       FLASH->CR1 &= (~FLASH_CR_PSIZE);
1143       FLASH->CR1 |=  VoltageRange;
1144 #endif /* FLASH_CR_PSIZE */
1145 
1146       /* Erase Bank1 */
1147       FLASH->CR1 |= (FLASH_CR_BER | FLASH_CR_START);
1148     }
1149 
1150 #if defined (DUAL_BANK)
1151     if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1152     {
1153 #if defined (FLASH_CR_PSIZE)
1154       /* Set Program/erase VoltageRange for Bank2 */
1155       FLASH->CR2 &= (~FLASH_CR_PSIZE);
1156       FLASH->CR2 |= VoltageRange;
1157 #endif /* FLASH_CR_PSIZE */
1158 
1159       /* Erase Bank2 */
1160       FLASH->CR2 |= (FLASH_CR_BER | FLASH_CR_START);
1161     }
1162 #endif /* DUAL_BANK */
1163   }
1164 }
1165 
1166 /**
1167   * @brief  Erase the specified FLASH memory sector
1168   * @param  Sector FLASH sector to erase
1169   *          This parameter can be a value of @ref FLASH_Sectors
1170   * @param  Banks Banks to be erased
1171   *          This parameter can be one of the following values:
1172   *            @arg FLASH_BANK_1: Bank1 to be erased
1173   *            @arg FLASH_BANK_2: Bank2 to be erased
1174   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
1175   * @param  VoltageRange The device program/erase parallelism.
1176   *          This parameter can be one of the following values:
1177   *            @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
1178   *            @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
1179   *            @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
1180   *            @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
1181   *
1182   * @retval None
1183   */
1184 void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange)
1185 {
1186   assert_param(IS_FLASH_SECTOR(Sector));
1187   assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
1188 #if defined (FLASH_CR_PSIZE)
1189   assert_param(IS_VOLTAGERANGE(VoltageRange));
1190 #else
1191   UNUSED(VoltageRange);
1192 #endif /* FLASH_CR_PSIZE */
1193 
1194   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1195   {
1196 #if defined (FLASH_CR_PSIZE)
1197     /* Reset Program/erase VoltageRange and Sector Number for Bank1 */
1198     FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
1199 
1200     FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
1201 #else
1202     /* Reset Sector Number for Bank1 */
1203     FLASH->CR1 &= ~(FLASH_CR_SNB);
1204 
1205     FLASH->CR1 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
1206 #endif /* FLASH_CR_PSIZE */
1207   }
1208 
1209 #if defined (DUAL_BANK)
1210   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1211   {
1212 #if defined (FLASH_CR_PSIZE)
1213     /* Reset Program/erase VoltageRange and Sector Number for Bank2 */
1214     FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
1215 
1216     FLASH->CR2 |= (FLASH_CR_SER | VoltageRange  | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
1217 #else
1218     /* Reset Sector Number for Bank2 */
1219     FLASH->CR2 &= ~(FLASH_CR_SNB);
1220 
1221     FLASH->CR2 |= (FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos) | FLASH_CR_START);
1222 #endif /* FLASH_CR_PSIZE */
1223   }
1224 #endif /* DUAL_BANK */
1225 }
1226 
1227 /**
1228   * @brief  Enable the write protection of the desired bank1 or bank 2 sectors
1229   * @param  WRPSector specifies the sector(s) to be write protected.
1230   *          This parameter can be one of the following values:
1231   *            @arg WRPSector:  A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_7 or OB_WRP_SECTOR_ALL
1232   *
1233   * @param  Banks the specific bank to apply WRP sectors
1234   *          This parameter can be one of the following values:
1235   *            @arg FLASH_BANK_1: enable WRP on specified bank1 sectors
1236   *            @arg FLASH_BANK_2: enable WRP on specified bank2 sectors
1237   *            @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors
1238   *
1239   * @retval HAL FLASH State
1240   */
1241 static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
1242 {
1243   /* Check the parameters */
1244   assert_param(IS_OB_WRP_SECTOR(WRPSector));
1245   assert_param(IS_FLASH_BANK(Banks));
1246 
1247   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1248   {
1249     /* Enable Write Protection for bank 1 */
1250     FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN));
1251   }
1252 
1253 #if defined (DUAL_BANK)
1254   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1255   {
1256     /* Enable Write Protection for bank 2 */
1257     FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN));
1258   }
1259 #endif /* DUAL_BANK */
1260 }
1261 
1262 /**
1263   * @brief  Disable the write protection of the desired bank1 or bank 2 sectors
1264   * @param  WRPSector specifies the sector(s) to disable write protection.
1265   *          This parameter can be one of the following values:
1266   *            @arg WRPSector:  A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_ALL
1267   *
1268   * @param  Banks the specific bank to apply WRP sectors
1269   *          This parameter can be one of the following values:
1270   *            @arg FLASH_BANK_1: disable WRP on specified bank1 sectors
1271   *            @arg FLASH_BANK_2: disable WRP on specified bank2 sectors
1272   *            @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors
1273   *
1274   * @retval HAL FLASH State
1275   */
1276 static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
1277 {
1278   /* Check the parameters */
1279   assert_param(IS_OB_WRP_SECTOR(WRPSector));
1280   assert_param(IS_FLASH_BANK(Banks));
1281 
1282   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1283   {
1284     /* Disable Write Protection for bank 1 */
1285     FLASH->WPSN_PRG1 |= (WRPSector & FLASH_WPSN_WRPSN);
1286   }
1287 
1288 #if defined (DUAL_BANK)
1289   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1290   {
1291     /* Disable Write Protection for bank 2 */
1292     FLASH->WPSN_PRG2 |= (WRPSector & FLASH_WPSN_WRPSN);
1293   }
1294 #endif /* DUAL_BANK */
1295 }
1296 
1297 /**
1298   * @brief  Get the write protection of the given bank 1 or bank 2 sectors
1299   * @param  WRPState gives the write protection state on the given bank.
1300   *          This parameter can be one of the following values:
1301   *          @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE
1302 
1303   * @param  WRPSector gives the write protected sector(s) on the given bank .
1304   *          This parameter can be one of the following values:
1305   *          @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_ALL
1306   *
1307   * @param  Bank the specific bank to apply WRP sectors
1308   *          This parameter can be exclusively one of the following values:
1309   *            @arg FLASH_BANK_1: Get bank1 WRP sectors
1310   *            @arg FLASH_BANK_2: Get bank2 WRP sectors
1311   *            @arg FLASH_BANK_BOTH: note allowed in this functions
1312   *
1313   * @retval HAL FLASH State
1314   */
1315 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank)
1316 {
1317   uint32_t regvalue = 0U;
1318 
1319   if(Bank == FLASH_BANK_1)
1320   {
1321     regvalue = FLASH->WPSN_CUR1;
1322   }
1323 
1324 #if defined (DUAL_BANK)
1325   if(Bank == FLASH_BANK_2)
1326   {
1327     regvalue = FLASH->WPSN_CUR2;
1328   }
1329 #endif /* DUAL_BANK */
1330 
1331   (*WRPSector) = (~regvalue) & FLASH_WPSN_WRPSN;
1332 
1333   if(*WRPSector == 0U)
1334   {
1335     (*WRPState) = OB_WRPSTATE_DISABLE;
1336   }
1337   else
1338   {
1339     (*WRPState) = OB_WRPSTATE_ENABLE;
1340   }
1341 }
1342 
1343 /**
1344   * @brief  Set the read protection level.
1345   *
1346   * @note   To configure the RDP level, the option lock bit OPTLOCK must be
1347   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
1348   * @note   To validate the RDP level, the option bytes must be reloaded
1349   *         through the call of the HAL_FLASH_OB_Launch() function.
1350   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
1351   *         to go back to level 1 or 0 !!!
1352   *
1353   * @param  RDPLevel specifies the read protection level.
1354   *         This parameter can be one of the following values:
1355   *            @arg OB_RDP_LEVEL_0: No protection
1356   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
1357   *            @arg OB_RDP_LEVEL_2: Full chip protection
1358   *
1359   * @retval HAL status
1360   */
1361 static void FLASH_OB_RDPConfig(uint32_t RDPLevel)
1362 {
1363   /* Check the parameters */
1364   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
1365 
1366   /* Configure the RDP level in the option bytes register */
1367   MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_RDP, RDPLevel);
1368 }
1369 
1370 /**
1371   * @brief  Get the read protection level.
1372   * @retval RDPLevel specifies the read protection level.
1373   *         This return value can be one of the following values:
1374   *            @arg OB_RDP_LEVEL_0: No protection
1375   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
1376   *            @arg OB_RDP_LEVEL_2: Full chip protection
1377   */
1378 static uint32_t FLASH_OB_GetRDP(void)
1379 {
1380   uint32_t rdp_level = READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_RDP);
1381   
1382   if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
1383   {
1384     return (OB_RDP_LEVEL_1);
1385   }
1386   else
1387   {
1388     return rdp_level;
1389   }
1390 }
1391 
1392 #if defined(DUAL_CORE)
1393 /**
1394   * @brief  Program the FLASH User Option Byte.
1395   *
1396   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
1397   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
1398   *
1399   * @note   To validate the user option bytes, the option bytes must be reloaded
1400   *         through the call of the HAL_FLASH_OB_Launch() function.
1401   *
1402   * @param  UserType The FLASH User Option Bytes to be modified :
1403   *                   a combination of @ref FLASHEx_OB_USER_Type
1404   *
1405   * @param  UserConfig The FLASH User Option Bytes values:
1406   *         IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1407   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1408   *         SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
1409   *         nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1410   *
1411   * @retval HAL status
1412   */
1413 #else
1414 /**
1415   * @brief  Program the FLASH User Option Byte.
1416   *
1417   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
1418   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
1419   *
1420   * @note   To validate the user option bytes, the option bytes must be reloaded
1421   *         through the call of the HAL_FLASH_OB_Launch() function.
1422   *
1423   * @param  UserType The FLASH User Option Bytes to be modified :
1424   *                   a combination of @arg FLASHEx_OB_USER_Type
1425   *
1426   * @param  UserConfig The FLASH User Option Bytes values:
1427   *         IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1428   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1429   *         SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1430   *
1431   * @retval HAL status
1432   */
1433 #endif /*DUAL_CORE*/
1434 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
1435 {
1436   uint32_t optr_reg_val = 0;
1437   uint32_t optr_reg_mask = 0;
1438 
1439   /* Check the parameters */
1440   assert_param(IS_OB_USER_TYPE(UserType));
1441 
1442   if((UserType & OB_USER_IWDG1_SW) != 0U)
1443   {
1444     /* IWDG_HW option byte should be modified */
1445     assert_param(IS_OB_IWDG1_SOURCE(UserConfig & FLASH_OPTSR_IWDG1_SW));
1446 
1447     /* Set value and mask for IWDG_HW option byte */
1448     optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG1_SW);
1449     optr_reg_mask |= FLASH_OPTSR_IWDG1_SW;
1450   }
1451 #if defined(DUAL_CORE)
1452   if((UserType & OB_USER_IWDG2_SW) != 0U)
1453   {
1454     /* IWDG2_SW option byte should be modified */
1455     assert_param(IS_OB_IWDG2_SOURCE(UserConfig & FLASH_OPTSR_IWDG2_SW));
1456 
1457     /* Set value and mask for IWDG2_SW option byte */
1458     optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG2_SW);
1459     optr_reg_mask |= FLASH_OPTSR_IWDG2_SW;
1460   }
1461 #endif /*DUAL_CORE*/
1462   if((UserType & OB_USER_NRST_STOP_D1) != 0U)
1463   {
1464     /* NRST_STOP option byte should be modified */
1465     assert_param(IS_OB_STOP_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D1));
1466 
1467     /* Set value and mask for NRST_STOP option byte */
1468     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D1);
1469     optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D1;
1470   }
1471 
1472   if((UserType & OB_USER_NRST_STDBY_D1) != 0U)
1473   {
1474     /* NRST_STDBY option byte should be modified */
1475     assert_param(IS_OB_STDBY_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D1));
1476 
1477     /* Set value and mask for NRST_STDBY option byte */
1478     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D1);
1479     optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D1;
1480   }
1481 
1482   if((UserType & OB_USER_IWDG_STOP) != 0U)
1483   {
1484     /* IWDG_STOP option byte should be modified */
1485     assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTSR_FZ_IWDG_STOP));
1486 
1487     /* Set value and mask for IWDG_STOP option byte */
1488     optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_STOP);
1489     optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_STOP;
1490   }
1491 
1492   if((UserType & OB_USER_IWDG_STDBY) != 0U)
1493   {
1494     /* IWDG_STDBY option byte should be modified */
1495     assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY));
1496 
1497     /* Set value and mask for IWDG_STDBY option byte */
1498     optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY);
1499     optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_SDBY;
1500   }
1501 
1502   if((UserType & OB_USER_ST_RAM_SIZE) != 0U)
1503   {
1504     /* ST_RAM_SIZE option byte should be modified */
1505     assert_param(IS_OB_USER_ST_RAM_SIZE(UserConfig & FLASH_OPTSR_ST_RAM_SIZE));
1506 
1507     /* Set value and mask for ST_RAM_SIZE option byte */
1508     optr_reg_val |= (UserConfig & FLASH_OPTSR_ST_RAM_SIZE);
1509     optr_reg_mask |= FLASH_OPTSR_ST_RAM_SIZE;
1510   }
1511 
1512   if((UserType & OB_USER_SECURITY) != 0U)
1513   {
1514     /* SECURITY option byte should be modified */
1515     assert_param(IS_OB_USER_SECURITY(UserConfig & FLASH_OPTSR_SECURITY));
1516 
1517     /* Set value and mask for SECURITY option byte */
1518     optr_reg_val |= (UserConfig & FLASH_OPTSR_SECURITY);
1519     optr_reg_mask |= FLASH_OPTSR_SECURITY;
1520   }
1521 
1522 #if defined(DUAL_CORE)
1523   if((UserType & OB_USER_BCM4) != 0U)
1524   {
1525     /* BCM4 option byte should be modified */
1526     assert_param(IS_OB_USER_BCM4(UserConfig & FLASH_OPTSR_BCM4));
1527 
1528     /* Set value and mask for BCM4 option byte */
1529     optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM4);
1530     optr_reg_mask |= FLASH_OPTSR_BCM4;
1531   }
1532 
1533   if((UserType & OB_USER_BCM7) != 0U)
1534   {
1535     /* BCM7 option byte should be modified */
1536     assert_param(IS_OB_USER_BCM7(UserConfig & FLASH_OPTSR_BCM7));
1537 
1538     /* Set value and mask for BCM7 option byte */
1539     optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM7);
1540     optr_reg_mask |= FLASH_OPTSR_BCM7;
1541   }
1542 #endif /* DUAL_CORE */
1543 
1544 #if defined (FLASH_OPTSR_NRST_STOP_D2)
1545   if((UserType & OB_USER_NRST_STOP_D2) != 0U)
1546   {
1547     /* NRST_STOP option byte should be modified */
1548     assert_param(IS_OB_STOP_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D2));
1549 
1550     /* Set value and mask for NRST_STOP option byte */
1551     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D2);
1552     optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D2;
1553   }
1554 
1555   if((UserType & OB_USER_NRST_STDBY_D2) != 0U)
1556   {
1557     /* NRST_STDBY option byte should be modified */
1558     assert_param(IS_OB_STDBY_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D2));
1559 
1560     /* Set value and mask for NRST_STDBY option byte */
1561     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D2);
1562     optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D2;
1563   }
1564 #endif /* FLASH_OPTSR_NRST_STOP_D2 */
1565 
1566 #if defined (DUAL_BANK)
1567   if((UserType & OB_USER_SWAP_BANK) != 0U)
1568   {
1569     /* SWAP_BANK_OPT option byte should be modified */
1570     assert_param(IS_OB_USER_SWAP_BANK(UserConfig & FLASH_OPTSR_SWAP_BANK_OPT));
1571 
1572     /* Set value and mask for SWAP_BANK_OPT option byte */
1573     optr_reg_val |= (UserConfig & FLASH_OPTSR_SWAP_BANK_OPT);
1574     optr_reg_mask |= FLASH_OPTSR_SWAP_BANK_OPT;
1575   }
1576 #endif /* DUAL_BANK */
1577 
1578   if((UserType & OB_USER_IOHSLV) != 0U)
1579   {
1580     /* IOHSLV_OPT option byte should be modified */
1581     assert_param(IS_OB_USER_IOHSLV(UserConfig & FLASH_OPTSR_IO_HSLV));
1582 
1583     /* Set value and mask for IOHSLV_OPT option byte */
1584     optr_reg_val |= (UserConfig & FLASH_OPTSR_IO_HSLV);
1585     optr_reg_mask |= FLASH_OPTSR_IO_HSLV;
1586   }
1587 
1588 #if defined (FLASH_OPTSR_VDDMMC_HSLV)
1589   if((UserType & OB_USER_VDDMMC_HSLV) != 0U)
1590   {
1591     /* VDDMMC_HSLV option byte should be modified */
1592     assert_param(IS_OB_USER_VDDMMC_HSLV(UserConfig & FLASH_OPTSR_VDDMMC_HSLV));
1593 
1594     /* Set value and mask for VDDMMC_HSLV option byte */
1595     optr_reg_val |= (UserConfig & FLASH_OPTSR_VDDMMC_HSLV);
1596     optr_reg_mask |= FLASH_OPTSR_VDDMMC_HSLV;
1597   }
1598 #endif /* FLASH_OPTSR_VDDMMC_HSLV */
1599 
1600   /* Configure the option bytes register */
1601   MODIFY_REG(FLASH->OPTSR_PRG, optr_reg_mask, optr_reg_val);
1602 }
1603 
1604 #if defined(DUAL_CORE)
1605 /**
1606   * @brief  Return the FLASH User Option Byte value.
1607   * @retval The FLASH User Option Bytes values
1608   *         IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1609   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1610   *         SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
1611   *         nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1612   */
1613 #else
1614 /**
1615   * @brief  Return the FLASH User Option Byte value.
1616   * @retval The FLASH User Option Bytes values
1617   *         IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1618   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1619   *         SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1620   */
1621 #endif /*DUAL_CORE*/
1622 static uint32_t FLASH_OB_GetUser(void)
1623 {
1624   uint32_t userConfig = READ_REG(FLASH->OPTSR_CUR);
1625   userConfig &= (~(FLASH_OPTSR_BOR_LEV | FLASH_OPTSR_RDP));
1626 
1627   return userConfig;
1628 }
1629 
1630 /**
1631   * @brief  Configure the Proprietary code readout protection of the desired addresses
1632   *
1633   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
1634   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
1635   * @note   To validate the PCROP options, the option bytes must be reloaded
1636   *         through the call of the HAL_FLASH_OB_Launch() function.
1637   *
1638   * @param  PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not
1639   *         when RDP level decreased from Level 1 to Level 0, or after a bank erase with protection removal
1640   *         This parameter must be a value of @arg FLASHEx_OB_PCROP_RDP enumeration
1641   *
1642   * @param  PCROPStartAddr specifies the start address of the Proprietary code readout protection
1643   *          This parameter can be an address between begin and end of the bank
1644   *
1645   * @param  PCROPEndAddr specifies the end address of the Proprietary code readout protection
1646   *          This parameter can be an address between PCROPStartAddr and end of the bank
1647   *
1648   * @param  Banks the specific bank to apply PCROP protection
1649   *          This parameter can be one of the following values:
1650   *            @arg FLASH_BANK_1: PCROP on specified bank1 area
1651   *            @arg FLASH_BANK_2: PCROP on specified bank2 area
1652   *            @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks)
1653   *
1654   * @retval None
1655   */
1656 static void FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks)
1657 {
1658   /* Check the parameters */
1659   assert_param(IS_FLASH_BANK(Banks));
1660   assert_param(IS_OB_PCROP_RDP(PCROPConfig));
1661 
1662   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1663   {
1664     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr));
1665     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr));
1666 
1667     /* Configure the Proprietary code readout protection */
1668     FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8)                                 | \
1669                        (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
1670                        PCROPConfig;
1671   }
1672 
1673 #if defined (DUAL_BANK)
1674   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1675   {
1676     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPStartAddr));
1677     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPEndAddr));
1678 
1679     /* Configure the Proprietary code readout protection */
1680     FLASH->PRAR_PRG2 = ((PCROPStartAddr - FLASH_BANK2_BASE) >> 8)                                 | \
1681                        (((PCROPEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
1682                        PCROPConfig;
1683   }
1684 #endif /* DUAL_BANK */
1685 }
1686 
1687 /**
1688   * @brief  Get the Proprietary code readout protection configuration on a given Bank
1689   *
1690   * @param  PCROPConfig indicates if the PCROP area for the given Bank shall be erased or not
1691   *         when RDP level decreased from Level 1 to Level 0 or after a bank erase with protection removal
1692   *
1693   * @param  PCROPStartAddr gives the start address of the Proprietary code readout protection of the bank
1694   *
1695   * @param  PCROPEndAddr gives the end address of the Proprietary code readout protection of the bank
1696   *
1697   * @param  Bank the specific bank to apply PCROP protection
1698   *          This parameter can be exclusively one of the following values:
1699   *            @arg FLASH_BANK_1: PCROP on specified bank1 area
1700   *            @arg FLASH_BANK_2: PCROP on specified bank2 area
1701   *            @arg FLASH_BANK_BOTH: is  not allowed here
1702   *
1703   * @retval None
1704   */
1705 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr, uint32_t Bank)
1706 {
1707   uint32_t regvalue = 0;
1708   uint32_t bankBase = 0;
1709 
1710   if(Bank == FLASH_BANK_1)
1711   {
1712     regvalue = FLASH->PRAR_CUR1;
1713     bankBase = FLASH_BANK1_BASE;
1714   }
1715 
1716 #if defined (DUAL_BANK)
1717   if(Bank == FLASH_BANK_2)
1718   {
1719     regvalue = FLASH->PRAR_CUR2;
1720     bankBase = FLASH_BANK2_BASE;
1721   }
1722 #endif /* DUAL_BANK */
1723 
1724   (*PCROPConfig) =  (regvalue & FLASH_PRAR_DMEP);
1725 
1726   (*PCROPStartAddr) = ((regvalue & FLASH_PRAR_PROT_AREA_START) << 8) + bankBase;
1727   (*PCROPEndAddr) = (regvalue & FLASH_PRAR_PROT_AREA_END) >> FLASH_PRAR_PROT_AREA_END_Pos;
1728   (*PCROPEndAddr) = ((*PCROPEndAddr) << 8) + bankBase;
1729 }
1730 
1731 /**
1732   * @brief  Set the BOR Level.
1733   * @param  Level specifies the Option Bytes BOR Reset Level.
1734   *          This parameter can be one of the following values:
1735   *            @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
1736   *            @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
1737   *            @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
1738   *            @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
1739   * @retval None
1740   */
1741 static void FLASH_OB_BOR_LevelConfig(uint32_t Level)
1742 {
1743   assert_param(IS_OB_BOR_LEVEL(Level));
1744 
1745   /* Configure BOR_LEV option byte */
1746   MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_BOR_LEV, Level);
1747 }
1748 
1749 /**
1750   * @brief  Get the BOR Level.
1751   * @retval The Option Bytes BOR Reset Level.
1752   *            This parameter can be one of the following values:
1753   *            @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
1754   *            @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
1755   *            @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
1756   *            @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
1757   */
1758 static uint32_t FLASH_OB_GetBOR(void)
1759 {
1760   return (FLASH->OPTSR_CUR & FLASH_OPTSR_BOR_LEV);
1761 }
1762 
1763 /**
1764   * @brief  Set Boot address
1765   * @param  BootOption Boot address option byte to be programmed,
1766   *                     This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
1767                         (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
1768   *
1769   * @param  BootAddress0 Specifies the Boot Address 0
1770   * @param  BootAddress1 Specifies the Boot Address 1
1771   * @retval HAL Status
1772   */
1773 static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
1774 {
1775   /* Check the parameters */
1776   assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
1777 
1778   if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
1779   {
1780     /* Check the parameters */
1781     assert_param(IS_BOOT_ADDRESS(BootAddress0));
1782 
1783     /* Configure CM7 BOOT ADD0 */
1784 #if defined(DUAL_CORE)
1785     MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD0, (BootAddress0 >> 16));
1786 #else /* Single Core*/
1787     MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD0, (BootAddress0 >> 16));
1788 #endif /* DUAL_CORE */
1789   }
1790 
1791   if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
1792   {
1793     /* Check the parameters */
1794     assert_param(IS_BOOT_ADDRESS(BootAddress1));
1795 
1796     /* Configure CM7 BOOT ADD1 */
1797 #if defined(DUAL_CORE)
1798     MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD1, BootAddress1);
1799 #else /* Single Core*/
1800     MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD1, BootAddress1);
1801 #endif /* DUAL_CORE */
1802   }
1803 }
1804 
1805 /**
1806   * @brief  Get Boot address
1807   * @param  BootAddress0 Specifies the Boot Address 0.
1808   * @param  BootAddress1 Specifies the Boot Address 1.
1809   * @retval HAL Status
1810   */
1811 static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
1812 {
1813   uint32_t regvalue;
1814 
1815 #if defined(DUAL_CORE)
1816   regvalue = FLASH->BOOT7_CUR;
1817 
1818   (*BootAddress0) = (regvalue & FLASH_BOOT7_BCM7_ADD0) << 16;
1819   (*BootAddress1) = (regvalue & FLASH_BOOT7_BCM7_ADD1);
1820 #else /* Single Core */
1821   regvalue = FLASH->BOOT_CUR;
1822 
1823   (*BootAddress0) = (regvalue & FLASH_BOOT_ADD0) << 16;
1824   (*BootAddress1) = (regvalue & FLASH_BOOT_ADD1);
1825 #endif /* DUAL_CORE */
1826 }
1827 
1828 #if defined(DUAL_CORE)
1829 /**
1830   * @brief  Set CM4 Boot address
1831   * @param  BootOption Boot address option byte to be programmed,
1832   *                     This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
1833                         (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
1834   *
1835   * @param  BootAddress0 Specifies the CM4 Boot Address 0.
1836   * @param  BootAddress1 Specifies the CM4 Boot Address 1.
1837   * @retval HAL Status
1838   */
1839 static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
1840 {
1841   /* Check the parameters */
1842   assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
1843 
1844   if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
1845   {
1846     /* Check the parameters */
1847     assert_param(IS_BOOT_ADDRESS(BootAddress0));
1848 
1849     /* Configure CM4 BOOT ADD0 */
1850     MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD0, (BootAddress0 >> 16));
1851 
1852   }
1853 
1854   if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
1855   {
1856     /* Check the parameters */
1857     assert_param(IS_BOOT_ADDRESS(BootAddress1));
1858 
1859     /* Configure CM4 BOOT ADD1 */
1860     MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD1, BootAddress1);
1861   }
1862 }
1863 
1864 /**
1865   * @brief  Get CM4 Boot address
1866   * @param  BootAddress0 Specifies the CM4 Boot Address 0.
1867   * @param  BootAddress1 Specifies the CM4 Boot Address 1.
1868   * @retval HAL Status
1869   */
1870 static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
1871 {
1872   uint32_t regvalue;
1873 
1874   regvalue = FLASH->BOOT4_CUR;
1875 
1876   (*BootAddress0) = (regvalue & FLASH_BOOT4_BCM4_ADD0) << 16;
1877   (*BootAddress1) = (regvalue & FLASH_BOOT4_BCM4_ADD1);
1878 }
1879 #endif /*DUAL_CORE*/
1880 
1881 /**
1882   * @brief  Set secure area configuration
1883   * @param  SecureAreaConfig specify if the secure area will be deleted or not
1884   *         when RDP level decreased from Level 1 to Level 0 or during a mass erase.
1885   *
1886   * @param  SecureAreaStartAddr Specifies the secure area start address
1887   * @param  SecureAreaEndAddr Specifies the secure area end address
1888   * @param  Banks the specific bank to apply Security protection
1889   *          This parameter can be one of the following values:
1890   *            @arg FLASH_BANK_1: Secure area on specified bank1 area
1891   *            @arg FLASH_BANK_2: Secure area on specified bank2 area
1892   *            @arg FLASH_BANK_BOTH: Secure area on specified bank1 and bank2 area (same config will be applied on both banks)
1893   * @retval None
1894   */
1895 static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks)
1896 {
1897   /* Check the parameters */
1898   assert_param(IS_FLASH_BANK(Banks));
1899   assert_param(IS_OB_SECURE_RDP(SecureAreaConfig));
1900 
1901   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1902   {
1903     /* Check the parameters */
1904     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaStartAddr));
1905     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaEndAddr));
1906 
1907     /* Configure the secure area */
1908     FLASH->SCAR_PRG1 = ((SecureAreaStartAddr - FLASH_BANK1_BASE) >> 8)                                | \
1909                        (((SecureAreaEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
1910                        (SecureAreaConfig & FLASH_SCAR_DMES);
1911   }
1912 
1913 #if defined (DUAL_BANK)
1914   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1915   {
1916     /* Check the parameters */
1917     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaStartAddr));
1918     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaEndAddr));
1919 
1920     /* Configure the secure area */
1921     FLASH->SCAR_PRG2 = ((SecureAreaStartAddr - FLASH_BANK2_BASE) >> 8)                                | \
1922                        (((SecureAreaEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
1923                        (SecureAreaConfig & FLASH_SCAR_DMES);
1924   }
1925 #endif /* DUAL_BANK */
1926 }
1927 
1928 /**
1929   * @brief  Get secure area configuration
1930   * @param  SecureAreaConfig indicates if the secure area will be deleted or not
1931   *         when RDP level decreased from Level 1 to Level 0 or during a mass erase.
1932   * @param  SecureAreaStartAddr gives the secure area start address
1933   * @param  SecureAreaEndAddr gives the secure area end address
1934   * @param  Bank Specifies the Bank
1935   * @retval None
1936   */
1937 static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank)
1938 {
1939   uint32_t regvalue = 0;
1940   uint32_t bankBase = 0;
1941 
1942   /* Check Bank parameter value */
1943   if(Bank == FLASH_BANK_1)
1944   {
1945     regvalue = FLASH->SCAR_CUR1;
1946     bankBase = FLASH_BANK1_BASE;
1947   }
1948 
1949 #if defined (DUAL_BANK)
1950   if(Bank == FLASH_BANK_2)
1951   {
1952     regvalue = FLASH->SCAR_CUR2;
1953     bankBase = FLASH_BANK2_BASE;
1954   }
1955 #endif /* DUAL_BANK */
1956 
1957   /* Get the secure area settings */
1958   (*SecureAreaConfig) = (regvalue & FLASH_SCAR_DMES);
1959   (*SecureAreaStartAddr) = ((regvalue & FLASH_SCAR_SEC_AREA_START) << 8) + bankBase;
1960   (*SecureAreaEndAddr) = (regvalue & FLASH_SCAR_SEC_AREA_END) >> FLASH_SCAR_SEC_AREA_END_Pos;
1961   (*SecureAreaEndAddr) = ((*SecureAreaEndAddr) << 8) + bankBase;
1962 }
1963 
1964 /**
1965   * @brief  Add a CRC sector to the list of sectors on which the CRC will be calculated
1966   * @param  Sector Specifies the CRC sector number
1967   * @param  Bank Specifies the Bank
1968   * @retval None
1969   */
1970 static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank)
1971 {
1972   /* Check the parameters */
1973   assert_param(IS_FLASH_SECTOR(Sector));
1974 
1975   if (Bank == FLASH_BANK_1)
1976   {
1977     /* Clear CRC sector */
1978     FLASH->CRCCR1 &= (~FLASH_CRCCR_CRC_SECT);
1979 
1980     /* Select CRC Sector and activate ADD_SECT bit */
1981     FLASH->CRCCR1 |= Sector | FLASH_CRCCR_ADD_SECT;
1982   }
1983 #if defined (DUAL_BANK)
1984   else
1985   {
1986     /* Clear CRC sector */
1987     FLASH->CRCCR2 &= (~FLASH_CRCCR_CRC_SECT);
1988 
1989     /* Select CRC Sector and activate ADD_SECT bit */
1990     FLASH->CRCCR2 |= Sector | FLASH_CRCCR_ADD_SECT;
1991   }
1992 #endif /* DUAL_BANK */
1993 }
1994 
1995 /**
1996   * @brief  Select CRC start and end memory addresses on which the CRC will be calculated
1997   * @param  CRCStartAddr Specifies the CRC start address
1998   * @param  CRCEndAddr Specifies the CRC end address
1999   * @param  Bank Specifies the Bank
2000   * @retval None
2001   */
2002 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank)
2003 {
2004   if (Bank == FLASH_BANK_1)
2005   {
2006     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCStartAddr));
2007     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCEndAddr));
2008 
2009     /* Write CRC Start and End addresses */
2010     FLASH->CRCSADD1 = CRCStartAddr;
2011     FLASH->CRCEADD1 = CRCEndAddr;
2012   }
2013 #if defined (DUAL_BANK)
2014   else
2015   {
2016     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCStartAddr));
2017     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCEndAddr));
2018 
2019     /* Write CRC Start and End addresses */
2020     FLASH->CRCSADD2 = CRCStartAddr;
2021     FLASH->CRCEADD2 = CRCEndAddr;
2022   }
2023 #endif /* DUAL_BANK */
2024 }
2025 /**
2026   * @}
2027   */
2028 
2029 #if defined (FLASH_OTPBL_LOCKBL)
2030 /**
2031   * @brief  Configure the OTP Block Lock.
2032   * @param  OTP_Block specifies the OTP Block to lock.
2033   *         This parameter can be a value of @ref FLASHEx_OTP_Blocks
2034   * @retval None
2035   */
2036 static void FLASH_OB_OTP_LockConfig(uint32_t OTP_Block)
2037 {
2038   /* Check the parameters */
2039   assert_param(IS_OTP_BLOCK(OTP_Block));
2040 
2041   /* Configure the OTP Block lock in the option bytes register */
2042   FLASH->OTPBL_PRG |= (OTP_Block & FLASH_OTPBL_LOCKBL);
2043 }
2044 
2045 /**
2046   * @brief  Get the OTP Block Lock.
2047   * @retval OTP_Block specifies the OTP Block to lock.
2048   *         This return value can be a value of @ref FLASHEx_OTP_Blocks
2049   */
2050 static uint32_t FLASH_OB_OTP_GetLock(void)
2051 {
2052   return (FLASH->OTPBL_CUR);
2053 }
2054 #endif /* FLASH_OTPBL_LOCKBL */
2055 
2056 #if defined (FLASH_OPTSR2_TCM_AXI_SHARED)
2057 /**
2058   * @brief  Configure the TCM / AXI Shared RAM.
2059   * @param  SharedRamConfig specifies the Shared RAM configuration.
2060   *         This parameter can be a value of @ref FLASHEx_OB_TCM_AXI_SHARED
2061   * @retval None
2062   */
2063 static void FLASH_OB_SharedRAM_Config(uint32_t SharedRamConfig)
2064 {
2065   /* Check the parameters */
2066   assert_param(IS_OB_USER_TCM_AXI_SHARED(SharedRamConfig));
2067 
2068   /* Configure the TCM / AXI Shared RAM in the option bytes register */
2069   MODIFY_REG(FLASH->OPTSR2_PRG, FLASH_OPTSR2_TCM_AXI_SHARED, SharedRamConfig);
2070 }
2071 
2072 /**
2073   * @brief  Get the TCM / AXI Shared RAM configuration.
2074   * @retval SharedRamConfig returns the TCM / AXI Shared RAM configuration.
2075   *         This return value can be a value of @ref FLASHEx_OB_TCM_AXI_SHARED
2076   */
2077 static uint32_t FLASH_OB_SharedRAM_GetConfig(void)
2078 {
2079   return (FLASH->OPTSR2_CUR & FLASH_OPTSR2_TCM_AXI_SHARED);
2080 }
2081 #endif /* FLASH_OPTSR2_TCM_AXI_SHARED */
2082 
2083 #if defined (FLASH_OPTSR2_CPUFREQ_BOOST)
2084 /**
2085   * @brief  Configure the CPU Frequency Boost.
2086   * @param  FreqBoost specifies the CPU Frequency Boost state.
2087   *         This parameter can be a value of @ref FLASHEx_OB_CPUFREQ_BOOST
2088   * @retval None
2089   */
2090 static void FLASH_OB_CPUFreq_BoostConfig(uint32_t FreqBoost)
2091 {
2092   /* Check the parameters */
2093   assert_param(IS_OB_USER_CPUFREQ_BOOST(FreqBoost));
2094 
2095   /* Configure the CPU Frequency Boost in the option bytes register */
2096   MODIFY_REG(FLASH->OPTSR2_PRG, FLASH_OPTSR2_CPUFREQ_BOOST, FreqBoost);
2097 }
2098 
2099 /**
2100   * @brief  Get the CPU Frequency Boost state.
2101   * @retval FreqBoost returns the CPU Frequency Boost state.
2102   *         This return value can be a value of @ref FLASHEx_OB_CPUFREQ_BOOST
2103   */
2104 static uint32_t FLASH_OB_CPUFreq_GetBoost(void)
2105 {
2106   return (FLASH->OPTSR2_CUR & FLASH_OPTSR2_CPUFREQ_BOOST);
2107 }
2108 #endif /* FLASH_OPTSR2_CPUFREQ_BOOST */
2109 
2110 #endif /* HAL_FLASH_MODULE_ENABLED */
2111 
2112 /**
2113   * @}
2114   */
2115 
2116 /**
2117   * @}
2118   */
2119