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