1 /**
2   ******************************************************************************
3   * @file    stm32l0xx_hal_flash_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended FLASH HAL module driver.
6   *
7   *          This file provides firmware functions to manage the following
8   *          functionalities of the internal FLASH memory:
9   *            + FLASH Interface configuration
10   *            + FLASH Memory Erasing
11   *            + DATA EEPROM Programming/Erasing
12   *            + Option Bytes Programming
13   *            + Interrupts management
14   *
15   @verbatim
16   ==============================================================================
17                ##### Flash peripheral Extended features  #####
18   ==============================================================================
19 
20   [..] Comparing to other products, the FLASH interface for STM32L0xx
21        devices contains the following additional features
22        (+) Erase functions
23        (+) DATA_EEPROM memory management
24        (+) BOOT option bit configuration
25        (+) PCROP protection for all sectors
26 
27                       ##### How to use this driver #####
28   ==============================================================================
29   [..] This driver provides functions to configure and program the FLASH memory
30        of all STM32L0xx. It includes:
31        (+) Full DATA_EEPROM erase and program management
32        (+) Boot activation
33        (+) PCROP protection configuration and control for all pages
34 
35   @endverbatim
36   ******************************************************************************
37   * @attention
38   *
39   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
40   *
41   * Redistribution and use in source and binary forms, with or without modification,
42   * are permitted provided that the following conditions are met:
43   *   1. Redistributions of source code must retain the above copyright notice,
44   *      this list of conditions and the following disclaimer.
45   *   2. Redistributions in binary form must reproduce the above copyright notice,
46   *      this list of conditions and the following disclaimer in the documentation
47   *      and/or other materials provided with the distribution.
48   *   3. Neither the name of STMicroelectronics nor the names of its contributors
49   *      may be used to endorse or promote products derived from this software
50   *      without specific prior written permission.
51   *
52   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
53   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
56   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
58   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
59   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
60   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
61   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62   *
63   ******************************************************************************
64   */
65 
66 /* Includes ------------------------------------------------------------------*/
67 #include "stm32l0xx_hal.h"
68 
69 /** @addtogroup STM32L0xx_HAL_Driver
70   * @{
71   */
72 #ifdef HAL_FLASH_MODULE_ENABLED
73 
74 /** @addtogroup FLASH
75   * @{
76   */
77 /** @addtogroup FLASH_Private_Variables
78  * @{
79  */
80 /* Variables used for Erase pages under interruption*/
81 extern FLASH_ProcessTypeDef pFlash;
82 /**
83   * @}
84   */
85 
86 /**
87   * @}
88   */
89 
90 /** @defgroup FLASHEx FLASHEx
91   * @brief FLASH HAL Extension module driver
92   * @{
93   */
94 
95 /* Private typedef -----------------------------------------------------------*/
96 /* Private define ------------------------------------------------------------*/
97 /** @defgroup FLASHEx_Private_Constants FLASHEx Private Constants
98  * @{
99  */
100 /**
101   * @}
102   */
103 
104 /* Private macro -------------------------------------------------------------*/
105 /** @defgroup FLASHEx_Private_Macros FLASHEx Private Macros
106   * @{
107   */
108 /**
109   * @}
110   */
111 
112 /* Private variables ---------------------------------------------------------*/
113 /* Private function prototypes -----------------------------------------------*/
114 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
115  * @{
116  */
117 void                      FLASH_PageErase(uint32_t PageAddress);
118 #if defined(FLASH_OPTR_BFB2)
119 static HAL_StatusTypeDef  FLASH_OB_BootConfig(uint8_t OB_BOOT);
120 #endif /* FLASH_OPTR_BFB2 */
121 static HAL_StatusTypeDef  FLASH_OB_RDPConfig(uint8_t OB_RDP);
122 static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);
123 static HAL_StatusTypeDef  FLASH_OB_BORConfig(uint8_t OB_BOR);
124 static uint8_t            FLASH_OB_GetRDP(void);
125 static uint8_t            FLASH_OB_GetUser(void);
126 static uint8_t            FLASH_OB_GetBOR(void);
127 static uint8_t            FLASH_OB_GetBOOTBit1(void);
128 static HAL_StatusTypeDef  FLASH_OB_BOOTBit1Config(uint8_t OB_BootBit1);
129 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
130 static HAL_StatusTypeDef  FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t Sector2, uint32_t NewState);
131 #else
132 static HAL_StatusTypeDef  FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t NewState);
133 #endif
134 static uint32_t           FLASH_OB_GetWRP(void);
135 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
136 static uint32_t           FLASH_OB_GetWRP2(void);
137 #endif
138 
139 /**
140   * @}
141   */
142 
143 /* Exported functions ---------------------------------------------------------*/
144 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
145   * @{
146   */
147 
148 /** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
149  *  @brief   FLASH Memory Erasing functions
150  *
151 @verbatim
152   ==============================================================================
153                 ##### FLASH Erasing Programming functions #####
154   ==============================================================================
155 
156     [..] The FLASH Memory Erasing functions, includes the following functions:
157     (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
158     (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback
159         is called with parameter 0xFFFFFFFF
160 
161     [..] Any operation of erase should follow these steps:
162     (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and
163         program memory access.
164     (#) Call the desired function to erase page.
165     (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access
166        (recommended to protect the FLASH memory against possible unwanted operation).
167 
168 @endverbatim
169   * @{
170   */
171 
172 /**
173   * @brief  Erase the specified FLASH memory Pages
174   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
175   *         must be called before.
176   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
177   *         (recommended to protect the FLASH memory against possible unwanted operation)
178   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
179   *         contains the configuration information for the erasing.
180   *
181   * @param[out]  PageError pointer to variable  that
182   *         contains the configuration information on faulty page in case of error
183   *         (0xFFFFFFFF means that all the pages have been correctly erased)
184   *
185   * @retval HAL_StatusTypeDef HAL Status
186   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)187 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
188 {
189   HAL_StatusTypeDef status = HAL_ERROR;
190   uint32_t address = 0U;
191 
192   /* Process Locked */
193   __HAL_LOCK(&pFlash);
194 
195   /* Wait for last operation to be completed */
196   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
197 
198   if (status == HAL_OK)
199   {
200     /*Initialization of PageError variable*/
201     *PageError = 0xFFFFFFFFU;
202 
203     /* Check the parameters */
204     assert_param(IS_NBPAGES(pEraseInit->NbPages));
205     assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
206     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
207     assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));
208 
209     /* Erase page by page to be done*/
210     for(address = pEraseInit->PageAddress;
211         address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
212         address += FLASH_PAGE_SIZE)
213     {
214       FLASH_PageErase(address);
215 
216       /* Wait for last operation to be completed */
217       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
218 
219       /* If the erase operation is completed, disable the ERASE Bit */
220       CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
221       CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
222 
223       if (status != HAL_OK)
224       {
225         /* In case of error, stop erase procedure and return the faulty address */
226         *PageError = address;
227         break;
228       }
229     }
230   }
231 
232   /* Process Unlocked */
233   __HAL_UNLOCK(&pFlash);
234 
235   return status;
236 }
237 
238 /**
239   * @brief  Perform a page erase of the specified FLASH memory pages  with interrupt enabled
240   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
241   *         must be called before.
242   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
243   *         (recommended to protect the FLASH memory against possible unwanted operation)
244   *          End of erase is done when @ref HAL_FLASH_EndOfOperationCallback is called with parameter
245   *          0xFFFFFFFF
246   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
247   *         contains the configuration information for the erasing.
248   *
249   * @retval HAL_StatusTypeDef HAL Status
250   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)251 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
252 {
253   HAL_StatusTypeDef status = HAL_ERROR;
254 
255   /* If procedure already ongoing, reject the next one */
256   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
257   {
258     return HAL_ERROR;
259   }
260 
261   /* Check the parameters */
262   assert_param(IS_NBPAGES(pEraseInit->NbPages));
263   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
264   assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
265   assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1));
266 
267   /* Process Locked */
268   __HAL_LOCK(&pFlash);
269 
270   /* Wait for last operation to be completed */
271   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
272 
273   if (status == HAL_OK)
274   {
275     /* Enable End of FLASH Operation and Error source interrupts */
276     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
277 
278     pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
279     pFlash.NbPagesToErase = pEraseInit->NbPages;
280     pFlash.Page = pEraseInit->PageAddress;
281 
282     /*Erase 1st page and wait for IT*/
283     FLASH_PageErase(pEraseInit->PageAddress);
284   }
285   else
286   {
287     /* Process Unlocked */
288     __HAL_UNLOCK(&pFlash);
289   }
290 
291   return status;
292 }
293 
294 /**
295   * @}
296   */
297 
298 /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
299  *  @brief   Option Bytes Programming functions
300  *
301 @verbatim
302   ==============================================================================
303                 ##### Option Bytes Programming functions #####
304   ==============================================================================
305 
306     [..] Any operation of erase or program should follow these steps:
307     (#) Call the @ref HAL_FLASH_OB_Unlock() function to enable the Flash option control
308         register access.
309     (#) Call following function to program the desired option bytes.
310         (++) @ref HAL_FLASHEx_OBProgram:
311          - To Enable/Disable the desired sector write protection.
312          - To set the desired read Protection Level.
313          - To configure the user option Bytes: IWDG, STOP and the Standby.
314          - To Set the BOR level.
315     (#) Once all needed option bytes to be programmed are correctly written, call the
316         @ref HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process.
317     (#) Call the @ref HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended
318         to protect the option Bytes against possible unwanted operations).
319 
320     [..] Proprietary code Read Out Protection (PcROP):
321     (#) The PcROP sector is selected by using the same option bytes as the Write
322         protection (nWRPi bits). As a result, these 2 options are exclusive each other.
323     (#) In order to activate the PcROP (change the function of the nWRPi option bits),
324         the WPRMOD option bit must be activated.
325     (#) The active value of nWRPi bits is inverted when PCROP mode is active, this
326         means: if WPRMOD = 1 and nWRPi = 1 (default value), then the user sector "i"
327         is read/write protected.
328     (#) To activate PCROP mode for Flash sector(s), you need to call the following function:
329         (++) @ref HAL_FLASHEx_AdvOBProgram in selecting sectors to be read/write protected
330         (++) @ref HAL_FLASHEx_OB_SelectPCROP to enable the read/write protection
331 
332 @endverbatim
333   * @{
334   */
335 
336 /**
337   * @brief  Program option bytes
338   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
339   *         contains the configuration information for the programming.
340   *
341   * @retval HAL_StatusTypeDef HAL Status
342   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)343 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
344 {
345   HAL_StatusTypeDef status = HAL_ERROR;
346 
347   /* Process Locked */
348   __HAL_LOCK(&pFlash);
349 
350   /* Check the parameters */
351   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
352 
353   /*Write protection configuration*/
354   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
355   {
356     assert_param(IS_WRPSTATE(pOBInit->WRPState));
357 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
358     status = FLASH_OB_ProtectedSectorsConfig(pOBInit->WRPSector, pOBInit->WRPSector2, pOBInit->WRPState);
359 #else
360     status = FLASH_OB_ProtectedSectorsConfig(pOBInit->WRPSector, pOBInit->WRPState);
361 #endif
362     if (status != HAL_OK)
363     {
364       /* Process Unlocked */
365       __HAL_UNLOCK(&pFlash);
366       return status;
367     }
368   }
369 
370   /* Read protection configuration*/
371   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
372   {
373     status = FLASH_OB_RDPConfig(pOBInit->RDPLevel);
374     if (status != HAL_OK)
375     {
376       /* Process Unlocked */
377       __HAL_UNLOCK(&pFlash);
378       return status;
379     }
380   }
381 
382   /* USER  configuration*/
383   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
384   {
385     status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_IWDG_SW,
386                                  pOBInit->USERConfig & OB_STOP_NORST,
387                                  pOBInit->USERConfig & OB_STDBY_NORST);
388     if (status != HAL_OK)
389     {
390       /* Process Unlocked */
391       __HAL_UNLOCK(&pFlash);
392       return status;
393     }
394   }
395 
396   /* BOR Level  configuration*/
397   if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
398   {
399     status = FLASH_OB_BORConfig(pOBInit->BORLevel);
400     if (status != HAL_OK)
401     {
402       /* Process Unlocked */
403       __HAL_UNLOCK(&pFlash);
404       return status;
405     }
406   }
407 
408   /* Program BOOT Bit1 config option byte */
409   if ((pOBInit->OptionType & OPTIONBYTE_BOOT_BIT1) == OPTIONBYTE_BOOT_BIT1)
410   {
411     status = FLASH_OB_BOOTBit1Config(pOBInit->BOOTBit1Config);
412   }
413   /* Process Unlocked */
414   __HAL_UNLOCK(&pFlash);
415 
416   return status;
417 }
418 
419 /**
420   * @brief   Get the Option byte configuration
421   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
422   *         contains the configuration information for the programming.
423   *
424   * @retval None
425   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)426 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
427 {
428   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR;
429 
430   /* Get WRP sector */
431   pOBInit->WRPSector = FLASH_OB_GetWRP();
432 
433 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
434   pOBInit->WRPSector2 = FLASH_OB_GetWRP2();
435 #endif
436 
437   /*Get RDP Level*/
438   pOBInit->RDPLevel   = FLASH_OB_GetRDP();
439 
440   /*Get USER*/
441   pOBInit->USERConfig = FLASH_OB_GetUser();
442 
443   /*Get BOR Level*/
444   pOBInit->BORLevel   = FLASH_OB_GetBOR();
445 
446   /* Get BOOT bit 1 config OB */
447   pOBInit->BOOTBit1Config = FLASH_OB_GetBOOTBit1();
448 }
449 
450 #if defined(FLASH_OPTR_WPRMOD) || defined(FLASH_OPTR_BFB2)
451 
452 /**
453   * @brief  Program option bytes
454   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
455   *         contains the configuration information for the programming.
456   *
457   * @retval HAL_StatusTypeDef HAL Status
458   */
HAL_FLASHEx_AdvOBProgram(FLASH_AdvOBProgramInitTypeDef * pAdvOBInit)459 HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
460 {
461   HAL_StatusTypeDef status = HAL_ERROR;
462 
463   /* Check the parameters */
464   assert_param(IS_OBEX(pAdvOBInit->OptionType));
465 
466 #if defined(FLASH_OPTR_WPRMOD)
467 
468   /* Program PCROP option byte*/
469   if ((pAdvOBInit->OptionType & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP)
470   {
471     /* Check the parameters */
472     assert_param(IS_PCROPSTATE(pAdvOBInit->PCROPState));
473 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
474     status = FLASH_OB_ProtectedSectorsConfig(pAdvOBInit->PCROPSector, pAdvOBInit->PCROPSector2, pAdvOBInit->PCROPState);
475 #else
476     status = FLASH_OB_ProtectedSectorsConfig(pAdvOBInit->PCROPSector, pAdvOBInit->PCROPState);
477 #endif
478   }
479 
480 #endif /* FLASH_OPTR_WPRMOD */
481 
482 #if defined(FLASH_OPTR_BFB2)
483 
484   /* Program BOOT config option byte */
485   if ((pAdvOBInit->OptionType & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG)
486   {
487     status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig);
488   }
489 
490 #endif /* FLASH_OPTR_BFB2 */
491 
492   return status;
493 }
494 
495 /**
496   * @brief  Get the OBEX byte configuration
497   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
498   *         contains the configuration information for the programming.
499   *
500   * @retval None
501   */
HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef * pAdvOBInit)502 void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
503 {
504   pAdvOBInit->OptionType = 0;
505 
506 #if defined(FLASH_OPTR_WPRMOD)
507 
508   pAdvOBInit->OptionType |= OPTIONBYTE_PCROP;
509 
510 
511   /* Get PCROP state */
512   pAdvOBInit->PCROPState = (FLASH->OPTR & FLASH_OPTR_WPRMOD) >> FLASH_OPTR_WPRMOD_Pos;
513   /* Get PCROP protected sector */
514   pAdvOBInit->PCROPSector = FLASH->WRPR;
515 
516 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
517   /* Get PCROP protected sector */
518   pAdvOBInit->PCROPSector2 = FLASH->WRPR2;
519 #endif
520 #endif /* FLASH_OPTR_WPRMOD */
521 
522 #if defined(FLASH_OPTR_BFB2)
523 
524   pAdvOBInit->OptionType |= OPTIONBYTE_BOOTCONFIG;
525 
526   /* Get Boot config OB */
527   pAdvOBInit->BootConfig = (FLASH->OPTR & FLASH_OPTR_BFB2) >> 16U;
528 
529 #endif /* FLASH_OPTR_BFB2 */
530 }
531 
532 #endif /* FLASH_OPTR_WPRMOD || FLASH_OPTR_BFB2 */
533 
534 #if defined(FLASH_OPTR_WPRMOD)
535 
536 /**
537   * @brief  Select the Protection Mode (WPRMOD).
538   * @note   Once WPRMOD bit is active, unprotection of a protected sector is not possible
539   * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
540   * @retval HAL status
541   */
HAL_FLASHEx_OB_SelectPCROP(void)542 HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void)
543 {
544   HAL_StatusTypeDef status = HAL_OK;
545   uint16_t tmp1 = 0;
546   uint32_t tmp2 = 0;
547   uint8_t optiontmp = 0;
548   uint16_t optiontmp2 = 0;
549 
550   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
551 
552   /* Mask RDP Byte */
553   optiontmp =  (uint8_t)(*(__IO uint8_t *)(OB_BASE));
554 
555   /* Update Option Byte */
556   optiontmp2 = (uint16_t)(OB_PCROP_SELECTED | optiontmp);
557 
558   /* calculate the option byte to write */
559   tmp1 = (uint16_t)(~(optiontmp2 ));
560   tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));
561 
562   if(status == HAL_OK)
563   {
564     /* Clean the error context */
565     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
566 
567     /* program PCRop */
568     OB->RDP = tmp2;
569 
570     /* Wait for last operation to be completed */
571     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
572   }
573 
574   /* Return the Read protection operation Status */
575   return status;
576 }
577 
578 /**
579   * @brief  Deselect the Protection Mode (WPRMOD).
580   * @note   Once WPRMOD bit is active, unprotection of a protected sector is not possible
581   * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
582   * @retval HAL status
583   */
HAL_FLASHEx_OB_DeSelectPCROP(void)584 HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void)
585 {
586   HAL_StatusTypeDef status = HAL_OK;
587   uint16_t tmp1 = 0;
588   uint32_t tmp2 = 0;
589   uint8_t optiontmp = 0;
590   uint16_t optiontmp2 = 0;
591 
592   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
593 
594   /* Mask RDP Byte */
595   optiontmp =  (uint8_t)(*(__IO uint8_t *)(OB_BASE));
596 
597   /* Update Option Byte */
598   optiontmp2 = (uint16_t)(OB_PCROP_DESELECTED | optiontmp);
599 
600   /* calculate the option byte to write */
601   tmp1 = (uint16_t)(~(optiontmp2 ));
602   tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));
603 
604   if(status == HAL_OK)
605   {
606     /* Clean the error context */
607     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
608 
609     /* program PCRop */
610     OB->RDP = tmp2;
611 
612     /* Wait for last operation to be completed */
613     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
614   }
615 
616   /* Return the Read protection operation Status */
617   return status;
618 }
619 
620 #endif /* FLASH_OPTR_WPRMOD */
621 
622 /**
623   * @}
624   */
625 
626 /** @defgroup FLASHEx_Exported_Functions_Group3 DATA EEPROM Programming functions
627  *  @brief   DATA EEPROM Programming functions
628  *
629 @verbatim
630  ===============================================================================
631                      ##### DATA EEPROM Programming functions #####
632  ===============================================================================
633 
634     [..] Any operation of erase or program should follow these steps:
635     (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function to enable the data EEPROM access
636         and Flash program erase control register access.
637     (#) Call the desired function to erase or program data.
638     (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to disable the data EEPROM access
639         and Flash program erase control register access(recommended
640         to protect the DATA_EEPROM against possible unwanted operation).
641 
642 @endverbatim
643   * @{
644   */
645 
646 /**
647   * @brief  Unlocks the data memory and FLASH_PECR register access.
648   * @retval HAL_StatusTypeDef HAL Status
649   */
HAL_FLASHEx_DATAEEPROM_Unlock(void)650 HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void)
651 {
652   if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET)
653   {
654     /* Unlocking the Data memory and FLASH_PECR register access*/
655     FLASH->PEKEYR = FLASH_PEKEY1;
656     FLASH->PEKEYR = FLASH_PEKEY2;
657   }
658   else
659   {
660     return HAL_ERROR;
661   }
662   return HAL_OK;
663 }
664 
665 /**
666   * @brief  Locks the Data memory and FLASH_PECR register access.
667   * @retval HAL_StatusTypeDef HAL Status
668   */
HAL_FLASHEx_DATAEEPROM_Lock(void)669 HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void)
670 {
671   /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */
672   SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);
673 
674   return HAL_OK;
675 }
676 
677 /**
678   * @brief  Erase a word in data memory.
679   * @param  Address specifies the address to be erased.
680   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
681   *         must be called before.
682   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access
683   *         and Flash program erase control register access(recommended to protect
684   *         the DATA_EEPROM against possible unwanted operation).
685   * @retval HAL_StatusTypeDef HAL Status
686   */
HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)687 HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t Address)
688 {
689   HAL_StatusTypeDef status = HAL_OK;
690 
691   /* Check the parameters */
692   assert_param(IS_FLASH_DATA_ADDRESS(Address));
693 
694   /* Wait for last operation to be completed */
695   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
696 
697   if(status == HAL_OK)
698   {
699     /* Clean the error context */
700     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
701 
702       /* Write 00000000h to valid address in the data memory */
703       *(__IO uint32_t *) Address = 0x00000000U;
704 
705     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
706   }
707 
708   /* Return the erase status */
709   return status;
710 }
711 
712 /**
713   * @brief  Program word at a specified address
714   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
715   *         must be called before.
716   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() to he data EEPROM access
717   *         and Flash program erase control register access(recommended to protect
718   *         the DATA_EEPROM against possible unwanted operation).
719   * @note   The function @ref HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram() can be called before
720   *         this function to configure the Fixed Time Programming.
721   * @param  TypeProgram  Indicate the way to program at a specified address.
722   *         This parameter can be a value of @ref FLASHEx_Type_Program_Data
723   * @param  Address  specifie the address to be programmed.
724   * @param  Data     specifie the data to be programmed
725   *
726   * @retval HAL_StatusTypeDef HAL Status
727   */
728 
HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram,uint32_t Address,uint32_t Data)729 HAL_StatusTypeDef   HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
730 {
731   HAL_StatusTypeDef status = HAL_ERROR;
732 
733   /* Process Locked */
734   __HAL_LOCK(&pFlash);
735 
736   /* Check the parameters */
737   assert_param(IS_TYPEPROGRAMDATA(TypeProgram));
738   assert_param(IS_FLASH_DATA_ADDRESS(Address));
739 
740   /* Wait for last operation to be completed */
741   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
742 
743   if(status == HAL_OK)
744   {
745     /* Clean the error context */
746     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
747 
748     if(TypeProgram == FLASH_TYPEPROGRAMDATA_WORD)
749     {
750       /* Program word (32-bit) at a specified address.*/
751       *(__IO uint32_t *)Address = Data;
752     }
753     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_HALFWORD)
754     {
755       /* Program halfword (16-bit) at a specified address.*/
756       *(__IO uint16_t *)Address = (uint16_t) Data;
757     }
758     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_BYTE)
759     {
760       /* Program byte (8-bit) at a specified address.*/
761       *(__IO uint8_t *)Address = (uint8_t) Data;
762     }
763     else
764     {
765       status = HAL_ERROR;
766     }
767 
768     if (status != HAL_OK)
769     {
770       /* Wait for last operation to be completed */
771       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
772     }
773   }
774 
775   /* Process Unlocked */
776   __HAL_UNLOCK(&pFlash);
777 
778   return status;
779 }
780 
781 /**
782   * @brief  Enable DATA EEPROM fixed Time programming (2*Tprog).
783   * @retval None
784   */
HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void)785 void HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void)
786 {
787   SET_BIT(FLASH->PECR, FLASH_PECR_FIX);
788 }
789 
790 /**
791   * @brief  Disables DATA EEPROM fixed Time programming (2*Tprog).
792   * @retval None
793   */
HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void)794 void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void)
795 {
796   CLEAR_BIT(FLASH->PECR, FLASH_PECR_FIX);
797 }
798 
799 /**
800   * @}
801   */
802 
803 /**
804   * @}
805   */
806 
807 /** @addtogroup FLASHEx_Private_Functions
808  * @{
809  */
810 
811 /*
812 ==============================================================================
813               OPTIONS BYTES
814 ==============================================================================
815 */
816 /**
817   * @brief  Enables or disables the read out protection.
818   * @note   To correctly run this function, the @ref HAL_FLASH_OB_Unlock() function
819   *         must be called before.
820   * @param  OB_RDP specifies the read protection level.
821   *   This parameter can be:
822   *     @arg @ref OB_RDP_LEVEL_0 No protection
823   *     @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
824   *     @arg @ref OB_RDP_LEVEL_2 Chip protection
825   *
826   *  !!!Warning!!! When enabling OB_RDP_LEVEL_2 it's no more possible to go back to level 1 or 0
827   *
828   * @retval HAL status
829   */
FLASH_OB_RDPConfig(uint8_t OB_RDP)830 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP)
831 {
832   HAL_StatusTypeDef status = HAL_OK;
833   uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
834 
835   /* Check the parameters */
836   assert_param(IS_OB_RDP(OB_RDP));
837 
838   tmp1 = (uint32_t)(OB->RDP & FLASH_OPTR_RDPROT);
839 
840 #if defined(FLASH_OPTR_WPRMOD)
841     /* Mask WPRMOD bit */
842     tmp3 = (uint32_t)(OB->RDP & FLASH_OPTR_WPRMOD);
843 #endif
844 
845     /* calculate the option byte to write */
846     tmp1 = (~((uint32_t)(OB_RDP | tmp3)));
847     tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)(OB_RDP | tmp3)));
848 
849     /* Wait for last operation to be completed */
850     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
851 
852     if(status == HAL_OK)
853     {
854       /* Clean the error context */
855       pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
856 
857       /* program read protection level */
858       OB->RDP = tmp2;
859 
860       /* Wait for last operation to be completed */
861       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
862     }
863 
864   /* Return the Read protection operation Status */
865   return status;
866 }
867 
868 /**
869   * @brief  Programs the FLASH brownout reset threshold level Option Byte.
870   * @param  OB_BOR Selects the brownout reset threshold level.
871   *   This parameter can be one of the following values:
872   *     @arg @ref OB_BOR_OFF BOR is disabled at power down, the reset is asserted when the VDD
873   *                      power supply reaches the PDR(Power Down Reset) threshold (1.5V)
874   *     @arg @ref OB_BOR_LEVEL1 BOR Reset threshold levels for 1.7V - 1.8V VDD power supply
875   *     @arg @ref OB_BOR_LEVEL2 BOR Reset threshold levels for 1.9V - 2.0V VDD power supply
876   *     @arg @ref OB_BOR_LEVEL3 BOR Reset threshold levels for 2.3V - 2.4V VDD power supply
877   *     @arg @ref OB_BOR_LEVEL4 BOR Reset threshold levels for 2.55V - 2.65V VDD power supply
878   *     @arg @ref OB_BOR_LEVEL5 BOR Reset threshold levels for 2.8V - 2.9V VDD power supply
879   * @retval HAL status
880   */
FLASH_OB_BORConfig(uint8_t OB_BOR)881 static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR)
882 {
883   HAL_StatusTypeDef status = HAL_OK;
884   uint32_t tmp = 0, tmp1 = 0;
885 
886   /* Check the parameters */
887   assert_param(IS_OB_BOR_LEVEL(OB_BOR));
888 
889   /* Get the User Option byte register */
890   tmp1 = OB->USER & ((~FLASH_OPTR_BOR_LEV) >> 16U);
891 
892   /* Calculate the option byte to write - [0xFF | nUSER | 0x00 | USER]*/
893   tmp = (uint32_t)~((OB_BOR | tmp1)) << 16U;
894   tmp |= (OB_BOR | tmp1);
895 
896   /* Wait for last operation to be completed */
897   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
898 
899   if(status == HAL_OK)
900   {
901     /* Clean the error context */
902     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
903 
904     /* Write the BOR Option Byte */
905     OB->USER = tmp;
906 
907     /* Wait for last operation to be completed */
908     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
909   }
910 
911   /* Return the Option Byte BOR programmation Status */
912   return status;
913 }
914 
915 /**
916   * @brief  Sets or resets the BOOT bit1 option bit.
917   * @param  OB_BootBit1 Set or Reset the BOOT bit1 option bit.
918   *          This parameter can be one of the following values:
919   *             @arg @ref OB_BOOT_BIT1_RESET BOOT1 option bit reset
920   *             @arg @ref OB_BOOT_BIT1_SET BOOT1 option bit set
921   * @retval HAL status
922   */
FLASH_OB_BOOTBit1Config(uint8_t OB_BootBit1)923 static HAL_StatusTypeDef  FLASH_OB_BOOTBit1Config(uint8_t OB_BootBit1)
924 {
925   HAL_StatusTypeDef status = HAL_OK;
926   uint32_t tmp = 0, tmp1 = 0, OB_Bits = ((uint32_t) OB_BootBit1) << 15;
927 
928   /* Check the parameters */
929   assert_param(IS_OB_BOOT1(OB_BootBit1));
930 
931   /* Get the User Option byte register */
932   tmp1 = OB->USER & ((~FLASH_OPTR_BOOT1) >> 16U);
933 
934   /* Calculate the user option byte to write */
935   tmp = (~(OB_Bits | tmp1)) << 16U;
936   tmp |= OB_Bits | tmp1;
937 
938   /* Wait for last operation to be completed */
939   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
940 
941   if(status == HAL_OK)
942   {
943     /* Clean the error context */
944     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
945     /* Program OB */
946     OB->USER = tmp;
947     /* Wait for last operation to be completed */
948     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
949   }
950 
951   return status;
952 }
953 
954 /**
955   * @brief  Returns the FLASH User Option Bytes values.
956   * @retval The FLASH User Option Bytes.
957   */
FLASH_OB_GetUser(void)958 static uint8_t FLASH_OB_GetUser(void)
959 {
960   /* Return the User Option Byte */
961   return (uint8_t)((FLASH->OPTR & FLASH_OPTR_USER) >> 16U);
962 }
963 
964 /**
965   * @brief  Returns the FLASH Read Protection level.
966   * @retval FLASH RDP level
967   *         This parameter can be one of the following values:
968   *            @arg @ref OB_RDP_LEVEL_0 No protection
969   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
970   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
971   */
FLASH_OB_GetRDP(void)972 static uint8_t FLASH_OB_GetRDP(void)
973 {
974   return (uint8_t)(FLASH->OPTR & FLASH_OPTR_RDPROT);
975 }
976 
977 /**
978   * @brief  Returns the FLASH BOR level.
979   * @retval The BOR level Option Bytes.
980   */
FLASH_OB_GetBOR(void)981 static uint8_t FLASH_OB_GetBOR(void)
982 {
983   /* Return the BOR level */
984   return (uint8_t)((FLASH->OPTR & (uint32_t)FLASH_OPTR_BOR_LEV) >> 16U);
985 }
986 
987 /**
988   * @brief  Returns the FLASH BOOT bit1 value.
989   * @retval The BOOT bit 1 value Option Bytes.
990   */
FLASH_OB_GetBOOTBit1(void)991 static uint8_t FLASH_OB_GetBOOTBit1(void)
992 {
993   /* Return the BOR level */
994   return (FLASH->OPTR & FLASH_OPTR_BOOT1) >> FLASH_OPTR_BOOT1_Pos;
995 
996 }
997 
998 /**
999   * @brief  Returns the FLASH Write Protection Option Bytes value.
1000   * @retval The FLASH Write Protection Option Bytes value.
1001   */
FLASH_OB_GetWRP(void)1002 static uint32_t FLASH_OB_GetWRP(void)
1003 {
1004   /* Return the FLASH write protection Register value */
1005   return (uint32_t)(FLASH->WRPR);
1006 }
1007 
1008 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
1009 /**
1010   * @brief  Returns the FLASH Write Protection Option Bytes value.
1011   * @retval The FLASH Write Protection Option Bytes value.
1012   */
FLASH_OB_GetWRP2(void)1013 static uint32_t FLASH_OB_GetWRP2(void)
1014 {
1015   /* Return the FLASH write protection Register value */
1016   return (uint32_t)(FLASH->WRPR2);
1017 }
1018 #endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */
1019 
1020 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
1021 /**
1022   * @brief  Write Option Byte of the desired pages of the Flash.
1023   * @param  Sector specifies the sectors to be write protected.
1024   * @param  Sector2 specifies the sectors to be write protected (only stm32l07xxx and stm32l08xxx devices)
1025   * @param  NewState new state of the specified FLASH Pages Write protection.
1026   *   This parameter can be:
1027   *        @arg @ref OB_WRPSTATE_ENABLE
1028   *        @arg @ref OB_WRPSTATE_DISABLE
1029   * @retval HAL_StatusTypeDef
1030   */
FLASH_OB_ProtectedSectorsConfig(uint32_t Sector,uint32_t Sector2,uint32_t NewState)1031 static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t Sector2, uint32_t NewState)
1032 #else
1033 /**
1034   * @brief  Write Option Byte of the desired pages of the Flash.
1035   * @param  Sector specifies the sectors to be write protected.
1036   * @param  NewState new state of the specified FLASH Pages Write protection.
1037   *   This parameter can be:
1038   *        @arg @ref OB_WRPSTATE_ENABLE
1039   *        @arg @ref OB_WRPSTATE_DISABLE
1040   * @retval HAL_StatusTypeDef
1041   */
1042 static HAL_StatusTypeDef FLASH_OB_ProtectedSectorsConfig(uint32_t Sector, uint32_t NewState)
1043 #endif
1044 {
1045   HAL_StatusTypeDef status = HAL_OK;
1046   uint32_t WRP_Data = 0;
1047   uint32_t OB_WRP = Sector;
1048 
1049   /* Wait for last operation to be completed */
1050   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1051 
1052   if(status == HAL_OK)
1053   {
1054     /* Clean the error context */
1055     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1056 
1057     /* Update WRP only if at least 1 selected sector */
1058     if (OB_WRP != 0x00000000U)
1059     {
1060       if ((OB_WRP & WRP_MASK_LOW) != 0x00000000U)
1061       {
1062         if (NewState != OB_WRPSTATE_DISABLE)
1063         {
1064           WRP_Data = (uint16_t)(((OB_WRP & WRP_MASK_LOW) | OB->WRP01));
1065           OB->WRP01 = (uint32_t)(~(WRP_Data) << 16U) | (WRP_Data);
1066         }
1067         else
1068         {
1069           WRP_Data = (uint16_t)(~OB_WRP & (WRP_MASK_LOW & OB->WRP01));
1070           OB->WRP01 =  (uint32_t)((~WRP_Data) << 16U) | (WRP_Data);
1071         }
1072       }
1073     }
1074 #if defined(STM32L071xx) || defined(STM32L072xx) || defined(STM32L073xx) || defined(STM32L081xx) || defined(STM32L082xx) || defined(STM32L083xx)
1075     /* Update WRP only if at least 1 selected sector */
1076     if (OB_WRP != 0x00000000U)
1077     {
1078       if ((OB_WRP & WRP_MASK_HIGH) != 0x00000000U)
1079       {
1080         if (NewState != OB_WRPSTATE_DISABLE)
1081         {
1082           WRP_Data = (uint16_t)((((OB_WRP & WRP_MASK_HIGH) >> 16U | OB->WRP23)));
1083           OB->WRP23 = (uint32_t)(~(WRP_Data) << 16U) | (WRP_Data);
1084         }
1085         else
1086         {
1087           WRP_Data = (uint16_t)((((~OB_WRP & WRP_MASK_HIGH) >> 16U & OB->WRP23)));
1088           OB->WRP23 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data);
1089         }
1090       }
1091     }
1092 
1093     OB_WRP = Sector2;
1094     /* Update WRP only if at least 1 selected sector */
1095     if (OB_WRP != 0x00000000U)
1096     {
1097       if ((OB_WRP & WRP_MASK_LOW) != 0x00000000U)
1098       {
1099         if (NewState != OB_WRPSTATE_DISABLE)
1100         {
1101           WRP_Data = (uint16_t)(((OB_WRP & WRP_MASK_LOW) | OB->WRP45));
1102           OB->WRP45 =(uint32_t)(~(WRP_Data) << 16U) | (WRP_Data);
1103         }
1104         else
1105         {
1106           WRP_Data = (uint16_t)(~OB_WRP & (WRP_MASK_LOW & OB->WRP45));
1107           OB->WRP45 = (uint32_t)((~WRP_Data) << 16U) | (WRP_Data);
1108         }
1109       }
1110     }
1111 #endif /* STM32L071xx || STM32L072xx || STM32L073xx || STM32L081xx || STM32L082xx || STM32L083xx */
1112   }
1113   /* Wait for last operation to be completed */
1114   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1115 
1116   /* Return the write protection operation Status */
1117   return status;
1118 }
1119 
1120 /**
1121   * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
1122   * @param  OB_IWDG Selects the WDG mode.
1123   *   This parameter can be one of the following values:
1124   *     @arg @ref OB_IWDG_SW Software WDG selected
1125   *     @arg @ref OB_IWDG_HW Hardware WDG selected
1126   * @param  OB_STOP Reset event when entering STOP mode.
1127   *   This parameter can be one of the following values:
1128   *     @arg @ref OB_STOP_NORST No reset generated when entering in STOP
1129   *     @arg @ref OB_STOP_RST Reset generated when entering in STOP
1130   * @param  OB_STDBY Reset event when entering Standby mode.
1131   *   This parameter can be one of the following values:
1132   *     @arg @ref OB_STDBY_NORST No reset generated when entering in STANDBY
1133   *     @arg @ref OB_STDBY_RST Reset generated when entering in STANDBY
1134   * @retval HAL status
1135   */
FLASH_OB_UserConfig(uint8_t OB_IWDG,uint8_t OB_STOP,uint8_t OB_STDBY)1136 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
1137 {
1138   HAL_StatusTypeDef status = HAL_OK;
1139   uint32_t tmp = 0, tmp1 = 0;
1140 
1141   /* Check the parameters */
1142   assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
1143   assert_param(IS_OB_STOP_SOURCE(OB_STOP));
1144   assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
1145 
1146   /* Get the User Option byte register */
1147   tmp1 = OB->USER & ((~FLASH_OPTR_USER) >> 16U);
1148 
1149   /* Calculate the user option byte to write */
1150   tmp = (uint32_t)(((uint32_t)~((uint32_t)((uint32_t)(OB_IWDG) | (uint32_t)(OB_STOP) | (uint32_t)(OB_STDBY) | tmp1))) << 16U);
1151   tmp |= ((uint32_t)(OB_IWDG) | ((uint32_t)OB_STOP) | (uint32_t)(OB_STDBY) | tmp1);
1152 
1153   /* Wait for last operation to be completed */
1154   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1155 
1156   if(status == HAL_OK)
1157   {
1158     /* Clean the error context */
1159     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1160 
1161     /* Write the User Option Byte */
1162     OB->USER = tmp;
1163 
1164     /* Wait for last operation to be completed */
1165     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1166   }
1167 
1168   /* Return the Option Byte program Status */
1169   return status;
1170 }
1171 
1172 #if defined(FLASH_OPTR_BFB2)
1173 /**
1174   * @brief  Configures to boot from Bank1 or Bank2.
1175   * @param  OB_BOOT select the FLASH Bank to boot from.
1176   *   This parameter can be one of the following values:
1177   *          This parameter can be one of the following values:
1178   *             @arg @ref OB_BOOT_BANK1 BFB2 option bit reset
1179   *             @arg @ref OB_BOOT_BANK2 BFB2 option bit set
1180   * @retval HAL status
1181   */
FLASH_OB_BootConfig(uint8_t OB_BOOT)1182 static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT)
1183 {
1184   HAL_StatusTypeDef status = HAL_OK;
1185   uint32_t tmp = 0U, tmp1 = 0U;
1186 
1187   /* Check the parameters */
1188   assert_param(IS_OB_BOOT_BANK(OB_BOOT));
1189 
1190   /* Get the User Option byte register  and BOR Level*/
1191   tmp1 = OB->USER & ((~FLASH_OPTR_BFB2) >> 16U);
1192 
1193   /* Calculate the option byte to write */
1194   tmp = (uint32_t)~(OB_BOOT | tmp1) << 16U;
1195   tmp |= (OB_BOOT | tmp1);
1196 
1197   /* Wait for last operation to be completed */
1198   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1199 
1200   if(status == HAL_OK)
1201   {
1202     /* Clean the error context */
1203     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1204 
1205     /* Write the BOOT Option Byte */
1206     OB->USER = tmp;
1207 
1208     /* Wait for last operation to be completed */
1209     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1210   }
1211 
1212   /* Return the Option Byte program Status */
1213   return status;
1214 }
1215 
1216 #endif /* FLASH_OPTR_BFB2 */
1217 
1218 /**
1219   * @}
1220   */
1221 
1222 /**
1223   * @}
1224   */
1225 
1226 /** @addtogroup FLASH
1227   * @{
1228   */
1229 
1230 
1231 /** @addtogroup FLASH_Private_Functions
1232  * @{
1233  */
1234 
1235 /**
1236   * @brief  Erases a specified page in program memory.
1237   * @param  PageAddress The page address in program memory to be erased.
1238   * @note   A Page is erased in the Program memory only if the address to load
1239   *         is the start address of a page (multiple of @ref FLASH_PAGE_SIZE bytes).
1240   * @retval None
1241   */
FLASH_PageErase(uint32_t PageAddress)1242 void FLASH_PageErase(uint32_t PageAddress)
1243 {
1244   /* Clean the error context */
1245   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1246 
1247   /* Set the ERASE bit */
1248   SET_BIT(FLASH->PECR, FLASH_PECR_ERASE);
1249 
1250   /* Set PROG bit */
1251   SET_BIT(FLASH->PECR, FLASH_PECR_PROG);
1252 
1253   /* Write 00000000h to the first word of the program page to erase */
1254   *(__IO uint32_t *)(uint32_t)(PageAddress & ~(FLASH_PAGE_SIZE - 1)) = 0x00000000;
1255 }
1256 
1257 /**
1258   * @}
1259   */
1260 
1261 /**
1262   * @}
1263   */
1264 
1265 #endif /* HAL_FLASH_MODULE_ENABLED */
1266 /**
1267   * @}
1268   */
1269 
1270 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1271