STM32L443xx HAL User Manual
stm32l4xx_hal_flash_ex.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_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 extended peripheral:
00008   *           + Extended programming operations functions
00009   *
00010  @verbatim
00011  ==============================================================================
00012                    ##### Flash Extended features #####
00013   ==============================================================================
00014 
00015   [..] Comparing to other previous devices, the FLASH interface for STM32L4xx
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 
00023                         ##### How to use this driver #####
00024  ==============================================================================
00025   [..] This driver provides functions to configure and program the FLASH memory
00026        of all STM32L4xx devices. It includes
00027       (#) Flash Memory Erase functions:
00028            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
00029                 HAL_FLASH_Lock() functions
00030            (++) Erase function: Erase page, erase all sectors
00031            (++) There are two modes of erase :
00032              (+++) Polling Mode using HAL_FLASHEx_Erase()
00033              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
00034 
00035       (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
00036         (++) Set/Reset the write protection
00037         (++) Set the Read protection Level
00038         (++) Program the user Option Bytes
00039         (++) Configure the PCROP protection
00040 
00041       (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
00042         (++) Get the value of a write protection area
00043         (++) Know if the read protection is activated
00044         (++) Get the value of the user Option Bytes
00045         (++) Get the value of a PCROP area
00046 
00047  @endverbatim
00048   ******************************************************************************
00049   * @attention
00050   *
00051   * Copyright (c) 2017 STMicroelectronics.
00052   * All rights reserved.
00053   *
00054   * This software is licensed under terms that can be found in the LICENSE file in
00055   * the root directory of this software component.
00056   * If no LICENSE file comes with this software, it is provided AS-IS.
00057   ******************************************************************************
00058   */
00059 
00060 /* Includes ------------------------------------------------------------------*/
00061 #include "stm32l4xx_hal.h"
00062 
00063 /** @addtogroup STM32L4xx_HAL_Driver
00064   * @{
00065   */
00066 
00067 /** @defgroup FLASHEx FLASHEx
00068   * @brief FLASH Extended HAL module driver
00069   * @{
00070   */
00071 
00072 #ifdef HAL_FLASH_MODULE_ENABLED
00073 
00074 /* Private typedef -----------------------------------------------------------*/
00075 /* Private define ------------------------------------------------------------*/
00076 /* Private macro -------------------------------------------------------------*/
00077 /* Private variables ---------------------------------------------------------*/
00078 /* Private function prototypes -----------------------------------------------*/
00079 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
00080  * @{
00081  */
00082 static void              FLASH_MassErase(uint32_t Banks);
00083 static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
00084 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel);
00085 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
00086 static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr);
00087 static void              FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset);
00088 static uint32_t          FLASH_OB_GetRDP(void);
00089 static uint32_t          FLASH_OB_GetUser(void);
00090 static void              FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr);
00091 /**
00092   * @}
00093   */
00094 
00095 /* Exported functions -------------------------------------------------------*/
00096 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
00097   * @{
00098   */
00099 
00100 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
00101  *  @brief   Extended IO operation functions
00102  *
00103 @verbatim
00104  ===============================================================================
00105                 ##### Extended programming operation functions #####
00106  ===============================================================================
00107     [..]
00108     This subsection provides a set of functions allowing to manage the Extended FLASH
00109     programming operations Operations.
00110 
00111 @endverbatim
00112   * @{
00113   */
00114 /**
00115   * @brief  Perform a mass erase or erase the specified FLASH memory pages.
00116   * @param[in]  pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
00117   *         contains the configuration information for the erasing.
00118   *
00119   * @param[out]  PageError  : pointer to variable that contains the configuration
00120   *         information on faulty page in case of error (0xFFFFFFFF means that all
00121   *         the pages have been correctly erased)
00122   *
00123   * @retval HAL Status
00124   */
00125 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
00126 {
00127   HAL_StatusTypeDef status;
00128   uint32_t page_index;
00129 
00130   /* Process Locked */
00131   __HAL_LOCK(&pFlash);
00132 
00133   /* Check the parameters */
00134   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
00135 
00136   /* Wait for last operation to be completed */
00137   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00138 
00139   if (status == HAL_OK)
00140   {
00141     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00142 
00143     /* Deactivate the cache if they are activated to avoid data misbehavior */
00144     if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
00145     {
00146       if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
00147       {
00148         /* Disable data cache  */
00149         __HAL_FLASH_DATA_CACHE_DISABLE();
00150         pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;
00151       }
00152       else
00153       {
00154         pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;
00155       }
00156     }
00157     else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
00158     {
00159       /* Disable data cache  */
00160       __HAL_FLASH_DATA_CACHE_DISABLE();
00161       pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
00162     }
00163     else
00164     {
00165       pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
00166     }
00167 
00168     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
00169     {
00170       /* Mass erase to be done */
00171       FLASH_MassErase(pEraseInit->Banks);
00172 
00173       /* Wait for last operation to be completed */
00174       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00175 
00176 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00177     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00178     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00179     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00180       /* If the erase operation is completed, disable the MER1 and MER2 Bits */
00181       CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
00182 #else
00183       /* If the erase operation is completed, disable the MER1 Bit */
00184       CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1));
00185 #endif
00186     }
00187     else
00188     {
00189       /*Initialization of PageError variable*/
00190       *PageError = 0xFFFFFFFFU;
00191 
00192       for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)
00193       {
00194         FLASH_PageErase(page_index, pEraseInit->Banks);
00195 
00196         /* Wait for last operation to be completed */
00197         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00198 
00199         /* If the erase operation is completed, disable the PER Bit */
00200         CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
00201 
00202         if (status != HAL_OK)
00203         {
00204           /* In case of error, stop erase procedure and return the faulty address */
00205           *PageError = page_index;
00206           break;
00207         }
00208       }
00209     }
00210 
00211     /* Flush the caches to be sure of the data consistency */
00212     FLASH_FlushCaches();
00213   }
00214 
00215   /* Process Unlocked */
00216   __HAL_UNLOCK(&pFlash);
00217 
00218   return status;
00219 }
00220 
00221 /**
00222   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
00223   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
00224   *         contains the configuration information for the erasing.
00225   *
00226   * @retval HAL Status
00227   */
00228 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
00229 {
00230   HAL_StatusTypeDef status = HAL_OK;
00231 
00232   /* Process Locked */
00233   __HAL_LOCK(&pFlash);
00234 
00235   /* Check the parameters */
00236   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
00237 
00238   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00239 
00240   /* Deactivate the cache if they are activated to avoid data misbehavior */
00241   if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)
00242   {
00243     if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
00244     {
00245       /* Disable data cache  */
00246       __HAL_FLASH_DATA_CACHE_DISABLE();
00247       pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;
00248     }
00249     else
00250     {
00251       pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;
00252     }
00253   }
00254   else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
00255   {
00256     /* Disable data cache  */
00257     __HAL_FLASH_DATA_CACHE_DISABLE();
00258     pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
00259   }
00260   else
00261   {
00262     pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
00263   }
00264 
00265   /* Enable End of Operation and Error interrupts */
00266   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
00267 
00268   pFlash.Bank = pEraseInit->Banks;
00269 
00270   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
00271   {
00272     /* Mass erase to be done */
00273     pFlash.ProcedureOnGoing = FLASH_PROC_MASS_ERASE;
00274     FLASH_MassErase(pEraseInit->Banks);
00275   }
00276   else
00277   {
00278     /* Erase by page to be done */
00279     pFlash.ProcedureOnGoing = FLASH_PROC_PAGE_ERASE;
00280     pFlash.NbPagesToErase = pEraseInit->NbPages;
00281     pFlash.Page = pEraseInit->Page;
00282 
00283     /*Erase 1st page and wait for IT */
00284     FLASH_PageErase(pEraseInit->Page, pEraseInit->Banks);
00285   }
00286 
00287   return status;
00288 }
00289 
00290 /**
00291   * @brief  Program Option bytes.
00292   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
00293   *         contains the configuration information for the programming.
00294   *
00295   * @retval HAL Status
00296   */
00297 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
00298 {
00299   HAL_StatusTypeDef status = HAL_OK;
00300 
00301   /* Process Locked */
00302   __HAL_LOCK(&pFlash);
00303 
00304   /* Check the parameters */
00305   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
00306 
00307   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00308 
00309   /* Write protection configuration */
00310   if((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
00311   {
00312     /* Configure of Write protection on the selected area */
00313     if(FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset) != HAL_OK)
00314     {
00315       status = HAL_ERROR;
00316     }
00317 
00318   }
00319 
00320   /* Read protection configuration */
00321   if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
00322   {
00323     /* Configure the Read protection level */
00324     if(FLASH_OB_RDPConfig(pOBInit->RDPLevel) != HAL_OK)
00325     {
00326       status = HAL_ERROR;
00327     }
00328   }
00329 
00330   /* User Configuration */
00331   if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
00332   {
00333     /* Configure the user option bytes */
00334     if(FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig) != HAL_OK)
00335     {
00336       status = HAL_ERROR;
00337     }
00338   }
00339 
00340   /* PCROP Configuration */
00341   if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
00342   {
00343     if (pOBInit->PCROPStartAddr != pOBInit->PCROPEndAddr)
00344     {
00345       /* Configure the Proprietary code readout protection */
00346       if(FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr) != HAL_OK)
00347       {
00348         status = HAL_ERROR;
00349       }
00350     }
00351   }
00352 
00353   /* Process Unlocked */
00354   __HAL_UNLOCK(&pFlash);
00355 
00356   return status;
00357 }
00358 
00359 /**
00360   * @brief  Get the Option bytes configuration.
00361   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that contains the
00362   *                  configuration information.
00363   * @note   The fields pOBInit->WRPArea and pOBInit->PCROPConfig should indicate
00364   *         which area is requested for the WRP and PCROP, else no information will be returned
00365   *
00366   * @retval None
00367   */
00368 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
00369 {
00370   pOBInit->OptionType = (OPTIONBYTE_RDP | OPTIONBYTE_USER);
00371 
00372 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00373     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00374     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00375     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00376   if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB) ||
00377      (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAB))
00378 #else
00379   if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))
00380 #endif
00381   {
00382     pOBInit->OptionType |= OPTIONBYTE_WRP;
00383     /* Get write protection on the selected area */
00384     FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
00385   }
00386 
00387   /* Get Read protection level */
00388   pOBInit->RDPLevel = FLASH_OB_GetRDP();
00389 
00390   /* Get the user option bytes */
00391   pOBInit->USERConfig = FLASH_OB_GetUser();
00392 
00393 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00394     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00395     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00396     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00397   if((pOBInit->PCROPConfig == FLASH_BANK_1) || (pOBInit->PCROPConfig == FLASH_BANK_2))
00398 #else
00399   if(pOBInit->PCROPConfig == FLASH_BANK_1)
00400 #endif
00401   {
00402     pOBInit->OptionType |= OPTIONBYTE_PCROP;
00403     /* Get the Proprietary code readout protection */
00404     FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr));
00405   }
00406 }
00407 
00408 /**
00409   * @}
00410   */
00411 
00412 #if defined (FLASH_CFGR_LVEN)
00413 /** @defgroup FLASHEx_Exported_Functions_Group2 Extended specific configuration functions
00414  *  @brief   Extended specific configuration functions
00415  *
00416 @verbatim
00417  ===============================================================================
00418                 ##### Extended specific configuration functions #####
00419  ===============================================================================
00420     [..]
00421     This subsection provides a set of functions allowing to manage the Extended FLASH
00422     specific configurations.
00423 
00424 @endverbatim
00425   * @{
00426   */
00427 
00428 /**
00429   * @brief  Configuration of the LVE pin of the Flash (managed by power controller
00430   *         or forced to low in order to use an external SMPS)
00431   * @param  ConfigLVE Configuration of the LVE pin,
00432   *              This parameter can be one of the following values:
00433   *                @arg FLASH_LVE_PIN_CTRL: LVE FLASH pin controlled by power controller
00434   *                @arg FLASH_LVE_PIN_FORCED: LVE FLASH pin enforced to low (external SMPS used)
00435   *
00436   * @note   Before enforcing the LVE pin to low, the SOC should be in low voltage
00437   *         range 2 and the voltage VDD12 should be higher than 1.08V and SMPS is ON.
00438   *
00439   * @retval HAL Status
00440   */
00441 HAL_StatusTypeDef HAL_FLASHEx_ConfigLVEPin(uint32_t ConfigLVE)
00442 {
00443   HAL_StatusTypeDef status;
00444 
00445   /* Process Locked */
00446   __HAL_LOCK(&pFlash);
00447 
00448   /* Check the parameters */
00449   assert_param(IS_FLASH_LVE_PIN(ConfigLVE));
00450 
00451   /* Wait for last operation to be completed */
00452   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00453 
00454   if (status == HAL_OK)
00455   {
00456     /* Check that the voltage scaling is range 2 */
00457     if (HAL_PWREx_GetVoltageRange() == PWR_REGULATOR_VOLTAGE_SCALE2)
00458     {
00459       /* Configure the LVEN bit */
00460       MODIFY_REG(FLASH->CFGR, FLASH_CFGR_LVEN, ConfigLVE);
00461 
00462       /* Check that the bit has been correctly configured */
00463       if (READ_BIT(FLASH->CFGR, FLASH_CFGR_LVEN) != ConfigLVE)
00464       {
00465         status = HAL_ERROR;
00466       }
00467     }
00468     else
00469     {
00470       /* Not allow to force Flash LVE pin if not in voltage range 2 */
00471       status = HAL_ERROR;
00472     }
00473   }
00474 
00475   /* Process Unlocked */
00476   __HAL_UNLOCK(&pFlash);
00477 
00478   return status;
00479 }
00480 
00481 /**
00482   * @}
00483   */
00484 #endif /* FLASH_CFGR_LVEN */
00485 
00486 /**
00487   * @}
00488   */
00489 
00490 /* Private functions ---------------------------------------------------------*/
00491 
00492 /** @addtogroup FLASHEx_Private_Functions
00493   * @{
00494   */
00495 /**
00496   * @brief  Mass erase of FLASH memory.
00497   * @param  Banks Banks to be erased
00498   *          This parameter can be one of the following values:
00499   *            @arg FLASH_BANK_1: Bank1 to be erased
00500   *            @arg FLASH_BANK_2: Bank2 to be erased
00501   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
00502   * @retval None
00503   */
00504 static void FLASH_MassErase(uint32_t Banks)
00505 {
00506 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00507   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) != 0U)
00508 #endif
00509   {
00510     /* Check the parameters */
00511     assert_param(IS_FLASH_BANK(Banks));
00512 
00513     /* Set the Mass Erase Bit for the bank 1 if requested */
00514     if((Banks & FLASH_BANK_1) != 0U)
00515     {
00516       SET_BIT(FLASH->CR, FLASH_CR_MER1);
00517     }
00518 
00519 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00520     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00521     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00522     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00523     /* Set the Mass Erase Bit for the bank 2 if requested */
00524     if((Banks & FLASH_BANK_2) != 0U)
00525     {
00526       SET_BIT(FLASH->CR, FLASH_CR_MER2);
00527     }
00528 #endif
00529   }
00530 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00531   else
00532   {
00533     SET_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
00534   }
00535 #endif
00536 
00537   /* Proceed to erase all sectors */
00538   SET_BIT(FLASH->CR, FLASH_CR_STRT);
00539 }
00540 
00541 /**
00542   * @brief  Erase the specified FLASH memory page.
00543   * @param  Page FLASH page to erase
00544   *         This parameter must be a value between 0 and (max number of pages in the bank - 1)
00545   * @param  Banks Bank(s) where the page will be erased
00546   *          This parameter can be one of the following values:
00547   *            @arg FLASH_BANK_1: Page in bank 1 to be erased
00548   *            @arg FLASH_BANK_2: Page in bank 2 to be erased
00549   * @retval None
00550   */
00551 void FLASH_PageErase(uint32_t Page, uint32_t Banks)
00552 {
00553   /* Check the parameters */
00554   assert_param(IS_FLASH_PAGE(Page));
00555 
00556 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00557     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00558     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00559     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00560 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00561   if(READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
00562   {
00563     CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
00564   }
00565   else
00566 #endif
00567   {
00568     assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
00569 
00570     if((Banks & FLASH_BANK_1) != 0U)
00571     {
00572       CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
00573     }
00574     else
00575     {
00576       SET_BIT(FLASH->CR, FLASH_CR_BKER);
00577     }
00578   }
00579 #else
00580   /* Prevent unused argument(s) compilation warning */
00581   UNUSED(Banks);
00582 #endif
00583 
00584   /* Proceed to erase the page */
00585   MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page & 0xFFU) << FLASH_CR_PNB_Pos));
00586   SET_BIT(FLASH->CR, FLASH_CR_PER);
00587   SET_BIT(FLASH->CR, FLASH_CR_STRT);
00588 }
00589 
00590 /**
00591   * @brief  Flush the instruction and data caches.
00592   * @retval None
00593   */
00594 void FLASH_FlushCaches(void)
00595 {
00596   FLASH_CacheTypeDef cache = pFlash.CacheToReactivate;
00597 
00598   /* Flush instruction cache  */
00599   if((cache == FLASH_CACHE_ICACHE_ENABLED) ||
00600      (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))
00601   {
00602     /* Disable instruction cache */
00603     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
00604     /* Reset instruction cache */
00605     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
00606     /* Enable instruction cache */
00607     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
00608   }
00609 
00610   /* Flush data cache */
00611   if((cache == FLASH_CACHE_DCACHE_ENABLED) ||
00612      (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))
00613   {
00614     /* Reset data cache */
00615     __HAL_FLASH_DATA_CACHE_RESET();
00616     /* Enable data cache */
00617     __HAL_FLASH_DATA_CACHE_ENABLE();
00618   }
00619 
00620   /* Reset internal variable */
00621   pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
00622 }
00623 
00624 /**
00625   * @brief  Configure the write protection of the desired pages.
00626   *
00627   * @note   When the memory read protection level is selected (RDP level = 1),
00628   *         it is not possible to program or erase Flash memory if the CPU debug
00629   *         features are connected (JTAG or single wire) or boot code is being
00630   *         executed from RAM or System flash, even if WRP is not activated.
00631   * @note   To configure the WRP options, the option lock bit OPTLOCK must be
00632   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
00633   * @note   To validate the WRP options, the option bytes must be reloaded
00634   *         through the call of the HAL_FLASH_OB_Launch() function.
00635   *
00636   * @param  WRPArea specifies the area to be configured.
00637   *          This parameter can be one of the following values:
00638   *            @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
00639   *            @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
00640   *            @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A  (don't apply for STM32L43x/STM32L44x devices)
00641   *            @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B  (don't apply for STM32L43x/STM32L44x devices)
00642   *
00643   * @param  WRPStartOffset specifies the start page of the write protected area
00644   *          This parameter can be page number between 0 and (max number of pages in the bank - 1)
00645   *
00646   * @param  WRDPEndOffset specifies the end page of the write protected area
00647   *          This parameter can be page number between WRPStartOffset and (max number of pages in the bank - 1)
00648   *
00649   * @retval HAL Status
00650   */
00651 static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
00652 {
00653   HAL_StatusTypeDef status;
00654 
00655   /* Check the parameters */
00656   assert_param(IS_OB_WRPAREA(WRPArea));
00657   assert_param(IS_FLASH_PAGE(WRPStartOffset));
00658   assert_param(IS_FLASH_PAGE(WRDPEndOffset));
00659 
00660   /* Wait for last operation to be completed */
00661   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00662 
00663   if(status == HAL_OK)
00664   {
00665     /* Configure the write protected area */
00666     if(WRPArea == OB_WRPAREA_BANK1_AREAA)
00667     {
00668       MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),
00669                  (WRPStartOffset | (WRDPEndOffset << 16)));
00670     }
00671     else if(WRPArea == OB_WRPAREA_BANK1_AREAB)
00672     {
00673       MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),
00674                  (WRPStartOffset | (WRDPEndOffset << 16)));
00675     }
00676 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00677     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00678     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00679     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00680     else if(WRPArea == OB_WRPAREA_BANK2_AREAA)
00681     {
00682       MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_STRT | FLASH_WRP2AR_WRP2A_END),
00683                  (WRPStartOffset | (WRDPEndOffset << 16)));
00684     }
00685     else if(WRPArea == OB_WRPAREA_BANK2_AREAB)
00686     {
00687       MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_STRT | FLASH_WRP2BR_WRP2B_END),
00688                  (WRPStartOffset | (WRDPEndOffset << 16)));
00689     }
00690 #endif
00691     else
00692     {
00693       /* Nothing to do */
00694     }
00695 
00696     /* Set OPTSTRT Bit */
00697     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
00698 
00699     /* Wait for last operation to be completed */
00700     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00701 
00702     /* If the option byte program operation is completed, disable the OPTSTRT Bit */
00703     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
00704   }
00705 
00706   return status;
00707 }
00708 
00709 /**
00710   * @brief  Set the read protection level.
00711   *
00712   * @note   To configure the RDP level, the option lock bit OPTLOCK must be
00713   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
00714   * @note   To validate the RDP level, the option bytes must be reloaded
00715   *         through the call of the HAL_FLASH_OB_Launch() function.
00716   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
00717   *         to go back to level 1 or 0 !!!
00718   *
00719   * @param  RDPLevel specifies the read protection level.
00720   *         This parameter can be one of the following values:
00721   *            @arg OB_RDP_LEVEL_0: No protection
00722   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
00723   *            @arg OB_RDP_LEVEL_2: Full chip protection
00724   *
00725   * @retval HAL status
00726   */
00727 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel)
00728 {
00729   HAL_StatusTypeDef status;
00730 
00731   /* Check the parameters */
00732   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
00733 
00734   /* Wait for last operation to be completed */
00735   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00736 
00737   if(status == HAL_OK)
00738   {
00739     /* Configure the RDP level in the option bytes register */
00740     MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, RDPLevel);
00741 
00742     /* Set OPTSTRT Bit */
00743     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
00744 
00745     /* Wait for last operation to be completed */
00746     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00747 
00748     /* If the option byte program operation is completed, disable the OPTSTRT Bit */
00749     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
00750   }
00751 
00752   return status;
00753 }
00754 
00755 /**
00756   * @brief  Program the FLASH User Option Byte.
00757   *
00758   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
00759   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
00760   * @note   To validate the user option bytes, the option bytes must be reloaded
00761   *         through the call of the HAL_FLASH_OB_Launch() function.
00762   *
00763   * @param  UserType The FLASH User Option Bytes to be modified
00764   * @param  UserConfig The FLASH User Option Bytes values:
00765   *         BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), IWDG_SW(Bit16),
00766   *         IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19), BFB2(Bit20),
00767   *         DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).
00768   *
00769   * @retval HAL status
00770   */
00771 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
00772 {
00773   uint32_t optr_reg_val = 0;
00774   uint32_t optr_reg_mask = 0;
00775   HAL_StatusTypeDef status;
00776 
00777   /* Check the parameters */
00778   assert_param(IS_OB_USER_TYPE(UserType));
00779 
00780   /* Wait for last operation to be completed */
00781   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00782 
00783   if(status == HAL_OK)
00784   {
00785     if((UserType & OB_USER_BOR_LEV) != 0U)
00786     {
00787       /* BOR level option byte should be modified */
00788       assert_param(IS_OB_USER_BOR_LEVEL(UserConfig & FLASH_OPTR_BOR_LEV));
00789 
00790       /* Set value and mask for BOR level option byte */
00791       optr_reg_val |= (UserConfig & FLASH_OPTR_BOR_LEV);
00792       optr_reg_mask |= FLASH_OPTR_BOR_LEV;
00793     }
00794 
00795     if((UserType & OB_USER_nRST_STOP) != 0U)
00796     {
00797       /* nRST_STOP option byte should be modified */
00798       assert_param(IS_OB_USER_STOP(UserConfig & FLASH_OPTR_nRST_STOP));
00799 
00800       /* Set value and mask for nRST_STOP option byte */
00801       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STOP);
00802       optr_reg_mask |= FLASH_OPTR_nRST_STOP;
00803     }
00804 
00805     if((UserType & OB_USER_nRST_STDBY) != 0U)
00806     {
00807       /* nRST_STDBY option byte should be modified */
00808       assert_param(IS_OB_USER_STANDBY(UserConfig & FLASH_OPTR_nRST_STDBY));
00809 
00810       /* Set value and mask for nRST_STDBY option byte */
00811       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STDBY);
00812       optr_reg_mask |= FLASH_OPTR_nRST_STDBY;
00813     }
00814 
00815     if((UserType & OB_USER_nRST_SHDW) != 0U)
00816     {
00817       /* nRST_SHDW option byte should be modified */
00818       assert_param(IS_OB_USER_SHUTDOWN(UserConfig & FLASH_OPTR_nRST_SHDW));
00819 
00820       /* Set value and mask for nRST_SHDW option byte */
00821       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_SHDW);
00822       optr_reg_mask |= FLASH_OPTR_nRST_SHDW;
00823     }
00824 
00825     if((UserType & OB_USER_IWDG_SW) != 0U)
00826     {
00827       /* IWDG_SW option byte should be modified */
00828       assert_param(IS_OB_USER_IWDG(UserConfig & FLASH_OPTR_IWDG_SW));
00829 
00830       /* Set value and mask for IWDG_SW option byte */
00831       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_SW);
00832       optr_reg_mask |= FLASH_OPTR_IWDG_SW;
00833     }
00834 
00835     if((UserType & OB_USER_IWDG_STOP) != 0U)
00836     {
00837       /* IWDG_STOP option byte should be modified */
00838       assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTR_IWDG_STOP));
00839 
00840       /* Set value and mask for IWDG_STOP option byte */
00841       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STOP);
00842       optr_reg_mask |= FLASH_OPTR_IWDG_STOP;
00843     }
00844 
00845     if((UserType & OB_USER_IWDG_STDBY) != 0U)
00846     {
00847       /* IWDG_STDBY option byte should be modified */
00848       assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTR_IWDG_STDBY));
00849 
00850       /* Set value and mask for IWDG_STDBY option byte */
00851       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STDBY);
00852       optr_reg_mask |= FLASH_OPTR_IWDG_STDBY;
00853     }
00854 
00855     if((UserType & OB_USER_WWDG_SW) != 0U)
00856     {
00857       /* WWDG_SW option byte should be modified */
00858       assert_param(IS_OB_USER_WWDG(UserConfig & FLASH_OPTR_WWDG_SW));
00859 
00860       /* Set value and mask for WWDG_SW option byte */
00861       optr_reg_val |= (UserConfig & FLASH_OPTR_WWDG_SW);
00862       optr_reg_mask |= FLASH_OPTR_WWDG_SW;
00863     }
00864 
00865 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00866     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00867     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00868     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00869     if((UserType & OB_USER_BFB2) != 0U)
00870     {
00871       /* BFB2 option byte should be modified */
00872       assert_param(IS_OB_USER_BFB2(UserConfig & FLASH_OPTR_BFB2));
00873 
00874       /* Set value and mask for BFB2 option byte */
00875       optr_reg_val |= (UserConfig & FLASH_OPTR_BFB2);
00876       optr_reg_mask |= FLASH_OPTR_BFB2;
00877     }
00878 
00879     if((UserType & OB_USER_DUALBANK) != 0U)
00880     {
00881 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00882       /* DUALBANK option byte should be modified */
00883       assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DB1M));
00884 
00885       /* Set value and mask for DUALBANK option byte */
00886       optr_reg_val |= (UserConfig & FLASH_OPTR_DB1M);
00887       optr_reg_mask |= FLASH_OPTR_DB1M;
00888 #else
00889       /* DUALBANK option byte should be modified */
00890       assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DUALBANK));
00891 
00892       /* Set value and mask for DUALBANK option byte */
00893       optr_reg_val |= (UserConfig & FLASH_OPTR_DUALBANK);
00894       optr_reg_mask |= FLASH_OPTR_DUALBANK;
00895 #endif
00896     }
00897 #endif
00898 
00899     if((UserType & OB_USER_nBOOT1) != 0U)
00900     {
00901       /* nBOOT1 option byte should be modified */
00902       assert_param(IS_OB_USER_BOOT1(UserConfig & FLASH_OPTR_nBOOT1));
00903 
00904       /* Set value and mask for nBOOT1 option byte */
00905       optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT1);
00906       optr_reg_mask |= FLASH_OPTR_nBOOT1;
00907     }
00908 
00909     if((UserType & OB_USER_SRAM2_PE) != 0U)
00910     {
00911       /* SRAM2_PE option byte should be modified */
00912       assert_param(IS_OB_USER_SRAM2_PARITY(UserConfig & FLASH_OPTR_SRAM2_PE));
00913 
00914       /* Set value and mask for SRAM2_PE option byte */
00915       optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_PE);
00916       optr_reg_mask |= FLASH_OPTR_SRAM2_PE;
00917     }
00918 
00919     if((UserType & OB_USER_SRAM2_RST) != 0U)
00920     {
00921       /* SRAM2_RST option byte should be modified */
00922       assert_param(IS_OB_USER_SRAM2_RST(UserConfig & FLASH_OPTR_SRAM2_RST));
00923 
00924       /* Set value and mask for SRAM2_RST option byte */
00925       optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_RST);
00926       optr_reg_mask |= FLASH_OPTR_SRAM2_RST;
00927     }
00928 
00929 #if defined (STM32L412xx) || defined (STM32L422xx) || defined (STM32L431xx) || defined (STM32L432xx) || defined (STM32L433xx) || \
00930     defined (STM32L442xx) || defined (STM32L443xx) || defined (STM32L451xx) || defined (STM32L452xx) || defined (STM32L462xx) || \
00931     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00932     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00933     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00934     if((UserType & OB_USER_nSWBOOT0) != 0U)
00935     {
00936       /* nSWBOOT0 option byte should be modified */
00937       assert_param(IS_OB_USER_SWBOOT0(UserConfig & FLASH_OPTR_nSWBOOT0));
00938 
00939       /* Set value and mask for nSWBOOT0 option byte */
00940       optr_reg_val |= (UserConfig & FLASH_OPTR_nSWBOOT0);
00941       optr_reg_mask |= FLASH_OPTR_nSWBOOT0;
00942     }
00943 
00944     if((UserType & OB_USER_nBOOT0) != 0U)
00945     {
00946       /* nBOOT0 option byte should be modified */
00947       assert_param(IS_OB_USER_BOOT0(UserConfig & FLASH_OPTR_nBOOT0));
00948 
00949       /* Set value and mask for nBOOT0 option byte */
00950       optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT0);
00951       optr_reg_mask |= FLASH_OPTR_nBOOT0;
00952     }
00953 #endif
00954 
00955     /* Configure the option bytes register */
00956     MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);
00957 
00958     /* Set OPTSTRT Bit */
00959     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
00960 
00961     /* Wait for last operation to be completed */
00962     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00963 
00964     /* If the option byte program operation is completed, disable the OPTSTRT Bit */
00965     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
00966   }
00967 
00968   return status;
00969 }
00970 
00971 /**
00972   * @brief  Configure the Proprietary code readout protection of the desired addresses.
00973   *
00974   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
00975   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
00976   * @note   To validate the PCROP options, the option bytes must be reloaded
00977   *         through the call of the HAL_FLASH_OB_Launch() function.
00978   *
00979   * @param  PCROPConfig specifies the configuration (Bank to be configured and PCROP_RDP option).
00980   *          This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
00981   *          with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE
00982   *
00983   * @param  PCROPStartAddr specifies the start address of the Proprietary code readout protection
00984   *          This parameter can be an address between begin and end of the bank
00985   *
00986   * @param  PCROPEndAddr specifies the end address of the Proprietary code readout protection
00987   *          This parameter can be an address between PCROPStartAddr and end of the bank
00988   *
00989   * @retval HAL Status
00990   */
00991 static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr)
00992 {
00993   HAL_StatusTypeDef status;
00994   uint32_t reg_value;
00995   uint32_t bank1_addr;
00996 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00997     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00998     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00999     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01000   uint32_t bank2_addr;
01001 #endif
01002 
01003   /* Check the parameters */
01004   assert_param(IS_FLASH_BANK_EXCLUSIVE(PCROPConfig & FLASH_BANK_BOTH));
01005   assert_param(IS_OB_PCROP_RDP(PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
01006   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPStartAddr));
01007   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPEndAddr));
01008 
01009   /* Wait for last operation to be completed */
01010   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01011 
01012   if(status == HAL_OK)
01013   {
01014 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
01015     defined (STM32L496xx) || defined (STM32L4A6xx) || \
01016     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
01017     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01018     /* Get the information about the bank swapping */
01019     if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
01020     {
01021       bank1_addr = FLASH_BASE;
01022       bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
01023     }
01024     else
01025     {
01026       bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
01027       bank2_addr = FLASH_BASE;
01028     }
01029 #else
01030     bank1_addr = FLASH_BASE;
01031 #endif
01032 
01033 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01034     if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
01035     {
01036       /* Configure the Proprietary code readout protection */
01037       if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
01038       {
01039         reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);
01040         MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
01041 
01042         reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);
01043         MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
01044       }
01045       else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
01046       {
01047         reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);
01048         MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
01049 
01050         reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);
01051         MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
01052       }
01053       else
01054       {
01055         /* Nothing to do */
01056       }
01057     }
01058     else
01059 #endif
01060     {
01061       /* Configure the Proprietary code readout protection */
01062       if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
01063       {
01064         reg_value = ((PCROPStartAddr - bank1_addr) >> 3);
01065         MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
01066 
01067         reg_value = ((PCROPEndAddr - bank1_addr) >> 3);
01068         MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
01069       }
01070 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
01071     defined (STM32L496xx) || defined (STM32L4A6xx) || \
01072     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
01073     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01074       else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
01075       {
01076         reg_value = ((PCROPStartAddr - bank2_addr) >> 3);
01077         MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
01078 
01079         reg_value = ((PCROPEndAddr - bank2_addr) >> 3);
01080         MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
01081       }
01082 #endif
01083       else
01084       {
01085         /* Nothing to do */
01086       }
01087     }
01088 
01089     MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP_RDP, (PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
01090 
01091     /* Set OPTSTRT Bit */
01092     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
01093 
01094     /* Wait for last operation to be completed */
01095     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
01096 
01097     /* If the option byte program operation is completed, disable the OPTSTRT Bit */
01098     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
01099   }
01100 
01101   return status;
01102 }
01103 
01104 /**
01105   * @brief  Return the FLASH Write Protection Option Bytes value.
01106   *
01107   * @param[in]  WRPArea: specifies the area to be returned.
01108   *          This parameter can be one of the following values:
01109   *            @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
01110   *            @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
01111   *            @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply to STM32L43x/STM32L44x devices)
01112   *            @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply to STM32L43x/STM32L44x devices)
01113   *
01114   * @param[out]  WRPStartOffset: specifies the address where to copied the start page
01115   *                         of the write protected area
01116   *
01117   * @param[out]  WRDPEndOffset: specifies the address where to copied the end page of
01118   *                        the write protected area
01119   *
01120   * @retval None
01121   */
01122 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset)
01123 {
01124   /* Get the configuration of the write protected area */
01125   if(WRPArea == OB_WRPAREA_BANK1_AREAA)
01126   {
01127     *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
01128     *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> 16);
01129   }
01130   else if(WRPArea == OB_WRPAREA_BANK1_AREAB)
01131   {
01132     *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
01133     *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> 16);
01134   }
01135 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
01136     defined (STM32L496xx) || defined (STM32L4A6xx) || \
01137     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
01138     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01139   else if(WRPArea == OB_WRPAREA_BANK2_AREAA)
01140   {
01141     *WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);
01142     *WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> 16);
01143   }
01144   else if(WRPArea == OB_WRPAREA_BANK2_AREAB)
01145   {
01146     *WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);
01147     *WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> 16);
01148   }
01149 #endif
01150   else
01151   {
01152     /* Nothing to do */
01153   }
01154 }
01155 
01156 /**
01157   * @brief  Return the FLASH Read Protection level.
01158   * @retval FLASH ReadOut Protection Status:
01159   *         This return value can be one of the following values:
01160   *            @arg OB_RDP_LEVEL_0: No protection
01161   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
01162   *            @arg OB_RDP_LEVEL_2: Full chip protection
01163   */
01164 static uint32_t FLASH_OB_GetRDP(void)
01165 {
01166   uint32_t rdp_level = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
01167 
01168   if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
01169   {
01170     return (OB_RDP_LEVEL_1);
01171   }
01172   else
01173   {
01174     return (READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP));
01175   }
01176 }
01177 
01178 /**
01179   * @brief  Return the FLASH User Option Byte value.
01180   * @retval The FLASH User Option Bytes values:
01181   *      For STM32L47x/STM32L48x devices :
01182   *         BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),
01183   *         IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),
01184   *         BFB2(Bit20), DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).
01185   *      For STM32L43x/STM32L44x devices :
01186   *         BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),
01187   *         IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),
01188   *         nBOOT1(Bit23), SRAM2_PE(Bit24), SRAM2_RST(Bit25), nSWBOOT0(Bit26) and nBOOT0(Bit27).
01189   */
01190 static uint32_t FLASH_OB_GetUser(void)
01191 {
01192   uint32_t user_config = READ_REG(FLASH->OPTR);
01193   CLEAR_BIT(user_config, FLASH_OPTR_RDP);
01194 
01195   return user_config;
01196 }
01197 
01198 /**
01199   * @brief  Return the FLASH Write Protection Option Bytes value.
01200   *
01201   * @param PCROPConfig [inout]: specifies the configuration (Bank to be configured and PCROP_RDP option).
01202   *          This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
01203   *          with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE
01204   *
01205   * @param PCROPStartAddr [out]: specifies the address where to copied the start address
01206   *                         of the Proprietary code readout protection
01207   *
01208   * @param PCROPEndAddr [out]: specifies the address where to copied the end address of
01209   *                       the Proprietary code readout protection
01210   *
01211   * @retval None
01212   */
01213 static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr)
01214 {
01215   uint32_t reg_value;
01216   uint32_t bank1_addr;
01217 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
01218     defined (STM32L496xx) || defined (STM32L4A6xx) || \
01219     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
01220     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01221   uint32_t bank2_addr;
01222 #endif
01223 
01224 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
01225     defined (STM32L496xx) || defined (STM32L4A6xx) || \
01226     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
01227     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01228   /* Get the information about the bank swapping */
01229   if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
01230   {
01231     bank1_addr = FLASH_BASE;
01232     bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
01233   }
01234   else
01235   {
01236     bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
01237     bank2_addr = FLASH_BASE;
01238   }
01239 #else
01240   bank1_addr = FLASH_BASE;
01241 #endif
01242 
01243 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01244   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
01245   {
01246     if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
01247     {
01248       reg_value       = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
01249       *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;
01250 
01251       reg_value     = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
01252       *PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;
01253     }
01254     else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
01255     {
01256       reg_value       = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
01257       *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;
01258 
01259       reg_value     = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
01260       *PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;;
01261     }
01262     else
01263     {
01264       /* Nothing to do */
01265     }
01266   }
01267   else
01268 #endif
01269   {
01270     if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
01271     {
01272       reg_value       = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
01273       *PCROPStartAddr = (reg_value << 3) + bank1_addr;
01274 
01275       reg_value     = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
01276       *PCROPEndAddr = (reg_value << 3) + bank1_addr + 0x7U;
01277     }
01278 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
01279     defined (STM32L496xx) || defined (STM32L4A6xx) || \
01280     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
01281     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
01282     else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
01283     {
01284       reg_value       = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
01285       *PCROPStartAddr = (reg_value << 3) + bank2_addr;
01286 
01287       reg_value     = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
01288       *PCROPEndAddr = (reg_value << 3) + bank2_addr + 0x7U;
01289     }
01290 #endif
01291     else
01292     {
01293       /* Nothing to do */
01294     }
01295   }
01296 
01297   *PCROPConfig |= (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP_RDP);
01298 }
01299 /**
01300   * @}
01301   */
01302 
01303 /**
01304   * @}
01305   */
01306 
01307 #endif /* HAL_FLASH_MODULE_ENABLED */
01308 
01309 /**
01310   * @}
01311   */
01312 
01313 /**
01314   * @}
01315   */
01316