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