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