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