1 /**
2   ******************************************************************************
3   * @file    stm32l1xx_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 STM32L1xx
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 STM32L1xx. 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) 2017 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 "stm32l1xx_hal.h"
68 
69 /** @addtogroup STM32L1xx_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 static HAL_StatusTypeDef  FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef *pOBInit, FunctionalState NewState);
119 static void               FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1, FunctionalState NewState);
120 #if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
121  || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
122  || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
123  || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
124 static void               FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2, FunctionalState NewState);
125 #endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
126 #if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
127  || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)   \
128  || defined(STM32L162xE)
129 static void               FLASH_OB_WRPConfigWRP3(uint32_t WRP3, FunctionalState NewState);
130 #endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
131 #if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
132  || defined(STM32L152xDX) || defined(STM32L162xDX)
133 static void               FLASH_OB_WRPConfigWRP4(uint32_t WRP4, FunctionalState NewState);
134 #endif /* STM32L151xE || STM32L152xE || STM32L151xDX || ... */
135 #if defined(FLASH_OBR_SPRMOD)
136 static HAL_StatusTypeDef  FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit, FunctionalState NewState);
137 #endif /* FLASH_OBR_SPRMOD */
138 #if defined(FLASH_OBR_nRST_BFB2)
139 static HAL_StatusTypeDef  FLASH_OB_BootConfig(uint8_t OB_BOOT);
140 #endif /* FLASH_OBR_nRST_BFB2 */
141 static HAL_StatusTypeDef  FLASH_OB_RDPConfig(uint8_t OB_RDP);
142 static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY);
143 static HAL_StatusTypeDef  FLASH_OB_BORConfig(uint8_t OB_BOR);
144 static uint8_t            FLASH_OB_GetRDP(void);
145 static uint8_t            FLASH_OB_GetUser(void);
146 static uint8_t            FLASH_OB_GetBOR(void);
147 static HAL_StatusTypeDef  FLASH_DATAEEPROM_FastProgramByte(uint32_t Address, uint8_t Data);
148 static HAL_StatusTypeDef  FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data);
149 static HAL_StatusTypeDef  FLASH_DATAEEPROM_FastProgramWord(uint32_t Address, uint32_t Data);
150 static HAL_StatusTypeDef  FLASH_DATAEEPROM_ProgramWord(uint32_t Address, uint32_t Data);
151 static HAL_StatusTypeDef  FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data);
152 static HAL_StatusTypeDef  FLASH_DATAEEPROM_ProgramByte(uint32_t Address, uint8_t Data);
153 /**
154   * @}
155   */
156 
157 /* Exported functions ---------------------------------------------------------*/
158 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
159   * @{
160   */
161 
162 /** @defgroup FLASHEx_Exported_Functions_Group1 FLASHEx Memory Erasing functions
163  *  @brief   FLASH Memory Erasing functions
164  *
165 @verbatim
166   ==============================================================================
167                 ##### FLASH Erasing Programming functions #####
168   ==============================================================================
169 
170     [..] The FLASH Memory Erasing functions, includes the following functions:
171     (+) @ref HAL_FLASHEx_Erase: return only when erase has been done
172     (+) @ref HAL_FLASHEx_Erase_IT: end of erase is done when @ref HAL_FLASH_EndOfOperationCallback
173         is called with parameter 0xFFFFFFFF
174 
175     [..] Any operation of erase should follow these steps:
176     (#) Call the @ref HAL_FLASH_Unlock() function to enable the flash control register and
177         program memory access.
178     (#) Call the desired function to erase page.
179     (#) Call the @ref HAL_FLASH_Lock() to disable the flash program memory access
180        (recommended to protect the FLASH memory against possible unwanted operation).
181 
182 @endverbatim
183   * @{
184   */
185 
186 /**
187   * @brief  Erase the specified FLASH memory Pages
188   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
189   *         must be called before.
190   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
191   *         (recommended to protect the FLASH memory against possible unwanted operation)
192   * @note   For STM32L151xDX/STM32L152xDX/STM32L162xDX, as memory is not continuous between
193   *         2 banks, user should perform pages erase by bank only.
194   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
195   *         contains the configuration information for the erasing.
196   *
197   * @param[out]  PageError pointer to variable  that
198   *         contains the configuration information on faulty page in case of error
199   *         (0xFFFFFFFF means that all the pages have been correctly erased)
200   *
201   * @retval HAL_StatusTypeDef HAL Status
202   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)203 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
204 {
205   HAL_StatusTypeDef status = HAL_ERROR;
206   uint32_t address = 0U;
207 
208   /* Process Locked */
209   __HAL_LOCK(&pFlash);
210 
211   /* Wait for last operation to be completed */
212   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
213 
214   if (status == HAL_OK)
215   {
216     /*Initialization of PageError variable*/
217     *PageError = 0xFFFFFFFFU;
218 
219     /* Check the parameters */
220     assert_param(IS_NBPAGES(pEraseInit->NbPages));
221     assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
222     assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
223     assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));
224 
225 #if defined(STM32L151xDX) || defined(STM32L152xDX) || defined(STM32L162xDX)
226     /* Check on which bank belongs the 1st address to erase */
227     if (pEraseInit->PageAddress < FLASH_BANK2_BASE)
228     {
229       /* BANK1 */
230       /* Check that last page to erase still belongs to BANK1 */
231       if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK1_END)
232       {
233         /*  Last page does not belong to BANK1, erase procedure cannot be performed because memory is not
234             continuous */
235         /* Process Unlocked */
236         __HAL_UNLOCK(&pFlash);
237         return HAL_ERROR;
238       }
239     }
240     else
241     {
242       /* BANK2 */
243       /* Check that last page to erase still belongs to BANK2 */
244       if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK2_END)
245       {
246         /*  Last page does not belong to BANK2, erase procedure cannot be performed because memory is not
247             continuous */
248         /* Process Unlocked */
249         __HAL_UNLOCK(&pFlash);
250         return HAL_ERROR;
251       }
252     }
253 #endif /* STM32L151xDX || STM32L152xDX || STM32L162xDX */
254 
255     /* Erase page by page to be done*/
256     for(address = pEraseInit->PageAddress;
257         address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
258         address += FLASH_PAGE_SIZE)
259     {
260       FLASH_PageErase(address);
261 
262       /* Wait for last operation to be completed */
263       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
264 
265       /* If the erase operation is completed, disable the ERASE Bit */
266       CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
267       CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
268 
269       if (status != HAL_OK)
270       {
271         /* In case of error, stop erase procedure and return the faulty address */
272         *PageError = address;
273         break;
274       }
275     }
276   }
277 
278   /* Process Unlocked */
279   __HAL_UNLOCK(&pFlash);
280 
281   return status;
282 }
283 
284 /**
285   * @brief  Perform a page erase of the specified FLASH memory pages  with interrupt enabled
286   * @note   To correctly run this function, the @ref HAL_FLASH_Unlock() function
287   *         must be called before.
288   *         Call the @ref HAL_FLASH_Lock() to disable the flash memory access
289   *         (recommended to protect the FLASH memory against possible unwanted operation)
290   *          End of erase is done when @ref HAL_FLASH_EndOfOperationCallback is called with parameter
291   *          0xFFFFFFFF
292   * @note   For STM32L151xDX/STM32L152xDX/STM32L162xDX, as memory is not continuous between
293   *         2 banks, user should perform pages erase by bank only.
294   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
295   *         contains the configuration information for the erasing.
296   *
297   * @retval HAL_StatusTypeDef HAL Status
298   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)299 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
300 {
301   HAL_StatusTypeDef status = HAL_ERROR;
302 
303   /* If procedure already ongoing, reject the next one */
304   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
305   {
306     return HAL_ERROR;
307   }
308 
309   /* Check the parameters */
310   assert_param(IS_NBPAGES(pEraseInit->NbPages));
311   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
312   assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
313   assert_param(IS_FLASH_PROGRAM_ADDRESS((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U));
314 
315   /* Process Locked */
316   __HAL_LOCK(&pFlash);
317 
318 #if defined(STM32L151xDX) || defined(STM32L152xDX) || defined(STM32L162xDX)
319     /* Check on which bank belongs the 1st address to erase */
320     if (pEraseInit->PageAddress < FLASH_BANK2_BASE)
321     {
322       /* BANK1 */
323       /* Check that last page to erase still belongs to BANK1 */
324       if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK1_END)
325       {
326         /*  Last page does not belong to BANK1, erase procedure cannot be performed because memory is not
327             continuous */
328         /* Process Unlocked */
329         __HAL_UNLOCK(&pFlash);
330         return HAL_ERROR;
331       }
332     }
333     else
334     {
335       /* BANK2 */
336       /* Check that last page to erase still belongs to BANK2 */
337       if (((pEraseInit->PageAddress & ~(FLASH_PAGE_SIZE - 1U)) + pEraseInit->NbPages * FLASH_PAGE_SIZE - 1U) > FLASH_BANK2_END)
338       {
339         /*  Last page does not belong to BANK2, erase procedure cannot be performed because memory is not
340             continuous */
341         /* Process Unlocked */
342         __HAL_UNLOCK(&pFlash);
343         return HAL_ERROR;
344       }
345     }
346 #endif /* STM32L151xDX || STM32L152xDX || STM32L162xDX */
347 
348   /* Wait for last operation to be completed */
349   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
350 
351   if (status == HAL_OK)
352   {
353     /* Enable End of FLASH Operation and Error source interrupts */
354     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
355 
356     pFlash.ProcedureOnGoing = FLASH_PROC_PAGEERASE;
357     pFlash.NbPagesToErase = pEraseInit->NbPages;
358     pFlash.Page = pEraseInit->PageAddress;
359 
360     /*Erase 1st page and wait for IT*/
361     FLASH_PageErase(pEraseInit->PageAddress);
362   }
363   else
364   {
365     /* Process Unlocked */
366     __HAL_UNLOCK(&pFlash);
367   }
368 
369   return status;
370 }
371 
372 /**
373   * @}
374   */
375 
376 /** @defgroup FLASHEx_Exported_Functions_Group2 Option Bytes Programming functions
377  *  @brief   Option Bytes Programming functions
378  *
379 @verbatim
380   ==============================================================================
381                 ##### Option Bytes Programming functions #####
382   ==============================================================================
383 
384     [..] Any operation of erase or program should follow these steps:
385     (#) Call the @ref HAL_FLASH_OB_Unlock() function to enable the Flash option control
386         register access.
387     (#) Call following function to program the desired option bytes.
388         (++) @ref HAL_FLASHEx_OBProgram:
389          - To Enable/Disable the desired sector write protection.
390          - To set the desired read Protection Level.
391          - To configure the user option Bytes: IWDG, STOP and the Standby.
392          - To Set the BOR level.
393     (#) Once all needed option bytes to be programmed are correctly written, call the
394         @ref HAL_FLASH_OB_Launch(void) function to launch the Option Bytes programming process.
395     (#) Call the @ref HAL_FLASH_OB_Lock() to disable the Flash option control register access (recommended
396         to protect the option Bytes against possible unwanted operations).
397 
398     [..] Proprietary code Read Out Protection (PcROP):
399     (#) The PcROP sector is selected by using the same option bytes as the Write
400         protection (nWRPi bits). As a result, these 2 options are exclusive each other.
401     (#) In order to activate the PcROP (change the function of the nWRPi option bits),
402         the SPRMOD option bit must be activated.
403     (#) The active value of nWRPi bits is inverted when PCROP mode is active, this
404         means: if SPRMOD = 1 and nWRPi = 1 (default value), then the user sector "i"
405         is read/write protected.
406     (#) To activate PCROP mode for Flash sector(s), you need to call the following function:
407         (++) @ref HAL_FLASHEx_AdvOBProgram in selecting sectors to be read/write protected
408         (++) @ref HAL_FLASHEx_OB_SelectPCROP to enable the read/write protection
409     (#) PcROP is available only in STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices.
410 
411 @endverbatim
412   * @{
413   */
414 
415 /**
416   * @brief  Program option bytes
417   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
418   *         contains the configuration information for the programming.
419   *
420   * @retval HAL_StatusTypeDef HAL Status
421   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)422 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
423 {
424   HAL_StatusTypeDef status = HAL_ERROR;
425 
426   /* Process Locked */
427   __HAL_LOCK(&pFlash);
428 
429   /* Check the parameters */
430   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
431 
432   /*Write protection configuration*/
433   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
434   {
435     assert_param(IS_WRPSTATE(pOBInit->WRPState));
436     if (pOBInit->WRPState == OB_WRPSTATE_ENABLE)
437     {
438       /* Enable of Write protection on the selected Sector*/
439       status = FLASH_OB_WRPConfig(pOBInit, ENABLE);
440     }
441     else
442     {
443       /* Disable of Write protection on the selected Sector*/
444       status = FLASH_OB_WRPConfig(pOBInit, DISABLE);
445     }
446     if (status != HAL_OK)
447     {
448       /* Process Unlocked */
449       __HAL_UNLOCK(&pFlash);
450       return status;
451     }
452   }
453 
454   /* Read protection configuration*/
455   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
456   {
457     status = FLASH_OB_RDPConfig(pOBInit->RDPLevel);
458     if (status != HAL_OK)
459     {
460       /* Process Unlocked */
461       __HAL_UNLOCK(&pFlash);
462       return status;
463     }
464   }
465 
466   /* USER  configuration*/
467   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
468   {
469     status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_IWDG_SW,
470                                  pOBInit->USERConfig & OB_STOP_NORST,
471                                  pOBInit->USERConfig & OB_STDBY_NORST);
472     if (status != HAL_OK)
473     {
474       /* Process Unlocked */
475       __HAL_UNLOCK(&pFlash);
476       return status;
477     }
478   }
479 
480   /* BOR Level  configuration*/
481   if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
482   {
483     status = FLASH_OB_BORConfig(pOBInit->BORLevel);
484     if (status != HAL_OK)
485     {
486       /* Process Unlocked */
487       __HAL_UNLOCK(&pFlash);
488       return status;
489     }
490   }
491   /* Process Unlocked */
492   __HAL_UNLOCK(&pFlash);
493 
494   return status;
495 }
496 
497 /**
498   * @brief   Get the Option byte configuration
499   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
500   *         contains the configuration information for the programming.
501   *
502   * @retval None
503   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)504 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
505 {
506   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR;
507 
508   /*Get WRP1*/
509   pOBInit->WRPSector0To31 = (uint32_t)(FLASH->WRPR1);
510 
511 #if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
512  || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
513  || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
514  || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
515 
516   /*Get WRP2*/
517   pOBInit->WRPSector32To63 = (uint32_t)(FLASH->WRPR2);
518 
519 #endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
520 
521 #if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
522  || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)  \
523  || defined(STM32L162xE)
524 
525   /*Get WRP3*/
526   pOBInit->WRPSector64To95 = (uint32_t)(FLASH->WRPR3);
527 
528 #endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
529 
530 #if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
531  || defined(STM32L152xDX) || defined(STM32L162xDX)
532 
533   /*Get WRP4*/
534   pOBInit->WRPSector96To127 = (uint32_t)(FLASH->WRPR4);
535 
536 #endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */
537 
538   /*Get RDP Level*/
539   pOBInit->RDPLevel   = FLASH_OB_GetRDP();
540 
541   /*Get USER*/
542   pOBInit->USERConfig = FLASH_OB_GetUser();
543 
544   /*Get BOR Level*/
545   pOBInit->BORLevel   = FLASH_OB_GetBOR();
546 }
547 
548 #if defined(FLASH_OBR_SPRMOD) || defined(FLASH_OBR_nRST_BFB2)
549 
550 /**
551   * @brief  Program option bytes
552   * @note   This function can be used only for Cat2 & Cat3 devices for PCROP and Cat4 & Cat5 for BFB2.
553   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
554   *         contains the configuration information for the programming.
555   *
556   * @retval HAL_StatusTypeDef HAL Status
557   */
HAL_FLASHEx_AdvOBProgram(FLASH_AdvOBProgramInitTypeDef * pAdvOBInit)558 HAL_StatusTypeDef HAL_FLASHEx_AdvOBProgram (FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
559 {
560   HAL_StatusTypeDef status = HAL_ERROR;
561 
562   /* Check the parameters */
563   assert_param(IS_OBEX(pAdvOBInit->OptionType));
564 
565 #if defined(FLASH_OBR_SPRMOD)
566 
567   /* Program PCROP option byte*/
568   if ((pAdvOBInit->OptionType & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP)
569   {
570     /* Check the parameters */
571     assert_param(IS_PCROPSTATE(pAdvOBInit->PCROPState));
572     if (pAdvOBInit->PCROPState == OB_PCROP_STATE_ENABLE)
573     {
574       /*Enable of Write protection on the selected Sector*/
575       status = FLASH_OB_PCROPConfig(pAdvOBInit, ENABLE);
576       if (status != HAL_OK)
577       {
578         return status;
579       }
580     }
581     else
582     {
583       /* Disable of Write protection on the selected Sector*/
584       status = FLASH_OB_PCROPConfig(pAdvOBInit, DISABLE);
585       if (status != HAL_OK)
586       {
587         return status;
588       }
589     }
590   }
591 
592 #endif /* FLASH_OBR_SPRMOD */
593 
594 #if defined(FLASH_OBR_nRST_BFB2)
595 
596   /* Program BOOT config option byte */
597   if ((pAdvOBInit->OptionType & OPTIONBYTE_BOOTCONFIG) == OPTIONBYTE_BOOTCONFIG)
598   {
599     status = FLASH_OB_BootConfig(pAdvOBInit->BootConfig);
600   }
601 
602 #endif /* FLASH_OBR_nRST_BFB2 */
603 
604   return status;
605 }
606 
607 /**
608   * @brief  Get the OBEX byte configuration
609   * @note   This function can be used only for Cat2  & Cat3 devices for PCROP and Cat4 & Cat5 for BFB2.
610   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
611   *         contains the configuration information for the programming.
612   *
613   * @retval None
614   */
HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef * pAdvOBInit)615 void HAL_FLASHEx_AdvOBGetConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit)
616 {
617   pAdvOBInit->OptionType = 0U;
618 
619 #if defined(FLASH_OBR_SPRMOD)
620 
621   pAdvOBInit->OptionType |= OPTIONBYTE_PCROP;
622 
623   /*Get PCROP state */
624   pAdvOBInit->PCROPState = (FLASH->OBR & FLASH_OBR_SPRMOD) >> POSITION_VAL(FLASH_OBR_SPRMOD);
625 
626   /*Get PCROP protected sector from 0 to 31 */
627   pAdvOBInit->PCROPSector0To31 = FLASH->WRPR1;
628 
629 #if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)
630 
631   /*Get PCROP protected sector from 32 to 63 */
632   pAdvOBInit->PCROPSector32To63 = FLASH->WRPR2;
633 
634 #endif /* STM32L100xC || STM32L151xC || STM32L152xC || STM32L162xC */
635 #endif /* FLASH_OBR_SPRMOD */
636 
637 #if defined(FLASH_OBR_nRST_BFB2)
638 
639   pAdvOBInit->OptionType |= OPTIONBYTE_BOOTCONFIG;
640 
641   /* Get Boot config OB */
642   pAdvOBInit->BootConfig = (FLASH->OBR & FLASH_OBR_nRST_BFB2) >> 16U;
643 
644 #endif /* FLASH_OBR_nRST_BFB2 */
645 }
646 
647 #endif /* FLASH_OBR_SPRMOD || FLASH_OBR_nRST_BFB2 */
648 
649 #if defined(FLASH_OBR_SPRMOD)
650 
651 /**
652   * @brief  Select the Protection Mode (SPRMOD).
653   * @note   This function can be used only for STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices
654   * @note   Once SPRMOD bit is active, unprotection of a protected sector is not possible
655   * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
656   * @retval HAL status
657   */
HAL_FLASHEx_OB_SelectPCROP(void)658 HAL_StatusTypeDef HAL_FLASHEx_OB_SelectPCROP(void)
659 {
660   HAL_StatusTypeDef status = HAL_OK;
661   uint16_t tmp1 = 0U;
662   uint32_t tmp2 = 0U;
663   uint8_t optiontmp = 0U;
664   uint16_t optiontmp2 = 0U;
665 
666   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
667 
668   /* Mask RDP Byte */
669   optiontmp =  (uint8_t)(*(__IO uint8_t *)(OB_BASE));
670 
671   /* Update Option Byte */
672   optiontmp2 = (uint16_t)(OB_PCROP_SELECTED | optiontmp);
673 
674   /* calculate the option byte to write */
675   tmp1 = (uint16_t)(~(optiontmp2 ));
676   tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));
677 
678   if(status == HAL_OK)
679   {
680     /* Clean the error context */
681     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
682 
683     /* program PCRop */
684     OB->RDP = tmp2;
685 
686     /* Wait for last operation to be completed */
687     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
688   }
689 
690   /* Return the Read protection operation Status */
691   return status;
692 }
693 
694 /**
695   * @brief  Deselect the Protection Mode (SPRMOD).
696   * @note   This function can be used only for STM32L151xBA, STM32L152xBA, STM32L151xC, STM32L152xC & STM32L162xC devices
697   * @note   Once SPRMOD bit is active, unprotection of a protected sector is not possible
698   * @note   Read a protected sector will set RDERR Flag and write a protected sector will set WRPERR Flag
699   * @retval HAL status
700   */
HAL_FLASHEx_OB_DeSelectPCROP(void)701 HAL_StatusTypeDef HAL_FLASHEx_OB_DeSelectPCROP(void)
702 {
703   HAL_StatusTypeDef status = HAL_OK;
704   uint16_t tmp1 = 0U;
705   uint32_t tmp2 = 0U;
706   uint8_t optiontmp = 0U;
707   uint16_t optiontmp2 = 0U;
708 
709   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
710 
711   /* Mask RDP Byte */
712   optiontmp =  (uint8_t)(*(__IO uint8_t *)(OB_BASE));
713 
714   /* Update Option Byte */
715   optiontmp2 = (uint16_t)(OB_PCROP_DESELECTED | optiontmp);
716 
717   /* calculate the option byte to write */
718   tmp1 = (uint16_t)(~(optiontmp2 ));
719   tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)optiontmp2));
720 
721   if(status == HAL_OK)
722   {
723     /* Clean the error context */
724     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
725 
726     /* program PCRop */
727     OB->RDP = tmp2;
728 
729     /* Wait for last operation to be completed */
730     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
731   }
732 
733   /* Return the Read protection operation Status */
734   return status;
735 }
736 
737 #endif /* FLASH_OBR_SPRMOD */
738 
739 /**
740   * @}
741   */
742 
743 /** @defgroup FLASHEx_Exported_Functions_Group3 DATA EEPROM Programming functions
744  *  @brief   DATA EEPROM Programming functions
745  *
746 @verbatim
747  ===============================================================================
748                      ##### DATA EEPROM Programming functions #####
749  ===============================================================================
750 
751     [..] Any operation of erase or program should follow these steps:
752     (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function to enable the data EEPROM access
753         and Flash program erase control register access.
754     (#) Call the desired function to erase or program data.
755     (#) Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to disable the data EEPROM access
756         and Flash program erase control register access(recommended
757         to protect the DATA_EEPROM against possible unwanted operation).
758 
759 @endverbatim
760   * @{
761   */
762 
763 /**
764   * @brief  Unlocks the data memory and FLASH_PECR register access.
765   * @retval HAL_StatusTypeDef HAL Status
766   */
HAL_FLASHEx_DATAEEPROM_Unlock(void)767 HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Unlock(void)
768 {
769   if((FLASH->PECR & FLASH_PECR_PELOCK) != RESET)
770   {
771     /* Unlocking the Data memory and FLASH_PECR register access*/
772     FLASH->PEKEYR = FLASH_PEKEY1;
773     FLASH->PEKEYR = FLASH_PEKEY2;
774   }
775   else
776   {
777     return HAL_ERROR;
778   }
779   return HAL_OK;
780 }
781 
782 /**
783   * @brief  Locks the Data memory and FLASH_PECR register access.
784   * @retval HAL_StatusTypeDef HAL Status
785   */
HAL_FLASHEx_DATAEEPROM_Lock(void)786 HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Lock(void)
787 {
788   /* Set the PELOCK Bit to lock the data memory and FLASH_PECR register access */
789   SET_BIT(FLASH->PECR, FLASH_PECR_PELOCK);
790 
791   return HAL_OK;
792 }
793 
794 /**
795   * @brief  Erase a word in data memory.
796   * @param  Address specifies the address to be erased.
797   * @param  TypeErase  Indicate the way to erase at a specified address.
798   *         This parameter can be a value of @ref FLASH_Type_Program
799   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
800   *         must be called before.
801   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Lock() to the data EEPROM access
802   *         and Flash program erase control register access(recommended to protect
803   *         the DATA_EEPROM against possible unwanted operation).
804   * @retval HAL_StatusTypeDef HAL Status
805   */
HAL_FLASHEx_DATAEEPROM_Erase(uint32_t TypeErase,uint32_t Address)806 HAL_StatusTypeDef HAL_FLASHEx_DATAEEPROM_Erase(uint32_t TypeErase, uint32_t Address)
807 {
808   HAL_StatusTypeDef status = HAL_OK;
809 
810   /* Check the parameters */
811   assert_param(IS_TYPEPROGRAMDATA(TypeErase));
812   assert_param(IS_FLASH_DATA_ADDRESS(Address));
813 
814   /* Wait for last operation to be completed */
815   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
816 
817   if(status == HAL_OK)
818   {
819     /* Clean the error context */
820     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
821 
822     if(TypeErase == FLASH_TYPEERASEDATA_WORD)
823     {
824       /* Write 00000000h to valid address in the data memory */
825       *(__IO uint32_t *) Address = 0x00000000U;
826     }
827 
828     if(TypeErase == FLASH_TYPEERASEDATA_HALFWORD)
829     {
830       /* Write 0000h to valid address in the data memory */
831       *(__IO uint16_t *) Address = (uint16_t)0x0000;
832     }
833 
834     if(TypeErase == FLASH_TYPEERASEDATA_BYTE)
835     {
836       /* Write 00h to valid address in the data memory */
837       *(__IO uint8_t *) Address = (uint8_t)0x00;
838     }
839 
840     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
841   }
842 
843   /* Return the erase status */
844   return status;
845 }
846 
847 /**
848   * @brief  Program word at a specified address
849   * @note   To correctly run this function, the @ref HAL_FLASHEx_DATAEEPROM_Unlock() function
850   *         must be called before.
851   *         Call the @ref HAL_FLASHEx_DATAEEPROM_Unlock() to he data EEPROM access
852   *         and Flash program erase control register access(recommended to protect
853   *         the DATA_EEPROM against possible unwanted operation).
854   * @note   The function @ref HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram() can be called before
855   *         this function to configure the Fixed Time Programming.
856   * @param  TypeProgram  Indicate the way to program at a specified address.
857   *         This parameter can be a value of @ref FLASHEx_Type_Program_Data
858   * @param  Address  specifie the address to be programmed.
859   * @param  Data     specifie the data to be programmed
860   *
861   * @retval HAL_StatusTypeDef HAL Status
862   */
863 
HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram,uint32_t Address,uint32_t Data)864 HAL_StatusTypeDef   HAL_FLASHEx_DATAEEPROM_Program(uint32_t TypeProgram, uint32_t Address, uint32_t Data)
865 {
866   HAL_StatusTypeDef status = HAL_ERROR;
867 
868   /* Process Locked */
869   __HAL_LOCK(&pFlash);
870 
871   /* Check the parameters */
872   assert_param(IS_TYPEPROGRAMDATA(TypeProgram));
873 
874   /* Wait for last operation to be completed */
875   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
876 
877   if(status == HAL_OK)
878   {
879     /* Clean the error context */
880     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
881 
882     if(TypeProgram == FLASH_TYPEPROGRAMDATA_WORD)
883     {
884       /* Program word (32-bit) at a specified address.*/
885       status = FLASH_DATAEEPROM_ProgramWord(Address, (uint32_t) Data);
886     }
887     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_HALFWORD)
888     {
889       /* Program halfword (16-bit) at a specified address.*/
890       status = FLASH_DATAEEPROM_ProgramHalfWord(Address, (uint16_t) Data);
891     }
892     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_BYTE)
893     {
894       /* Program byte (8-bit) at a specified address.*/
895       status = FLASH_DATAEEPROM_ProgramByte(Address, (uint8_t) Data);
896     }
897     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTBYTE)
898     {
899       /*Program word (8-bit) at a specified address.*/
900       status = FLASH_DATAEEPROM_FastProgramByte(Address, (uint8_t) Data);
901     }
902     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTHALFWORD)
903     {
904       /* Program halfword (16-bit) at a specified address.*/
905       status = FLASH_DATAEEPROM_FastProgramHalfWord(Address, (uint16_t) Data);
906     }
907     else if(TypeProgram == FLASH_TYPEPROGRAMDATA_FASTWORD)
908     {
909       /* Program word (32-bit) at a specified address.*/
910       status = FLASH_DATAEEPROM_FastProgramWord(Address, (uint32_t) Data);
911     }
912     else
913     {
914       status = HAL_ERROR;
915     }
916 
917   }
918 
919   /* Process Unlocked */
920   __HAL_UNLOCK(&pFlash);
921 
922   return status;
923 }
924 
925 /**
926   * @brief  Enable DATA EEPROM fixed Time programming (2*Tprog).
927   * @retval None
928   */
HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void)929 void HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram(void)
930 {
931   SET_BIT(FLASH->PECR, FLASH_PECR_FTDW);
932 }
933 
934 /**
935   * @brief  Disables DATA EEPROM fixed Time programming (2*Tprog).
936   * @retval None
937   */
HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void)938 void HAL_FLASHEx_DATAEEPROM_DisableFixedTimeProgram(void)
939 {
940   CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
941 }
942 
943 /**
944   * @}
945   */
946 
947 /**
948   * @}
949   */
950 
951 /** @addtogroup FLASHEx_Private_Functions
952  * @{
953  */
954 
955 /*
956 ==============================================================================
957               OPTIONS BYTES
958 ==============================================================================
959 */
960 /**
961   * @brief  Enables or disables the read out protection.
962   * @note   To correctly run this function, the @ref HAL_FLASH_OB_Unlock() function
963   *         must be called before.
964   * @param  OB_RDP specifies the read protection level.
965   *   This parameter can be:
966   *     @arg @ref OB_RDP_LEVEL_0 No protection
967   *     @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
968   *     @arg @ref OB_RDP_LEVEL_2 Chip protection
969   *
970   *  !!!Warning!!! When enabling OB_RDP_LEVEL_2 it's no more possible to go back to level 1 or 0
971   *
972   * @retval HAL status
973   */
FLASH_OB_RDPConfig(uint8_t OB_RDP)974 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint8_t OB_RDP)
975 {
976   HAL_StatusTypeDef status = HAL_OK;
977   uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U;
978 
979   /* Check the parameters */
980   assert_param(IS_OB_RDP(OB_RDP));
981 
982   tmp1 = (uint32_t)(OB->RDP & FLASH_OBR_RDPRT);
983 
984   /* According to errata sheet, DocID022054 Rev 5, par2.1.5
985   Before setting Level0 in the RDP register, check that the current level is not equal to Level0.
986   If the current level is not equal to Level0, Level0 can be activated.
987   If the current level is Level0 then the RDP register must not be written again with Level0. */
988 
989   if ((tmp1 == OB_RDP_LEVEL_0) && (OB_RDP == OB_RDP_LEVEL_0))
990   {
991     /*current level is Level0 then the RDP register must not be written again with Level0. */
992     status = HAL_ERROR;
993   }
994   else
995   {
996 #if defined(FLASH_OBR_SPRMOD)
997     /* Mask SPRMOD bit */
998     tmp3 = (uint32_t)(OB->RDP & FLASH_OBR_SPRMOD);
999 #endif
1000 
1001     /* calculate the option byte to write */
1002     tmp1 = (~((uint32_t)(OB_RDP | tmp3)));
1003     tmp2 = (uint32_t)(((uint32_t)((uint32_t)(tmp1) << 16U)) | ((uint32_t)(OB_RDP | tmp3)));
1004 
1005     /* Wait for last operation to be completed */
1006     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1007 
1008     if(status == HAL_OK)
1009     {
1010       /* Clean the error context */
1011       pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1012 
1013       /* program read protection level */
1014       OB->RDP = tmp2;
1015 
1016       /* Wait for last operation to be completed */
1017       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1018     }
1019   }
1020 
1021   /* Return the Read protection operation Status */
1022   return status;
1023 }
1024 
1025 /**
1026   * @brief  Programs the FLASH brownout reset threshold level Option Byte.
1027   * @param  OB_BOR Selects the brownout reset threshold level.
1028   *   This parameter can be one of the following values:
1029   *     @arg @ref OB_BOR_OFF BOR is disabled at power down, the reset is asserted when the VDD
1030   *                      power supply reaches the PDR(Power Down Reset) threshold (1.5V)
1031   *     @arg @ref OB_BOR_LEVEL1 BOR Reset threshold levels for 1.7V - 1.8V VDD power supply
1032   *     @arg @ref OB_BOR_LEVEL2 BOR Reset threshold levels for 1.9V - 2.0V VDD power supply
1033   *     @arg @ref OB_BOR_LEVEL3 BOR Reset threshold levels for 2.3V - 2.4V VDD power supply
1034   *     @arg @ref OB_BOR_LEVEL4 BOR Reset threshold levels for 2.55V - 2.65V VDD power supply
1035   *     @arg @ref OB_BOR_LEVEL5 BOR Reset threshold levels for 2.8V - 2.9V VDD power supply
1036   * @retval HAL status
1037   */
FLASH_OB_BORConfig(uint8_t OB_BOR)1038 static HAL_StatusTypeDef FLASH_OB_BORConfig(uint8_t OB_BOR)
1039 {
1040   HAL_StatusTypeDef status = HAL_OK;
1041   uint32_t tmp = 0U, tmp1 = 0U;
1042 
1043   /* Check the parameters */
1044   assert_param(IS_OB_BOR_LEVEL(OB_BOR));
1045 
1046   /* Get the User Option byte register */
1047   tmp1 = OB->USER & ((~FLASH_OBR_BOR_LEV) >> 16U);
1048 
1049   /* Calculate the option byte to write - [0xFFU | nUSER | 0x00U | USER]*/
1050   tmp = (uint32_t)~((OB_BOR | tmp1)) << 16U;
1051   tmp |= (OB_BOR | tmp1);
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     /* Write the BOR Option Byte */
1062     OB->USER = tmp;
1063 
1064     /* Wait for last operation to be completed */
1065     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1066   }
1067 
1068   /* Return the Option Byte BOR programmation Status */
1069   return status;
1070 }
1071 
1072 /**
1073   * @brief  Returns the FLASH User Option Bytes values.
1074   * @retval The FLASH User Option Bytes.
1075   */
FLASH_OB_GetUser(void)1076 static uint8_t FLASH_OB_GetUser(void)
1077 {
1078   /* Return the User Option Byte */
1079   return (uint8_t)((FLASH->OBR & FLASH_OBR_USER) >> 16U);
1080 }
1081 
1082 /**
1083   * @brief  Returns the FLASH Read Protection level.
1084   * @retval FLASH RDP level
1085   *         This parameter can be one of the following values:
1086   *            @arg @ref OB_RDP_LEVEL_0 No protection
1087   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
1088   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
1089   */
FLASH_OB_GetRDP(void)1090 static uint8_t FLASH_OB_GetRDP(void)
1091 {
1092   return (uint8_t)(FLASH->OBR & FLASH_OBR_RDPRT);
1093 }
1094 
1095 /**
1096   * @brief  Returns the FLASH BOR level.
1097   * @retval The BOR level Option Bytes.
1098   */
FLASH_OB_GetBOR(void)1099 static uint8_t FLASH_OB_GetBOR(void)
1100 {
1101   /* Return the BOR level */
1102   return (uint8_t)((FLASH->OBR & (uint32_t)FLASH_OBR_BOR_LEV) >> 16U);
1103 }
1104 
1105 /**
1106   * @brief  Write protects the desired pages of the first 64KB of the Flash.
1107   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
1108   *         contains WRP parameters.
1109   * @param  NewState new state of the specified FLASH Pages Wtite protection.
1110   *   This parameter can be: ENABLE or DISABLE.
1111   * @retval HAL_StatusTypeDef
1112   */
FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef * pOBInit,FunctionalState NewState)1113 static HAL_StatusTypeDef FLASH_OB_WRPConfig(FLASH_OBProgramInitTypeDef *pOBInit, FunctionalState NewState)
1114 {
1115   HAL_StatusTypeDef status = HAL_OK;
1116 
1117   /* Wait for last operation to be completed */
1118   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1119 
1120   if(status == HAL_OK)
1121   {
1122     /* Clean the error context */
1123     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1124 
1125     /* WRP for sector between 0 to 31 */
1126     if (pOBInit->WRPSector0To31 != 0U)
1127     {
1128       FLASH_OB_WRPConfigWRP1OrPCROP1(pOBInit->WRPSector0To31, NewState);
1129     }
1130 
1131 #if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
1132  || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
1133  || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
1134  || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
1135 
1136     /* Pages for Cat3, Cat4 & Cat5 devices*/
1137     /* WRP for sector between 32 to 63 */
1138     if (pOBInit->WRPSector32To63 != 0U)
1139     {
1140       FLASH_OB_WRPConfigWRP2OrPCROP2(pOBInit->WRPSector32To63, NewState);
1141     }
1142 
1143 #endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
1144 
1145 #if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
1146  || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)  \
1147  || defined(STM32L162xE)
1148 
1149     /* Pages for devices with FLASH >= 256KB*/
1150     /* WRP for sector between 64 to 95 */
1151     if (pOBInit->WRPSector64To95 != 0U)
1152     {
1153       FLASH_OB_WRPConfigWRP3(pOBInit->WRPSector64To95, NewState);
1154     }
1155 
1156 #endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
1157 
1158 #if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
1159  || defined(STM32L152xDX) || defined(STM32L162xDX)
1160 
1161     /* Pages for Cat5 devices*/
1162     /* WRP for sector between 96 to 127 */
1163     if (pOBInit->WRPSector96To127 != 0U)
1164     {
1165       FLASH_OB_WRPConfigWRP4(pOBInit->WRPSector96To127, NewState);
1166     }
1167 
1168 #endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */
1169 
1170     /* Wait for last operation to be completed */
1171     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1172   }
1173 
1174   /* Return the write protection operation Status */
1175   return status;
1176 }
1177 
1178 #if defined(STM32L151xBA) || defined(STM32L152xBA) || defined(STM32L151xC) || defined(STM32L152xC) \
1179  || defined(STM32L162xC)
1180 /**
1181   * @brief  Enables the read/write protection (PCROP) of the desired
1182   *         sectors.
1183   * @note   This function can be used only for Cat2 & Cat3 devices
1184   * @param  pAdvOBInit pointer to an FLASH_AdvOBProgramInitTypeDef structure that
1185   *         contains PCROP parameters.
1186   * @param  NewState new state of the specified FLASH Pages read/Write protection.
1187   *   This parameter can be: ENABLE or DISABLE.
1188   * @retval HAL status
1189   */
FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef * pAdvOBInit,FunctionalState NewState)1190 static HAL_StatusTypeDef FLASH_OB_PCROPConfig(FLASH_AdvOBProgramInitTypeDef *pAdvOBInit, FunctionalState NewState)
1191 {
1192   HAL_StatusTypeDef status = HAL_OK;
1193   FunctionalState pcropstate = DISABLE;
1194 
1195   /* Wait for last operation to be completed */
1196   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1197 
1198   /* Invert state to use same function of WRP */
1199   if (NewState == DISABLE)
1200   {
1201     pcropstate = ENABLE;
1202   }
1203 
1204   if(status == HAL_OK)
1205   {
1206     /* Clean the error context */
1207     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1208 
1209     /* Pages for Cat2 devices*/
1210     /* PCROP for sector between 0 to 31 */
1211     if (pAdvOBInit->PCROPSector0To31 != 0U)
1212     {
1213       FLASH_OB_WRPConfigWRP1OrPCROP1(pAdvOBInit->PCROPSector0To31, pcropstate);
1214     }
1215 
1216 #if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)
1217 
1218     /* Pages for Cat3 devices*/
1219     /* WRP for sector between 32 to 63 */
1220     if (pAdvOBInit->PCROPSector32To63 != 0U)
1221     {
1222       FLASH_OB_WRPConfigWRP2OrPCROP2(pAdvOBInit->PCROPSector32To63, pcropstate);
1223     }
1224 
1225 #endif /* STM32L100xC || STM32L151xC || STM32L152xC || STM32L162xC  */
1226 
1227     /* Wait for last operation to be completed */
1228     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1229   }
1230 
1231   /* Return the write protection operation Status */
1232   return status;
1233 }
1234 #endif /* STM32L151xBA || STM32L152xBA || STM32L151xC || STM32L152xC || STM32L162xC */
1235 
1236 /**
1237   * @brief  Write protects the desired pages of the first 128KB of the Flash.
1238   * @param  WRP1OrPCROP1 specifies the address of the pages to be write protected.
1239   *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection1
1240   * @param  NewState new state of the specified FLASH Pages Write protection.
1241   *   This parameter can be: ENABLE or DISABLE.
1242   * @retval None
1243   */
FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1,FunctionalState NewState)1244 static void FLASH_OB_WRPConfigWRP1OrPCROP1(uint32_t WRP1OrPCROP1, FunctionalState NewState)
1245 {
1246   uint32_t wrp01data = 0U, wrp23data = 0U;
1247 
1248   uint32_t tmp1 = 0U, tmp2 = 0U;
1249 
1250   /* Check the parameters */
1251   assert_param(IS_OB_WRP(WRP1OrPCROP1));
1252   assert_param(IS_FUNCTIONAL_STATE(NewState));
1253 
1254   if (NewState != DISABLE)
1255   {
1256     wrp01data = (uint16_t)(((WRP1OrPCROP1 & WRP_MASK_LOW) | OB->WRP01));
1257     wrp23data = (uint16_t)((((WRP1OrPCROP1 & WRP_MASK_HIGH)>>16U | OB->WRP23)));
1258     tmp1 = (uint32_t)(~(wrp01data) << 16U)|(wrp01data);
1259     OB->WRP01 = tmp1;
1260 
1261     tmp2 = (uint32_t)(~(wrp23data) << 16U)|(wrp23data);
1262     OB->WRP23 = tmp2;
1263   }
1264   else
1265   {
1266     wrp01data = (uint16_t)(~WRP1OrPCROP1 & (WRP_MASK_LOW & OB->WRP01));
1267     wrp23data = (uint16_t)((((~WRP1OrPCROP1 & WRP_MASK_HIGH)>>16U & OB->WRP23)));
1268 
1269     tmp1 = (uint32_t)((~wrp01data) << 16U)|(wrp01data);
1270     OB->WRP01 = tmp1;
1271 
1272     tmp2 = (uint32_t)((~wrp23data) << 16U)|(wrp23data);
1273     OB->WRP23 = tmp2;
1274   }
1275 }
1276 
1277 #if defined(STM32L100xC) || defined(STM32L151xC) || defined(STM32L152xC) || defined(STM32L162xC)    \
1278  || defined(STM32L151xCA) || defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xCA) \
1279  || defined(STM32L152xD) || defined(STM32L152xDX) || defined(STM32L162xCA) || defined(STM32L162xD)  \
1280  || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE)
1281 /**
1282   * @brief  Enable Write protects the desired pages of the second 128KB of the Flash.
1283   * @note   This function can be used only for Cat3, Cat4  & Cat5 devices.
1284   * @param  WRP2OrPCROP2 specifies the address of the pages to be write protected.
1285   *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection2
1286   * @param  NewState new state of the specified FLASH Pages Wtite protection.
1287   *   This parameter can be: ENABLE or DISABLE.
1288   * @retval None
1289   */
FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2,FunctionalState NewState)1290 static void FLASH_OB_WRPConfigWRP2OrPCROP2(uint32_t WRP2OrPCROP2, FunctionalState NewState)
1291 {
1292   uint32_t wrp45data = 0U, wrp67data = 0U;
1293 
1294   uint32_t tmp1 = 0U, tmp2 = 0U;
1295 
1296   /* Check the parameters */
1297   assert_param(IS_OB_WRP(WRP2OrPCROP2));
1298   assert_param(IS_FUNCTIONAL_STATE(NewState));
1299 
1300   if (NewState != DISABLE)
1301   {
1302     wrp45data = (uint16_t)(((WRP2OrPCROP2 & WRP_MASK_LOW) | OB->WRP45));
1303     wrp67data = (uint16_t)((((WRP2OrPCROP2 & WRP_MASK_HIGH)>>16U | OB->WRP67)));
1304     tmp1 = (uint32_t)(~(wrp45data) << 16U)|(wrp45data);
1305     OB->WRP45 = tmp1;
1306 
1307     tmp2 = (uint32_t)(~(wrp67data) << 16U)|(wrp67data);
1308     OB->WRP67 = tmp2;
1309   }
1310   else
1311   {
1312     wrp45data = (uint16_t)(~WRP2OrPCROP2 & (WRP_MASK_LOW & OB->WRP45));
1313     wrp67data = (uint16_t)((((~WRP2OrPCROP2 & WRP_MASK_HIGH)>>16U & OB->WRP67)));
1314 
1315     tmp1 = (uint32_t)((~wrp45data) << 16U)|(wrp45data);
1316     OB->WRP45 = tmp1;
1317 
1318     tmp2 = (uint32_t)((~wrp67data) << 16U)|(wrp67data);
1319     OB->WRP67 = tmp2;
1320   }
1321 }
1322 #endif /* STM32L100xC || STM32L151xC || STM32L152xC || (...) || STM32L151xE || STM32L152xE || STM32L162xE */
1323 
1324 #if defined(STM32L151xD) || defined(STM32L151xDX) || defined(STM32L152xD) || defined(STM32L152xDX) \
1325  || defined(STM32L162xD) || defined(STM32L162xDX) || defined(STM32L151xE) || defined(STM32L152xE)  \
1326  || defined(STM32L162xE)
1327 /**
1328   * @brief  Enable Write protects the desired pages of the third 128KB of the Flash.
1329   * @note   This function can be used only for STM32L151xD, STM32L152xD, STM32L162xD  & Cat5 devices.
1330   * @param  WRP3 specifies the address of the pages to be write protected.
1331   *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection3
1332   * @param  NewState new state of the specified FLASH Pages Wtite protection.
1333   *   This parameter can be: ENABLE or DISABLE.
1334   * @retval None
1335   */
FLASH_OB_WRPConfigWRP3(uint32_t WRP3,FunctionalState NewState)1336 static void FLASH_OB_WRPConfigWRP3(uint32_t WRP3, FunctionalState NewState)
1337 {
1338   uint32_t wrp89data = 0U, wrp1011data = 0U;
1339 
1340   uint32_t tmp1 = 0U, tmp2 = 0U;
1341 
1342   /* Check the parameters */
1343   assert_param(IS_OB_WRP(WRP3));
1344   assert_param(IS_FUNCTIONAL_STATE(NewState));
1345 
1346   if (NewState != DISABLE)
1347   {
1348     wrp89data = (uint16_t)(((WRP3 & WRP_MASK_LOW) | OB->WRP89));
1349     wrp1011data = (uint16_t)((((WRP3 & WRP_MASK_HIGH)>>16U | OB->WRP1011)));
1350     tmp1 = (uint32_t)(~(wrp89data) << 16U)|(wrp89data);
1351     OB->WRP89 = tmp1;
1352 
1353     tmp2 = (uint32_t)(~(wrp1011data) << 16U)|(wrp1011data);
1354     OB->WRP1011 = tmp2;
1355   }
1356   else
1357   {
1358     wrp89data = (uint16_t)(~WRP3 & (WRP_MASK_LOW & OB->WRP89));
1359     wrp1011data = (uint16_t)((((~WRP3 & WRP_MASK_HIGH)>>16U & OB->WRP1011)));
1360 
1361     tmp1 = (uint32_t)((~wrp89data) << 16U)|(wrp89data);
1362     OB->WRP89 = tmp1;
1363 
1364     tmp2 = (uint32_t)((~wrp1011data) << 16U)|(wrp1011data);
1365     OB->WRP1011 = tmp2;
1366   }
1367 }
1368 #endif /* STM32L151xD || STM32L152xD || STM32L162xD || STM32L151xE || STM32L152xE || STM32L162xE */
1369 
1370 #if defined(STM32L151xE) || defined(STM32L152xE) || defined(STM32L162xE) || defined(STM32L151xDX) \
1371  || defined(STM32L152xDX) || defined(STM32L162xDX)
1372 /**
1373   * @brief  Enable Write protects the desired pages of the Fourth 128KB of the Flash.
1374   * @note   This function can be used only for Cat5 & STM32L1xxDX devices.
1375   * @param  WRP4 specifies the address of the pages to be write protected.
1376   *   This parameter can be a combination of @ref FLASHEx_Option_Bytes_Write_Protection4
1377   * @param  NewState new state of the specified FLASH Pages Wtite protection.
1378   *   This parameter can be: ENABLE or DISABLE.
1379   * @retval None
1380   */
FLASH_OB_WRPConfigWRP4(uint32_t WRP4,FunctionalState NewState)1381 static void FLASH_OB_WRPConfigWRP4(uint32_t WRP4, FunctionalState NewState)
1382 {
1383   uint32_t wrp1213data = 0U, wrp1415data = 0U;
1384 
1385   uint32_t tmp1 = 0U, tmp2 = 0U;
1386 
1387   /* Check the parameters */
1388   assert_param(IS_OB_WRP(WRP4));
1389   assert_param(IS_FUNCTIONAL_STATE(NewState));
1390 
1391   if (NewState != DISABLE)
1392   {
1393     wrp1213data = (uint16_t)(((WRP4 & WRP_MASK_LOW) | OB->WRP1213));
1394     wrp1415data = (uint16_t)((((WRP4 & WRP_MASK_HIGH)>>16U | OB->WRP1415)));
1395     tmp1 = (uint32_t)(~(wrp1213data) << 16U)|(wrp1213data);
1396     OB->WRP1213 = tmp1;
1397 
1398     tmp2 = (uint32_t)(~(wrp1415data) << 16U)|(wrp1415data);
1399     OB->WRP1415 = tmp2;
1400   }
1401   else
1402   {
1403     wrp1213data = (uint16_t)(~WRP4 & (WRP_MASK_LOW & OB->WRP1213));
1404     wrp1415data = (uint16_t)((((~WRP4 & WRP_MASK_HIGH)>>16U & OB->WRP1415)));
1405 
1406     tmp1 = (uint32_t)((~wrp1213data) << 16U)|(wrp1213data);
1407     OB->WRP1213 = tmp1;
1408 
1409     tmp2 = (uint32_t)((~wrp1415data) << 16U)|(wrp1415data);
1410     OB->WRP1415 = tmp2;
1411   }
1412 }
1413 #endif /* STM32L151xE || STM32L152xE || STM32L162xE || STM32L151xDX || ... */
1414 
1415 /**
1416   * @brief  Programs the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
1417   * @param  OB_IWDG Selects the WDG mode.
1418   *   This parameter can be one of the following values:
1419   *     @arg @ref OB_IWDG_SW Software WDG selected
1420   *     @arg @ref OB_IWDG_HW Hardware WDG selected
1421   * @param  OB_STOP Reset event when entering STOP mode.
1422   *   This parameter can be one of the following values:
1423   *     @arg @ref OB_STOP_NORST No reset generated when entering in STOP
1424   *     @arg @ref OB_STOP_RST Reset generated when entering in STOP
1425   * @param  OB_STDBY Reset event when entering Standby mode.
1426   *   This parameter can be one of the following values:
1427   *     @arg @ref OB_STDBY_NORST No reset generated when entering in STANDBY
1428   *     @arg @ref OB_STDBY_RST Reset generated when entering in STANDBY
1429   * @retval HAL status
1430   */
FLASH_OB_UserConfig(uint8_t OB_IWDG,uint8_t OB_STOP,uint8_t OB_STDBY)1431 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t OB_IWDG, uint8_t OB_STOP, uint8_t OB_STDBY)
1432 {
1433   HAL_StatusTypeDef status = HAL_OK;
1434   uint32_t tmp = 0U, tmp1 = 0U;
1435 
1436   /* Check the parameters */
1437   assert_param(IS_OB_IWDG_SOURCE(OB_IWDG));
1438   assert_param(IS_OB_STOP_SOURCE(OB_STOP));
1439   assert_param(IS_OB_STDBY_SOURCE(OB_STDBY));
1440 
1441   /* Get the User Option byte register */
1442   tmp1 = OB->USER & ((~FLASH_OBR_USER) >> 16U);
1443 
1444   /* Calculate the user option byte to write */
1445   tmp = (uint32_t)(((uint32_t)~((uint32_t)((uint32_t)(OB_IWDG) | (uint32_t)(OB_STOP) | (uint32_t)(OB_STDBY) | tmp1))) << 16U);
1446   tmp |= ((uint32_t)(OB_IWDG) | ((uint32_t)OB_STOP) | (uint32_t)(OB_STDBY) | tmp1);
1447 
1448   /* Wait for last operation to be completed */
1449   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1450 
1451   if(status == HAL_OK)
1452   {
1453     /* Clean the error context */
1454     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1455 
1456     /* Write the User Option Byte */
1457     OB->USER = tmp;
1458 
1459     /* Wait for last operation to be completed */
1460     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1461   }
1462 
1463   /* Return the Option Byte program Status */
1464   return status;
1465 }
1466 
1467 #if defined(FLASH_OBR_nRST_BFB2)
1468 /**
1469   * @brief  Configures to boot from Bank1 or Bank2.
1470   * @param  OB_BOOT select the FLASH Bank to boot from.
1471   *   This parameter can be one of the following values:
1472   *     @arg @ref OB_BOOT_BANK2 At startup, if boot pins are set in boot from user Flash
1473   *        position and this parameter is selected the device will boot from Bank2 or Bank1,
1474   *        depending on the activation of the bank. The active banks are checked in
1475   *        the following order: Bank2, followed by Bank1.
1476   *        The active bank is recognized by the value programmed at the base address
1477   *        of the respective bank (corresponding to the initial stack pointer value
1478   *        in the interrupt vector table).
1479   *     @arg @ref OB_BOOT_BANK1 At startup, if boot pins are set in boot from user Flash
1480   *        position and this parameter is selected the device will boot from Bank1(Default).
1481   *        For more information, please refer to AN2606 from www.st.com.
1482   * @retval HAL status
1483   */
FLASH_OB_BootConfig(uint8_t OB_BOOT)1484 static HAL_StatusTypeDef FLASH_OB_BootConfig(uint8_t OB_BOOT)
1485 {
1486   HAL_StatusTypeDef status = HAL_OK;
1487   uint32_t tmp = 0U, tmp1 = 0U;
1488 
1489   /* Check the parameters */
1490   assert_param(IS_OB_BOOT_BANK(OB_BOOT));
1491 
1492   /* Get the User Option byte register  and BOR Level*/
1493   tmp1 = OB->USER & ((~FLASH_OBR_nRST_BFB2) >> 16U);
1494 
1495   /* Calculate the option byte to write */
1496   tmp = (uint32_t)~(OB_BOOT | tmp1) << 16U;
1497   tmp |= (OB_BOOT | tmp1);
1498 
1499   /* Wait for last operation to be completed */
1500   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1501 
1502   if(status == HAL_OK)
1503   {
1504     /* Clean the error context */
1505     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1506 
1507     /* Write the BOOT Option Byte */
1508     OB->USER = tmp;
1509 
1510     /* Wait for last operation to be completed */
1511     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1512   }
1513 
1514   /* Return the Option Byte program Status */
1515   return status;
1516 }
1517 
1518 #endif /* FLASH_OBR_nRST_BFB2 */
1519 
1520 /*
1521 ==============================================================================
1522               DATA
1523 ==============================================================================
1524 */
1525 
1526 /**
1527   * @brief  Write a Byte at a specified address in data memory.
1528   * @param  Address specifies the address to be written.
1529   * @param  Data specifies the data to be written.
1530   * @note   This function assumes that the is data word is already erased.
1531   * @retval HAL status
1532   */
FLASH_DATAEEPROM_FastProgramByte(uint32_t Address,uint8_t Data)1533 static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramByte(uint32_t Address, uint8_t Data)
1534 {
1535   HAL_StatusTypeDef status = HAL_OK;
1536 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1537   uint32_t tmp = 0U, tmpaddr = 0U;
1538 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1539 
1540   /* Check the parameters */
1541   assert_param(IS_FLASH_DATA_ADDRESS(Address));
1542 
1543   /* Wait for last operation to be completed */
1544   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1545 
1546   if(status == HAL_OK)
1547   {
1548     /* Clear the FTDW bit */
1549     CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
1550 
1551 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1552     /* Possible only on Cat1 devices */
1553     if(Data != (uint8_t)0x00U)
1554     {
1555       /* If the previous operation is completed, proceed to write the new Data */
1556       *(__IO uint8_t *)Address = Data;
1557 
1558       /* Wait for last operation to be completed */
1559       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1560     }
1561     else
1562     {
1563       tmpaddr = Address & 0xFFFFFFFCU;
1564       tmp = * (__IO uint32_t *) tmpaddr;
1565       tmpaddr = 0xFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1566       tmp &= ~tmpaddr;
1567       status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
1568       /* Process Unlocked */
1569       __HAL_UNLOCK(&pFlash);
1570       status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
1571       /* Process Locked */
1572       __HAL_LOCK(&pFlash);
1573     }
1574 #else /*!Cat1*/
1575     /* If the previous operation is completed, proceed to write the new Data */
1576     *(__IO uint8_t *)Address = Data;
1577 
1578     /* Wait for last operation to be completed */
1579     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1580 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1581   }
1582   /* Return the Write Status */
1583   return status;
1584 }
1585 
1586 /**
1587   * @brief  Writes a half word at a specified address in data memory.
1588   * @param  Address specifies the address to be written.
1589   * @param  Data specifies the data to be written.
1590   * @note   This function assumes that the is data word is already erased.
1591   * @retval HAL status
1592   */
FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address,uint16_t Data)1593 static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramHalfWord(uint32_t Address, uint16_t Data)
1594 {
1595   HAL_StatusTypeDef status = HAL_OK;
1596 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1597   uint32_t tmp = 0U, tmpaddr = 0U;
1598 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1599 
1600   /* Check the parameters */
1601   assert_param(IS_FLASH_DATA_ADDRESS(Address));
1602 
1603   /* Wait for last operation to be completed */
1604   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1605 
1606   if(status == HAL_OK)
1607   {
1608     /* Clear the FTDW bit */
1609     CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
1610 
1611 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1612     /* Possible only on Cat1 devices */
1613     if(Data != (uint16_t)0x0000U)
1614     {
1615       /* If the previous operation is completed, proceed to write the new data */
1616       *(__IO uint16_t *)Address = Data;
1617 
1618       /* Wait for last operation to be completed */
1619       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1620     }
1621     else
1622     {
1623       /* Process Unlocked */
1624       __HAL_UNLOCK(&pFlash);
1625       if((Address & 0x3U) != 0x3U)
1626       {
1627         tmpaddr = Address & 0xFFFFFFFCU;
1628         tmp = * (__IO uint32_t *) tmpaddr;
1629         tmpaddr = 0xFFFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1630         tmp &= ~tmpaddr;
1631         status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
1632         status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
1633       }
1634       else
1635       {
1636         HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address, 0x00U);
1637         HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address + 1U, 0x00U);
1638       }
1639       /* Process Locked */
1640       __HAL_LOCK(&pFlash);
1641     }
1642 #else /* !Cat1 */
1643     /* If the previous operation is completed, proceed to write the new data */
1644     *(__IO uint16_t *)Address = Data;
1645 
1646     /* Wait for last operation to be completed */
1647     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1648 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1649   }
1650   /* Return the Write Status */
1651   return status;
1652 }
1653 
1654 /**
1655   * @brief  Programs a word at a specified address in data memory.
1656   * @param  Address specifies the address to be written.
1657   * @param  Data specifies the data to be written.
1658   * @note   This function assumes that the is data word is already erased.
1659   * @retval HAL status
1660   */
FLASH_DATAEEPROM_FastProgramWord(uint32_t Address,uint32_t Data)1661 static HAL_StatusTypeDef FLASH_DATAEEPROM_FastProgramWord(uint32_t Address, uint32_t Data)
1662 {
1663   HAL_StatusTypeDef status = HAL_OK;
1664 
1665   /* Check the parameters */
1666   assert_param(IS_FLASH_DATA_ADDRESS(Address));
1667 
1668   /* Wait for last operation to be completed */
1669   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1670 
1671   if(status == HAL_OK)
1672   {
1673     /* Clear the FTDW bit */
1674     CLEAR_BIT(FLASH->PECR, FLASH_PECR_FTDW);
1675 
1676     /* If the previous operation is completed, proceed to program the new data */
1677     *(__IO uint32_t *)Address = Data;
1678 
1679     /* Wait for last operation to be completed */
1680     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1681   }
1682   /* Return the Write Status */
1683   return status;
1684 }
1685 
1686 /**
1687   * @brief  Write a Byte at a specified address in data memory without erase.
1688   * @param  Address specifies the address to be written.
1689   * @param  Data specifies the data to be written.
1690   * @retval HAL status
1691   */
FLASH_DATAEEPROM_ProgramByte(uint32_t Address,uint8_t Data)1692 static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramByte(uint32_t Address, uint8_t Data)
1693 {
1694   HAL_StatusTypeDef status = HAL_OK;
1695 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1696   uint32_t tmp = 0U, tmpaddr = 0U;
1697 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1698 
1699   /* Check the parameters */
1700   assert_param(IS_FLASH_DATA_ADDRESS(Address));
1701 
1702   /* Wait for last operation to be completed */
1703   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1704 
1705   if(status == HAL_OK)
1706   {
1707 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1708     if(Data != (uint8_t) 0x00U)
1709     {
1710       *(__IO uint8_t *)Address = Data;
1711 
1712       /* Wait for last operation to be completed */
1713       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1714 
1715     }
1716     else
1717     {
1718       tmpaddr = Address & 0xFFFFFFFCU;
1719       tmp = * (__IO uint32_t *) tmpaddr;
1720       tmpaddr = 0xFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1721       tmp &= ~tmpaddr;
1722       status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
1723       /* Process Unlocked */
1724       __HAL_UNLOCK(&pFlash);
1725       status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
1726       /* Process Locked */
1727       __HAL_LOCK(&pFlash);
1728     }
1729 #else /* Not Cat1*/
1730     *(__IO uint8_t *)Address = Data;
1731 
1732     /* Wait for last operation to be completed */
1733     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1734 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1735   }
1736   /* Return the Write Status */
1737   return status;
1738 }
1739 
1740 /**
1741   * @brief  Writes a half word at a specified address in data memory without erase.
1742   * @param  Address specifies the address to be written.
1743   * @param  Data specifies the data to be written.
1744   * @retval HAL status
1745   */
FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address,uint16_t Data)1746 static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramHalfWord(uint32_t Address, uint16_t Data)
1747 {
1748   HAL_StatusTypeDef status = HAL_OK;
1749 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1750   uint32_t tmp = 0U, tmpaddr = 0U;
1751 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1752 
1753   /* Check the parameters */
1754   assert_param(IS_FLASH_DATA_ADDRESS(Address));
1755 
1756   /* Wait for last operation to be completed */
1757   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1758 
1759   if(status == HAL_OK)
1760   {
1761 #if defined(STM32L100xB) || defined(STM32L151xB) || defined(STM32L152xB)
1762     if(Data != (uint16_t)0x0000U)
1763     {
1764       *(__IO uint16_t *)Address = Data;
1765 
1766       /* Wait for last operation to be completed */
1767       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1768     }
1769     else
1770     {
1771       /* Process Unlocked */
1772       __HAL_UNLOCK(&pFlash);
1773       if((Address & 0x3U) != 0x3U)
1774       {
1775         tmpaddr = Address & 0xFFFFFFFCU;
1776         tmp = * (__IO uint32_t *) tmpaddr;
1777         tmpaddr = 0xFFFFU << ((uint32_t) (0x8U * (Address & 0x3U)));
1778         tmp &= ~tmpaddr;
1779         status = HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_WORD, Address & 0xFFFFFFFCU);
1780         status = HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTWORD, (Address & 0xFFFFFFFCU), tmp);
1781       }
1782       else
1783       {
1784         HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address, 0x00U);
1785         HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, Address + 1U, 0x00U);
1786       }
1787       /* Process Locked */
1788       __HAL_LOCK(&pFlash);
1789     }
1790 #else /* Not Cat1*/
1791     *(__IO uint16_t *)Address = Data;
1792 
1793     /* Wait for last operation to be completed */
1794     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1795 #endif /* STM32L100xB || STM32L151xB || STM32L152xB  */
1796   }
1797   /* Return the Write Status */
1798   return status;
1799 }
1800 
1801 /**
1802   * @brief  Programs a word at a specified address in data memory without erase.
1803   * @param  Address specifies the address to be written.
1804   * @param  Data specifies the data to be written.
1805   * @retval HAL status
1806   */
FLASH_DATAEEPROM_ProgramWord(uint32_t Address,uint32_t Data)1807 static HAL_StatusTypeDef FLASH_DATAEEPROM_ProgramWord(uint32_t Address, uint32_t Data)
1808 {
1809   HAL_StatusTypeDef status = HAL_OK;
1810 
1811   /* Check the parameters */
1812   assert_param(IS_FLASH_DATA_ADDRESS(Address));
1813 
1814   /* Wait for last operation to be completed */
1815   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1816 
1817   if(status == HAL_OK)
1818   {
1819     *(__IO uint32_t *)Address = Data;
1820 
1821     /* Wait for last operation to be completed */
1822     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1823   }
1824   /* Return the Write Status */
1825   return status;
1826 }
1827 
1828 /**
1829   * @}
1830   */
1831 
1832 /**
1833   * @}
1834   */
1835 
1836 /** @addtogroup FLASH
1837   * @{
1838   */
1839 
1840 
1841 /** @addtogroup FLASH_Private_Functions
1842  * @{
1843  */
1844 
1845 /**
1846   * @brief  Erases a specified page in program memory.
1847   * @param  PageAddress The page address in program memory to be erased.
1848   * @note   A Page is erased in the Program memory only if the address to load
1849   *         is the start address of a page (multiple of @ref FLASH_PAGE_SIZE bytes).
1850   * @retval None
1851   */
FLASH_PageErase(uint32_t PageAddress)1852 void FLASH_PageErase(uint32_t PageAddress)
1853 {
1854   /* Clean the error context */
1855   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
1856 
1857   /* Set the ERASE bit */
1858   SET_BIT(FLASH->PECR, FLASH_PECR_ERASE);
1859 
1860   /* Set PROG bit */
1861   SET_BIT(FLASH->PECR, FLASH_PECR_PROG);
1862 
1863   /* Write 00000000h to the first word of the program page to erase */
1864   *(__IO uint32_t *)(uint32_t)(PageAddress & ~(FLASH_PAGE_SIZE - 1)) = 0x00000000;
1865 }
1866 
1867 /**
1868   * @}
1869   */
1870 
1871 /**
1872   * @}
1873   */
1874 
1875 #endif /* HAL_FLASH_MODULE_ENABLED */
1876 /**
1877   * @}
1878   */
1879 
1880 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1881