1 /**
2   ******************************************************************************
3   * @file    stm32f2xx_hal_flash_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended FLASH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the FLASH extension peripheral:
8   *           + Extended programming operations functions
9   *
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2017 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file in
17   * the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                    ##### Flash Extension features #####
24   ==============================================================================
25 
26                       ##### How to use this driver #####
27   ==============================================================================
28   [..] This driver provides functions to configure and program the FLASH memory
29        of all STM32F2xx devices. It includes
30       (#) FLASH Memory Erase functions:
31            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
32                 HAL_FLASH_Lock() functions
33            (++) Erase function: Erase sector, erase all sectors
34            (++) There are two modes of erase :
35              (+++) Polling Mode using HAL_FLASHEx_Erase()
36              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
37 
38       (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to :
39            (++) Set/Reset the write protection
40            (++) Set the Read protection Level
41            (++) Set the BOR level
42            (++) Program the user Option Bytes
43 
44   @endverbatim
45   ******************************************************************************
46   */
47 
48 /* Includes ------------------------------------------------------------------*/
49 #include "stm32f2xx_hal.h"
50 
51 /** @addtogroup STM32F2xx_HAL_Driver
52   * @{
53   */
54 
55 /** @defgroup FLASHEx FLASHEx
56   * @brief FLASH HAL Extension module driver
57   * @{
58   */
59 
60 #ifdef HAL_FLASH_MODULE_ENABLED
61 
62 /* Private typedef -----------------------------------------------------------*/
63 /* Private define ------------------------------------------------------------*/
64 /** @addtogroup FLASHEx_Private_Constants
65   * @{
66   */
67 #define FLASH_TIMEOUT_VALUE       50000U   /* 50 s */
68 /**
69   * @}
70   */
71 
72 /* Private macro -------------------------------------------------------------*/
73 /* Private variables ---------------------------------------------------------*/
74 /** @addtogroup FLASHEx_Private_Variables
75   * @{
76   */
77 extern FLASH_ProcessTypeDef pFlash;
78 /**
79   * @}
80   */
81 
82 /* Private function prototypes -----------------------------------------------*/
83 /** @addtogroup FLASHEx_Private_Functions
84   * @{
85   */
86 /* Option bytes control */
87 static void               FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks);
88 static HAL_StatusTypeDef  FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks);
89 static HAL_StatusTypeDef  FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks);
90 static HAL_StatusTypeDef  FLASH_OB_RDP_LevelConfig(uint8_t Level);
91 static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint8_t Iwdg, uint8_t Stop, uint8_t Stdby);
92 static HAL_StatusTypeDef  FLASH_OB_BOR_LevelConfig(uint8_t Level);
93 static uint8_t            FLASH_OB_GetUser(void);
94 static uint16_t           FLASH_OB_GetWRP(void);
95 static uint8_t            FLASH_OB_GetRDP(void);
96 static uint8_t            FLASH_OB_GetBOR(void);
97 
98 extern HAL_StatusTypeDef         FLASH_WaitForLastOperation(uint32_t Timeout);
99 /**
100   * @}
101   */
102 
103 /* Exported functions --------------------------------------------------------*/
104 /** @defgroup FLASHEx_Exported_Functions FLASH Exported Functions
105   * @{
106   */
107 
108 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
109   *  @brief   Extended IO operation functions
110   *
111 @verbatim
112  ===============================================================================
113                 ##### Extended programming operation functions #####
114  ===============================================================================
115     [..]
116     This subsection provides a set of functions allowing to manage the Extension FLASH
117     programming operations.
118 
119 @endverbatim
120   * @{
121   */
122 /**
123   * @brief  Perform a mass erase or erase the specified FLASH memory sectors
124   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
125   *         contains the configuration information for the erasing.
126   *
127   * @param[out]  SectorError pointer to variable  that
128   *         contains the configuration information on faulty sector in case of error
129   *         (0xFFFFFFFF means that all the sectors have been correctly erased)
130   *
131   * @retval HAL Status
132   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * SectorError)133 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
134 {
135   HAL_StatusTypeDef status = HAL_ERROR;
136   uint32_t index = 0U;
137 
138   /* Process Locked */
139   __HAL_LOCK(&pFlash);
140 
141   /* Check the parameters */
142   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
143 
144   /* Wait for last operation to be completed */
145   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
146 
147   if(status == HAL_OK)
148   {
149     /*Initialization of SectorError variable*/
150     *SectorError = 0xFFFFFFFFU;
151 
152     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
153     {
154       /*Mass erase to be done*/
155       FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
156 
157       /* Wait for last operation to be completed */
158       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
159 
160       /* if the erase operation is completed, disable the MER Bit */
161       FLASH->CR &= (~FLASH_MER_BIT);
162     }
163     else
164     {
165       /* Check the parameters */
166       assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));
167 
168       /* Erase by sector by sector to be done*/
169       for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++)
170       {
171         FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange);
172 
173         /* Wait for last operation to be completed */
174         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
175 
176         /* If the erase operation is completed, disable the SER and SNB Bits */
177         CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB));
178 
179         if(status != HAL_OK)
180         {
181           /* In case of error, stop erase procedure and return the faulty sector*/
182           *SectorError = index;
183           break;
184         }
185       }
186     }
187     /* Flush the caches to be sure of the data consistency */
188     FLASH_FlushCaches();
189   }
190 
191   /* Process Unlocked */
192   __HAL_UNLOCK(&pFlash);
193 
194   return status;
195 }
196 
197 /**
198   * @brief  Perform a mass erase or erase the specified FLASH memory sectors  with interrupt enabled
199   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
200   *         contains the configuration information for the erasing.
201   *
202   * @retval HAL Status
203   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)204 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
205 {
206   HAL_StatusTypeDef status = HAL_OK;
207 
208   /* Check the parameters */
209   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
210 
211   /* Enable End of FLASH Operation interrupt */
212   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
213 
214   /* Enable Error source interrupt */
215   __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
216 
217   /* Clear pending flags (if any) */
218   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
219                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR);
220 
221   if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
222   {
223     /*Mass erase to be done*/
224     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
225     pFlash.Bank = pEraseInit->Banks;
226     FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
227   }
228   else
229   {
230     /* Erase by sector to be done*/
231 
232     /* Check the parameters */
233     assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));
234 
235     pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE;
236     pFlash.NbSectorsToErase = pEraseInit->NbSectors;
237     pFlash.Sector = pEraseInit->Sector;
238     pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange;
239 
240     /*Erase 1st sector and wait for IT*/
241     FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange);
242   }
243 
244   return status;
245 }
246 
247 /**
248   * @brief   Program option bytes
249   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
250   *         contains the configuration information for the programming.
251   *
252   * @retval HAL Status
253   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)254 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
255 {
256   HAL_StatusTypeDef status = HAL_ERROR;
257 
258   /* Process Locked */
259   __HAL_LOCK(&pFlash);
260 
261   /* Check the parameters */
262   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
263 
264   /*Write protection configuration*/
265   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
266   {
267     assert_param(IS_WRPSTATE(pOBInit->WRPState));
268     if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)
269     {
270       /*Enable of Write protection on the selected Sector*/
271       status = FLASH_OB_EnableWRP(pOBInit->WRPSector, pOBInit->Banks);
272     }
273     else
274     {
275       /*Disable of Write protection on the selected Sector*/
276       status = FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks);
277     }
278   }
279 
280   /*Read protection configuration*/
281   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)
282   {
283     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);
284   }
285 
286   /*USER  configuration*/
287   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)
288   {
289     status = FLASH_OB_UserConfig(pOBInit->USERConfig&OB_IWDG_SW,
290                                      pOBInit->USERConfig&OB_STOP_NO_RST,
291                                      pOBInit->USERConfig&OB_STDBY_NO_RST);
292   }
293 
294   /*BOR Level  configuration*/
295   if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
296   {
297     status = FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
298   }
299 
300   /* Process Unlocked */
301   __HAL_UNLOCK(&pFlash);
302 
303   return status;
304 }
305 
306 /**
307   * @brief   Get the Option byte configuration
308   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
309   *         contains the configuration information for the programming.
310   *
311   * @retval None
312   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)313 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
314 {
315   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER | OPTIONBYTE_BOR;
316 
317   /*Get WRP*/
318   pOBInit->WRPSector = (uint32_t)FLASH_OB_GetWRP();
319 
320   /*Get RDP Level*/
321   pOBInit->RDPLevel = (uint32_t)FLASH_OB_GetRDP();
322 
323   /*Get USER*/
324   pOBInit->USERConfig = (uint8_t)FLASH_OB_GetUser();
325 
326   /*Get BOR Level*/
327   pOBInit->BORLevel = (uint32_t)FLASH_OB_GetBOR();
328 }
329 
330 /**
331   * @}
332   */
333 
334 /**
335   * @brief  Erase the specified FLASH memory sector
336   * @param  Sector FLASH sector to erase
337   *         The value of this parameter depend on device used within the same series
338   * @param  VoltageRange The device voltage range which defines the erase parallelism.
339   *          This parameter can be one of the following values:
340   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
341   *                                  the operation will be done by byte (8-bit)
342   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
343   *                                  the operation will be done by half word (16-bit)
344   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
345   *                                  the operation will be done by word (32-bit)
346   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
347   *                                  the operation will be done by double word (64-bit)
348   *
349   * @retval None
350   */
FLASH_Erase_Sector(uint32_t Sector,uint8_t VoltageRange)351 void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)
352 {
353   uint32_t tmp_psize = 0U;
354 
355   /* Check the parameters */
356   assert_param(IS_FLASH_SECTOR(Sector));
357   assert_param(IS_VOLTAGERANGE(VoltageRange));
358 
359   if(VoltageRange == FLASH_VOLTAGE_RANGE_1)
360   {
361      tmp_psize = FLASH_PSIZE_BYTE;
362   }
363   else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)
364   {
365     tmp_psize = FLASH_PSIZE_HALF_WORD;
366   }
367   else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)
368   {
369     tmp_psize = FLASH_PSIZE_WORD;
370   }
371   else
372   {
373     tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
374   }
375 
376   /* If the previous operation is completed, proceed to erase the sector */
377   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
378   FLASH->CR |= tmp_psize;
379   CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
380   FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB));
381   FLASH->CR |= FLASH_CR_STRT;
382 }
383 
384 /**
385   * @brief  Flush the instruction and data caches
386   * @retval None
387   */
FLASH_FlushCaches(void)388 void FLASH_FlushCaches(void)
389 {
390   /* Flush instruction cache  */
391   if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != RESET)
392   {
393     /* Disable instruction cache  */
394     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
395     /* Reset instruction cache */
396     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
397     /* Enable instruction cache */
398     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
399   }
400 
401   /* Flush data cache */
402   if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
403   {
404     /* Disable data cache  */
405     __HAL_FLASH_DATA_CACHE_DISABLE();
406     /* Reset data cache */
407     __HAL_FLASH_DATA_CACHE_RESET();
408     /* Enable data cache */
409     __HAL_FLASH_DATA_CACHE_ENABLE();
410   }
411 }
412 
413 /**
414   * @brief  Mass erase of FLASH memory
415   * @param  VoltageRange The device voltage range which defines the erase parallelism.
416   *          This parameter can be one of the following values:
417   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V,
418   *                                  the operation will be done by byte (8-bit)
419   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,
420   *                                  the operation will be done by half word (16-bit)
421   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,
422   *                                  the operation will be done by word (32-bit)
423   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp,
424   *                                  the operation will be done by double word (64-bit)
425   *
426   * @param  Banks Banks to be erased
427   *          This parameter can be one of the following values:
428   *            @arg FLASH_BANK_1: Bank1 to be erased
429   *
430   * @retval None
431   */
FLASH_MassErase(uint8_t VoltageRange,uint32_t Banks)432 static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks)
433 {
434   /* Prevent unused argument(s) compilation warning */
435   UNUSED(Banks);
436 
437   /* Check the parameters */
438   assert_param(IS_VOLTAGERANGE(VoltageRange));
439   assert_param(IS_FLASH_BANK(Banks));
440 
441   /* If the previous operation is completed, proceed to erase all sectors */
442   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
443   FLASH->CR |= FLASH_CR_MER;
444   FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange <<8U);
445 }
446 
447 /**
448   * @brief  Enable the write protection of the desired bank 1 sectors
449   *
450   * @note   When the memory read protection level is selected (RDP level = 1),
451   *         it is not possible to program or erase the flash sector i if CortexM3
452   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
453   *
454   * @param  WRPSector specifies the sector(s) to be write protected.
455   *         The value of this parameter depend on device used within the same series
456   *
457   * @param  Banks Enable write protection on all the sectors for the specific bank
458   *          This parameter can be one of the following values:
459   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
460   *
461   * @retval HAL Status
462   */
FLASH_OB_EnableWRP(uint32_t WRPSector,uint32_t Banks)463 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
464 {
465   HAL_StatusTypeDef status = HAL_OK;
466 
467   /* Prevent unused argument(s) compilation warning */
468   UNUSED(Banks);
469 
470   /* Check the parameters */
471   assert_param(IS_OB_WRP_SECTOR(WRPSector));
472   assert_param(IS_FLASH_BANK(Banks));
473 
474   /* Wait for last operation to be completed */
475   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
476 
477   if(status == HAL_OK)
478   {
479     *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS &= (~WRPSector);
480   }
481 
482   return status;
483 }
484 
485 /**
486   * @brief  Disable the write protection of the desired bank 1 sectors
487   *
488   * @note   When the memory read protection level is selected (RDP level = 1),
489   *         it is not possible to program or erase the flash sector if CortexM3
490   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1
491   *
492   * @param  WRPSector specifies the sector(s) to be write protected.
493   *         The value of this parameter depend on device used within the same series
494   *
495   * @param  Banks Enable write protection on all the sectors for the specific bank
496   *          This parameter can be one of the following values:
497   *            @arg FLASH_BANK_1: WRP on all sectors of bank1
498   *
499   * @retval HAL Status
500   */
FLASH_OB_DisableWRP(uint32_t WRPSector,uint32_t Banks)501 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
502 {
503   HAL_StatusTypeDef status = HAL_OK;
504 
505   /* Prevent unused argument(s) compilation warning */
506   UNUSED(Banks);
507 
508   /* Check the parameters */
509   assert_param(IS_OB_WRP_SECTOR(WRPSector));
510   assert_param(IS_FLASH_BANK(Banks));
511 
512   /* Wait for last operation to be completed */
513   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
514 
515   if(status == HAL_OK)
516   {
517     *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector;
518   }
519 
520   return status;
521 }
522 
523 /**
524   * @brief  Set the read protection level.
525   * @param  Level specifies the read protection level.
526   *          This parameter can be one of the following values:
527   *            @arg OB_RDP_LEVEL_0: No protection
528   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
529   *            @arg OB_RDP_LEVEL_2: Full chip protection
530   *
531   * @note WARNING: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
532   *
533   * @retval HAL Status
534   */
FLASH_OB_RDP_LevelConfig(uint8_t Level)535 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level)
536 {
537   HAL_StatusTypeDef status = HAL_OK;
538 
539   /* Check the parameters */
540   assert_param(IS_OB_RDP_LEVEL(Level));
541 
542   /* Wait for last operation to be completed */
543   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
544 
545   if(status == HAL_OK)
546   {
547     *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = Level;
548   }
549 
550   return status;
551 }
552 
553 /**
554   * @brief  Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.
555   * @param  Iwdg Selects the IWDG mode
556   *          This parameter can be one of the following values:
557   *            @arg OB_IWDG_SW: Software IWDG selected
558   *            @arg OB_IWDG_HW: Hardware IWDG selected
559   * @param  Stop Reset event when entering STOP mode.
560   *          This parameter  can be one of the following values:
561   *            @arg OB_STOP_NO_RST: No reset generated when entering in STOP
562   *            @arg OB_STOP_RST: Reset generated when entering in STOP
563   * @param  Stdby Reset event when entering Standby mode.
564   *          This parameter  can be one of the following values:
565   *            @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY
566   *            @arg OB_STDBY_RST: Reset generated when entering in STANDBY
567   * @retval HAL Status
568   */
FLASH_OB_UserConfig(uint8_t Iwdg,uint8_t Stop,uint8_t Stdby)569 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint8_t Iwdg, uint8_t Stop, uint8_t Stdby)
570 {
571   uint8_t optiontmp = 0xFF;
572   HAL_StatusTypeDef status = HAL_OK;
573 
574   /* Check the parameters */
575   assert_param(IS_OB_IWDG_SOURCE(Iwdg));
576   assert_param(IS_OB_STOP_SOURCE(Stop));
577   assert_param(IS_OB_STDBY_SOURCE(Stdby));
578 
579   /* Wait for last operation to be completed */
580   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
581 
582   if(status == HAL_OK)
583   {
584     /* Mask OPTLOCK, OPTSTRT, BOR_LEV and BFB2 bits */
585     optiontmp =  (uint8_t)((*(__IO uint8_t *)OPTCR_BYTE0_ADDRESS) & (uint8_t)0x1F);
586 
587     /* Update User Option Byte */
588     *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS = Iwdg | (uint8_t)(Stdby | (uint8_t)(Stop | ((uint8_t)optiontmp)));
589   }
590 
591   return status;
592 }
593 
594 /**
595   * @brief  Set the BOR Level.
596   * @param  Level specifies the Option Bytes BOR Reset Level.
597   *          This parameter can be one of the following values:
598   *            @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
599   *            @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
600   *            @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
601   *            @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V
602   * @retval HAL Status
603   */
FLASH_OB_BOR_LevelConfig(uint8_t Level)604 static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level)
605 {
606   /* Check the parameters */
607   assert_param(IS_OB_BOR_LEVEL(Level));
608 
609   /* Set the BOR Level */
610   *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS &= (~FLASH_OPTCR_BOR_LEV);
611   *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= Level;
612 
613   return HAL_OK;
614 
615 }
616 
617 /**
618   * @brief  Return the FLASH User Option Byte value.
619   * @retval uint8_t FLASH User Option Bytes values: IWDG_SW(Bit0), RST_STOP(Bit1)
620   *         and RST_STDBY(Bit2).
621   */
FLASH_OB_GetUser(void)622 static uint8_t FLASH_OB_GetUser(void)
623 {
624   /* Return the User Option Byte */
625   return ((uint8_t)(FLASH->OPTCR & 0xE0));
626 }
627 
628 /**
629   * @brief  Return the FLASH Write Protection Option Bytes value.
630   * @retval uint16_t FLASH Write Protection Option Bytes value
631   */
FLASH_OB_GetWRP(void)632 static uint16_t FLASH_OB_GetWRP(void)
633 {
634   /* Return the FLASH write protection Register value */
635   return (*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS));
636 }
637 
638 /**
639   * @brief  Returns the FLASH Read Protection level.
640   * @retval FLASH ReadOut Protection Status:
641   *         This parameter can be one of the following values:
642   *            @arg OB_RDP_LEVEL_0: No protection
643   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
644   *            @arg OB_RDP_LEVEL_2: Full chip protection
645   */
FLASH_OB_GetRDP(void)646 static uint8_t FLASH_OB_GetRDP(void)
647 {
648   uint8_t readstatus = OB_RDP_LEVEL_0;
649 
650   if((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) == (uint8_t)OB_RDP_LEVEL_2))
651   {
652     readstatus = OB_RDP_LEVEL_2;
653   }
654   else if((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS) == (uint8_t)OB_RDP_LEVEL_0))
655   {
656     readstatus = OB_RDP_LEVEL_0;
657   }
658   else
659   {
660     readstatus = OB_RDP_LEVEL_1;
661   }
662 
663   return readstatus;
664 }
665 
666 /**
667   * @brief  Returns the FLASH BOR level.
668   * @retval uint8_t The FLASH BOR level:
669   *           - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V
670   *           - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V
671   *           - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V
672   *           - OB_BOR_OFF   : Supply voltage ranges from 1.62 to 2.1 V
673   */
FLASH_OB_GetBOR(void)674 static uint8_t FLASH_OB_GetBOR(void)
675 {
676   /* Return the FLASH BOR level */
677   return (uint8_t)(*(__IO uint8_t *)(OPTCR_BYTE0_ADDRESS) & (uint8_t)0x0C);
678 }
679 
680 /**
681   * @}
682   */
683 
684 #endif /* HAL_FLASH_MODULE_ENABLED */
685 
686 /**
687   * @}
688   */
689 
690 /**
691   * @}
692   */
693 
694