]> git.leonardobizzoni.com Git - pioneer-stm32/blob
33314d4a1207c283d14b26d91f1d005daa3fe7d1
[pioneer-stm32] /
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f7xx_hal_flash_ex.c\r
4   * @author  MCD Application Team\r
5   * @brief   Extended FLASH HAL module driver.\r
6   *          This file provides firmware functions to manage the following \r
7   *          functionalities of the FLASH extension peripheral:\r
8   *           + Extended programming operations functions\r
9   *  \r
10   @verbatim\r
11   ==============================================================================\r
12                    ##### Flash Extension features #####\r
13   ==============================================================================\r
14            \r
15   [..] Comparing to other previous devices, the FLASH interface for STM32F76xx/STM32F77xx \r
16        devices contains the following additional features \r
17        \r
18        (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write\r
19            capability (RWW)\r
20        (+) Dual bank memory organization       \r
21        (+) Dual boot mode\r
22    \r
23                       ##### How to use this driver #####\r
24   ==============================================================================\r
25   [..] This driver provides functions to configure and program the FLASH memory \r
26        of all STM32F7xx devices. It includes\r
27       (#) FLASH Memory Erase functions: \r
28            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and \r
29                 HAL_FLASH_Lock() functions\r
30            (++) Erase function: Erase sector, erase all sectors\r
31            (++) There are two modes of erase :\r
32              (+++) Polling Mode using HAL_FLASHEx_Erase()\r
33              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()\r
34              \r
35       (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to :\r
36            (++) Set/Reset the write protection\r
37            (++) Set the Read protection Level\r
38            (++) Set the BOR level\r
39            (++) Program the user Option Bytes\r
40   \r
41   @endverbatim\r
42   ******************************************************************************\r
43   * @attention\r
44   *\r
45   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.\r
46   * All rights reserved.</center></h2>\r
47   *\r
48   * This software component is licensed by ST under BSD 3-Clause license,\r
49   * the "License"; You may not use this file except in compliance with the\r
50   * License. You may obtain a copy of the License at:\r
51   *                        opensource.org/licenses/BSD-3-Clause\r
52   *\r
53   ******************************************************************************\r
54   */ \r
55 \r
56 /* Includes ------------------------------------------------------------------*/\r
57 #include "stm32f7xx_hal.h"\r
58 \r
59 /** @addtogroup STM32F7xx_HAL_Driver\r
60   * @{\r
61   */\r
62 \r
63 /** @defgroup FLASHEx FLASHEx\r
64   * @brief FLASH HAL Extension module driver\r
65   * @{\r
66   */\r
67 \r
68 #ifdef HAL_FLASH_MODULE_ENABLED\r
69 \r
70 /* Private typedef -----------------------------------------------------------*/\r
71 /* Private define ------------------------------------------------------------*/\r
72 /** @addtogroup FLASHEx_Private_Constants\r
73   * @{\r
74   */    \r
75 #define SECTOR_MASK               0xFFFFFF07U\r
76 #define FLASH_TIMEOUT_VALUE       50000U/* 50 s */\r
77 /**\r
78   * @}\r
79   */\r
80     \r
81 /* Private macro -------------------------------------------------------------*/\r
82 /* Private variables ---------------------------------------------------------*/\r
83 /** @addtogroup FLASHEx_Private_Variables\r
84   * @{\r
85   */    \r
86 extern FLASH_ProcessTypeDef pFlash;\r
87 /**\r
88   * @}\r
89   */\r
90 \r
91 /* Private function prototypes -----------------------------------------------*/\r
92 /** @addtogroup FLASHEx_Private_Functions\r
93   * @{\r
94   */\r
95 /* Option bytes control */\r
96 static HAL_StatusTypeDef  FLASH_OB_EnableWRP(uint32_t WRPSector);\r
97 static HAL_StatusTypeDef  FLASH_OB_DisableWRP(uint32_t WRPSector);\r
98 static HAL_StatusTypeDef  FLASH_OB_RDP_LevelConfig(uint8_t Level);\r
99 static HAL_StatusTypeDef  FLASH_OB_BOR_LevelConfig(uint8_t Level);\r
100 static HAL_StatusTypeDef  FLASH_OB_BootAddressConfig(uint32_t BootOption, uint32_t Address);\r
101 static uint32_t           FLASH_OB_GetUser(void);\r
102 static uint32_t           FLASH_OB_GetWRP(void);\r
103 static uint8_t            FLASH_OB_GetRDP(void);\r
104 static uint32_t           FLASH_OB_GetBOR(void);\r
105 static uint32_t           FLASH_OB_GetBootAddress(uint32_t BootOption);\r
106 \r
107 #if defined (FLASH_OPTCR_nDBANK)\r
108 static void               FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks);\r
109 static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, \\r
110                                               uint32_t Iwdgstdby, uint32_t NDBank, uint32_t NDBoot);\r
111 #else\r
112 static void               FLASH_MassErase(uint8_t VoltageRange);\r
113 static HAL_StatusTypeDef  FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, uint32_t Iwdgstdby);\r
114 #endif /* FLASH_OPTCR_nDBANK */\r
115 \r
116 #if defined (FLASH_OPTCR2_PCROP)\r
117 static HAL_StatusTypeDef  FLASH_OB_PCROP_Config(uint32_t PCROPSector);\r
118 static HAL_StatusTypeDef  FLASH_OB_PCROP_RDP_Config(uint32_t Pcrop_Rdp);\r
119 static uint32_t           FLASH_OB_GetPCROP(void);\r
120 static uint32_t           FLASH_OB_GetPCROPRDP(void);\r
121 #endif /* FLASH_OPTCR2_PCROP */\r
122 \r
123 extern HAL_StatusTypeDef  FLASH_WaitForLastOperation(uint32_t Timeout);\r
124 /**\r
125   * @}\r
126   */\r
127 \r
128 /* Exported functions --------------------------------------------------------*/\r
129 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions\r
130   * @{\r
131   */\r
132 \r
133 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions\r
134  *  @brief   Extended IO operation functions \r
135  *\r
136 @verbatim   \r
137  ===============================================================================\r
138                 ##### Extended programming operation functions #####\r
139  ===============================================================================  \r
140     [..]\r
141     This subsection provides a set of functions allowing to manage the Extension FLASH \r
142     programming operations Operations.\r
143 \r
144 @endverbatim\r
145   * @{\r
146   */\r
147 /**\r
148   * @brief  Perform a mass erase or erase the specified FLASH memory sectors \r
149   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that\r
150   *         contains the configuration information for the erasing.\r
151   * \r
152   * @param[out]  SectorError pointer to variable  that\r
153   *         contains the configuration information on faulty sector in case of error \r
154   *         (0xFFFFFFFF means that all the sectors have been correctly erased)\r
155   * \r
156   * @retval HAL Status\r
157   */\r
158 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)\r
159 {\r
160   HAL_StatusTypeDef status = HAL_ERROR;\r
161   uint32_t index = 0;\r
162   \r
163   /* Process Locked */\r
164   __HAL_LOCK(&pFlash);\r
165 \r
166   /* Check the parameters */\r
167   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
168 \r
169   /* Wait for last operation to be completed */\r
170   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
171 \r
172   if(status == HAL_OK)\r
173   {\r
174     /*Initialization of SectorError variable*/\r
175     *SectorError = 0xFFFFFFFFU;\r
176     \r
177     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)\r
178     {\r
179       /*Mass erase to be done*/\r
180 #if defined (FLASH_OPTCR_nDBANK)      \r
181       FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);\r
182 #else\r
183       FLASH_MassErase((uint8_t) pEraseInit->VoltageRange);      \r
184 #endif /* FLASH_OPTCR_nDBANK */\r
185                       \r
186       /* Wait for last operation to be completed */\r
187       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
188       \r
189       /* if the erase operation is completed, disable the MER Bit */\r
190       FLASH->CR &= (~FLASH_MER_BIT);\r
191     }\r
192     else\r
193     {\r
194       /* Check the parameters */\r
195       assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));\r
196 \r
197       /* Erase by sector by sector to be done*/\r
198       for(index = pEraseInit->Sector; index < (pEraseInit->NbSectors + pEraseInit->Sector); index++)\r
199       {\r
200         FLASH_Erase_Sector(index, (uint8_t) pEraseInit->VoltageRange);\r
201 \r
202         /* Wait for last operation to be completed */\r
203         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
204         \r
205         /* If the erase operation is completed, disable the SER Bit and SNB Bits */\r
206         CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB)); \r
207 \r
208         if(status != HAL_OK) \r
209         {\r
210           /* In case of error, stop erase procedure and return the faulty sector*/\r
211           *SectorError = index;\r
212           break;\r
213         }\r
214       }\r
215     }\r
216   }\r
217 \r
218   /* Process Unlocked */\r
219   __HAL_UNLOCK(&pFlash);\r
220 \r
221   return status;\r
222 }\r
223 \r
224 /**\r
225   * @brief  Perform a mass erase or erase the specified FLASH memory sectors  with interrupt enabled\r
226   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that\r
227   *         contains the configuration information for the erasing.\r
228   * \r
229   * @retval HAL Status\r
230   */\r
231 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)\r
232 {\r
233   HAL_StatusTypeDef status = HAL_OK;\r
234 \r
235   /* Process Locked */\r
236   __HAL_LOCK(&pFlash);\r
237 \r
238   /* Check the parameters */\r
239   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
240 \r
241   /* Enable End of FLASH Operation interrupt */\r
242   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);\r
243   \r
244   /* Enable Error source interrupt */\r
245   __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);\r
246   \r
247   /* Clear pending flags (if any) */  \r
248   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\\r
249                          FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_ERSERR);  \r
250   \r
251   if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)\r
252   {\r
253     /*Mass erase to be done*/\r
254     pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;\r
255 #if defined (FLASH_OPTCR_nDBANK)    \r
256     FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);\r
257 #else\r
258     FLASH_MassErase((uint8_t) pEraseInit->VoltageRange);      \r
259 #endif /* FLASH_OPTCR_nDBANK */    \r
260   }\r
261   else\r
262   {\r
263     /* Erase by sector to be done*/\r
264 \r
265     /* Check the parameters */\r
266     assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));\r
267 \r
268     pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE;\r
269     pFlash.NbSectorsToErase = pEraseInit->NbSectors;\r
270     pFlash.Sector = pEraseInit->Sector;\r
271     pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange;\r
272 \r
273     /*Erase 1st sector and wait for IT*/\r
274     FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange);\r
275   }\r
276 \r
277   return status;\r
278 }\r
279 \r
280 /**\r
281   * @brief  Program option bytes\r
282   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that\r
283   *         contains the configuration information for the programming.\r
284   * \r
285   * @retval HAL Status\r
286   */\r
287 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)\r
288 {\r
289   HAL_StatusTypeDef status = HAL_ERROR;\r
290   \r
291   /* Process Locked */\r
292   __HAL_LOCK(&pFlash);\r
293 \r
294   /* Check the parameters */\r
295   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));\r
296 \r
297   /* Write protection configuration */\r
298   if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)\r
299   {\r
300     assert_param(IS_WRPSTATE(pOBInit->WRPState));\r
301     if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)\r
302     {\r
303       /*Enable of Write protection on the selected Sector*/\r
304       status = FLASH_OB_EnableWRP(pOBInit->WRPSector);\r
305     }\r
306     else\r
307     {\r
308       /*Disable of Write protection on the selected Sector*/\r
309       status = FLASH_OB_DisableWRP(pOBInit->WRPSector);\r
310     }\r
311   }\r
312 \r
313   /* Read protection configuration */\r
314   if((pOBInit->OptionType & OPTIONBYTE_RDP) == OPTIONBYTE_RDP)\r
315   {\r
316     status = FLASH_OB_RDP_LevelConfig(pOBInit->RDPLevel);\r
317   }\r
318 \r
319   /* USER  configuration */\r
320   if((pOBInit->OptionType & OPTIONBYTE_USER) == OPTIONBYTE_USER)\r
321   {\r
322 #if defined (FLASH_OPTCR_nDBANK)\r
323     status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_WWDG_SW, \r
324                                  pOBInit->USERConfig & OB_IWDG_SW,\r
325                                  pOBInit->USERConfig & OB_STOP_NO_RST,\r
326                                  pOBInit->USERConfig & OB_STDBY_NO_RST, \r
327                                  pOBInit->USERConfig & OB_IWDG_STOP_ACTIVE,\r
328                                  pOBInit->USERConfig & OB_IWDG_STDBY_ACTIVE,\r
329                                  pOBInit->USERConfig & OB_NDBANK_SINGLE_BANK,\r
330                                  pOBInit->USERConfig & OB_DUAL_BOOT_DISABLE);\r
331 #else\r
332     status = FLASH_OB_UserConfig(pOBInit->USERConfig & OB_WWDG_SW, \r
333                                  pOBInit->USERConfig & OB_IWDG_SW,\r
334                                  pOBInit->USERConfig & OB_STOP_NO_RST,\r
335                                  pOBInit->USERConfig & OB_STDBY_NO_RST, \r
336                                  pOBInit->USERConfig & OB_IWDG_STOP_ACTIVE,\r
337                                  pOBInit->USERConfig & OB_IWDG_STDBY_ACTIVE);    \r
338 #endif /* FLASH_OPTCR_nDBANK */\r
339   }\r
340   \r
341   /* BOR Level  configuration */\r
342   if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)\r
343   {\r
344     status = FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);\r
345   }\r
346   \r
347   /* Boot 0 Address configuration */\r
348   if((pOBInit->OptionType & OPTIONBYTE_BOOTADDR_0) == OPTIONBYTE_BOOTADDR_0)\r
349   {\r
350     status = FLASH_OB_BootAddressConfig(OPTIONBYTE_BOOTADDR_0, pOBInit->BootAddr0);\r
351   }\r
352   \r
353   /* Boot 1 Address configuration */\r
354   if((pOBInit->OptionType & OPTIONBYTE_BOOTADDR_1) == OPTIONBYTE_BOOTADDR_1)\r
355   {\r
356     status = FLASH_OB_BootAddressConfig(OPTIONBYTE_BOOTADDR_1, pOBInit->BootAddr1);\r
357   }\r
358   \r
359 #if defined (FLASH_OPTCR2_PCROP)\r
360   /* PCROP configuration */\r
361   if((pOBInit->OptionType & OPTIONBYTE_PCROP) == OPTIONBYTE_PCROP)\r
362   {\r
363     status = FLASH_OB_PCROP_Config(pOBInit->PCROPSector);\r
364   }\r
365   \r
366   /* PCROP_RDP configuration */\r
367   if((pOBInit->OptionType & OPTIONBYTE_PCROP_RDP) == OPTIONBYTE_PCROP_RDP)\r
368   {\r
369     status = FLASH_OB_PCROP_RDP_Config(pOBInit->PCROPRdp);\r
370   }\r
371 #endif /* FLASH_OPTCR2_PCROP */\r
372 \r
373   /* Process Unlocked */\r
374   __HAL_UNLOCK(&pFlash);\r
375 \r
376   return status;\r
377 }\r
378 \r
379 /**\r
380   * @brief  Get the Option byte configuration\r
381   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that\r
382   *         contains the configuration information for the programming.\r
383   * \r
384   * @retval None\r
385   */\r
386 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)\r
387 {\r
388   pOBInit->OptionType = OPTIONBYTE_WRP | OPTIONBYTE_RDP | OPTIONBYTE_USER |\\r
389                         OPTIONBYTE_BOR | OPTIONBYTE_BOOTADDR_0 | OPTIONBYTE_BOOTADDR_1;\r
390 \r
391   /*Get WRP*/\r
392   pOBInit->WRPSector = FLASH_OB_GetWRP();\r
393 \r
394   /*Get RDP Level*/\r
395   pOBInit->RDPLevel = FLASH_OB_GetRDP();\r
396 \r
397   /*Get USER*/\r
398   pOBInit->USERConfig = FLASH_OB_GetUser();\r
399 \r
400   /*Get BOR Level*/\r
401   pOBInit->BORLevel = FLASH_OB_GetBOR();\r
402   \r
403   /*Get Boot Address when Boot pin = 0 */\r
404   pOBInit->BootAddr0 = FLASH_OB_GetBootAddress(OPTIONBYTE_BOOTADDR_0);\r
405   \r
406   /*Get Boot Address when Boot pin = 1 */\r
407   pOBInit->BootAddr1 = FLASH_OB_GetBootAddress(OPTIONBYTE_BOOTADDR_1);\r
408 \r
409 #if defined (FLASH_OPTCR2_PCROP)\r
410   /*Get PCROP Sectors */\r
411   pOBInit->PCROPSector = FLASH_OB_GetPCROP();\r
412   \r
413   /*Get PCROP_RDP Value */\r
414   pOBInit->PCROPRdp = FLASH_OB_GetPCROPRDP();\r
415 #endif /* FLASH_OPTCR2_PCROP */\r
416 }\r
417 /**\r
418   * @}\r
419   */\r
420 \r
421 #if defined (FLASH_OPTCR_nDBANK)\r
422 /**\r
423   * @brief  Full erase of FLASH memory sectors \r
424   * @param  VoltageRange The device voltage range which defines the erase parallelism.  \r
425   *          This parameter can be one of the following values:\r
426   *            @arg VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, \r
427   *                                  the operation will be done by byte (8-bit) \r
428   *            @arg VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,\r
429   *                                  the operation will be done by half word (16-bit)\r
430   *            @arg VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,\r
431   *                                  the operation will be done by word (32-bit)\r
432   *            @arg VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, \r
433   *                                  the operation will be done by double word (64-bit)\r
434   * @param  Banks Banks to be erased\r
435   *          This parameter can be one of the following values:\r
436   *            @arg FLASH_BANK_1: Bank1 to be erased\r
437   *            @arg FLASH_BANK_2: Bank2 to be erased\r
438   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased\r
439   *\r
440   * @retval HAL Status\r
441   */\r
442 static void FLASH_MassErase(uint8_t VoltageRange, uint32_t Banks)\r
443 {\r
444   /* Check the parameters */\r
445   assert_param(IS_VOLTAGERANGE(VoltageRange));\r
446   assert_param(IS_FLASH_BANK(Banks));\r
447 \r
448   /* if the previous operation is completed, proceed to erase all sectors */\r
449   FLASH->CR &= CR_PSIZE_MASK;\r
450   if(Banks == FLASH_BANK_BOTH)\r
451   {\r
452     /* bank1 & bank2 will be erased*/\r
453     FLASH->CR |= FLASH_MER_BIT;\r
454   }\r
455   else if(Banks == FLASH_BANK_2)\r
456   {\r
457     /*Only bank2 will be erased*/\r
458     FLASH->CR |= FLASH_CR_MER2;\r
459   }\r
460   else\r
461   {\r
462     /*Only bank1 will be erased*/\r
463     FLASH->CR |= FLASH_CR_MER1;    \r
464   }\r
465   FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange <<8);\r
466   /* Data synchronous Barrier (DSB) Just after the write operation\r
467      This will force the CPU to respect the sequence of instruction (no optimization).*/\r
468   __DSB();\r
469 }\r
470 \r
471 /**\r
472   * @brief  Erase the specified FLASH memory sector\r
473   * @param  Sector FLASH sector to erase\r
474   *         The value of this parameter depend on device used within the same series      \r
475   * @param  VoltageRange The device voltage range which defines the erase parallelism.  \r
476   *          This parameter can be one of the following values:\r
477   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, \r
478   *                                  the operation will be done by byte (8-bit) \r
479   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,\r
480   *                                  the operation will be done by half word (16-bit)\r
481   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,\r
482   *                                  the operation will be done by word (32-bit)\r
483   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, \r
484   *                                  the operation will be done by double word (64-bit)\r
485   * \r
486   * @retval None\r
487   */\r
488 void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)\r
489 {\r
490   uint32_t tmp_psize = 0;\r
491 \r
492   /* Check the parameters */\r
493   assert_param(IS_FLASH_SECTOR(Sector));\r
494   assert_param(IS_VOLTAGERANGE(VoltageRange));\r
495   \r
496   if(VoltageRange == FLASH_VOLTAGE_RANGE_1)\r
497   {\r
498      tmp_psize = FLASH_PSIZE_BYTE;\r
499   }\r
500   else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)\r
501   {\r
502     tmp_psize = FLASH_PSIZE_HALF_WORD;\r
503   }\r
504   else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)\r
505   {\r
506     tmp_psize = FLASH_PSIZE_WORD;\r
507   }\r
508   else\r
509   {\r
510     tmp_psize = FLASH_PSIZE_DOUBLE_WORD;\r
511   }\r
512   \r
513   /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */\r
514   if(Sector > FLASH_SECTOR_11) \r
515   {\r
516     Sector += 4;\r
517   }  \r
518 \r
519   /* If the previous operation is completed, proceed to erase the sector */\r
520   FLASH->CR &= CR_PSIZE_MASK;\r
521   FLASH->CR |= tmp_psize;\r
522   CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);\r
523   FLASH->CR |= FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos);\r
524   FLASH->CR |= FLASH_CR_STRT;\r
525   \r
526   /* Data synchronous Barrier (DSB) Just after the write operation\r
527      This will force the CPU to respect the sequence of instruction (no optimization).*/\r
528   __DSB();\r
529 }\r
530 \r
531 /**\r
532   * @brief  Return the FLASH Write Protection Option Bytes value.\r
533   * @retval uint32_t FLASH Write Protection Option Bytes value\r
534   */\r
535 static uint32_t FLASH_OB_GetWRP(void)\r
536 {\r
537   /* Return the FLASH write protection Register value */\r
538   return ((uint32_t)(FLASH->OPTCR & 0x0FFF0000));\r
539 }\r
540 \r
541 /**\r
542   * @brief  Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.    \r
543   * @param  Wwdg Selects the IWDG mode\r
544   *          This parameter can be one of the following values:\r
545   *            @arg OB_WWDG_SW: Software WWDG selected\r
546   *            @arg OB_WWDG_HW: Hardware WWDG selected\r
547   * @param  Iwdg Selects the WWDG mode\r
548   *          This parameter can be one of the following values:\r
549   *            @arg OB_IWDG_SW: Software IWDG selected\r
550   *            @arg OB_IWDG_HW: Hardware IWDG selected\r
551   * @param  Stop Reset event when entering STOP mode.\r
552   *          This parameter  can be one of the following values:\r
553   *            @arg OB_STOP_NO_RST: No reset generated when entering in STOP\r
554   *            @arg OB_STOP_RST: Reset generated when entering in STOP\r
555   * @param  Stdby Reset event when entering Standby mode.\r
556   *          This parameter  can be one of the following values:\r
557   *            @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY\r
558   *            @arg OB_STDBY_RST: Reset generated when entering in STANDBY\r
559   * @param  Iwdgstop Independent watchdog counter freeze in Stop mode.\r
560   *          This parameter  can be one of the following values:\r
561   *            @arg OB_IWDG_STOP_FREEZE: Freeze IWDG counter in STOP\r
562   *            @arg OB_IWDG_STOP_ACTIVE: IWDG counter active in STOP\r
563   * @param  Iwdgstdby Independent watchdog counter freeze in standby mode.\r
564   *          This parameter  can be one of the following values:\r
565   *            @arg OB_IWDG_STDBY_FREEZE: Freeze IWDG counter in STANDBY\r
566   *            @arg OB_IWDG_STDBY_ACTIVE: IWDG counter active in STANDBY\r
567   * @param  NDBank Flash Single Bank mode enabled.\r
568   *          This parameter  can be one of the following values:\r
569   *            @arg OB_NDBANK_SINGLE_BANK: enable 256 bits mode (Flash is a single bank)\r
570   *            @arg OB_NDBANK_DUAL_BANK: disable 256 bits mode (Flash is a dual bank in 128 bits mode)  \r
571   * @param  NDBoot Flash Dual boot mode disable.\r
572   *          This parameter  can be one of the following values:\r
573   *            @arg OB_DUAL_BOOT_DISABLE: Disable Dual Boot\r
574   *            @arg OB_DUAL_BOOT_ENABLE: Enable Dual Boot\r
575 \r
576   * @retval HAL Status\r
577   */\r
578 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, \\r
579                                              uint32_t Iwdgstdby, uint32_t NDBank, uint32_t NDBoot)\r
580 {\r
581   uint32_t useroptionmask = 0x00;\r
582   uint32_t useroptionvalue = 0x00;\r
583 \r
584   HAL_StatusTypeDef status = HAL_OK;\r
585 \r
586   /* Check the parameters */\r
587   assert_param(IS_OB_WWDG_SOURCE(Wwdg));\r
588   assert_param(IS_OB_IWDG_SOURCE(Iwdg));\r
589   assert_param(IS_OB_STOP_SOURCE(Stop));\r
590   assert_param(IS_OB_STDBY_SOURCE(Stdby));\r
591   assert_param(IS_OB_IWDG_STOP_FREEZE(Iwdgstop));\r
592   assert_param(IS_OB_IWDG_STDBY_FREEZE(Iwdgstdby));\r
593   assert_param(IS_OB_NDBANK(NDBank));\r
594   assert_param(IS_OB_NDBOOT(NDBoot));\r
595   \r
596   /* Wait for last operation to be completed */\r
597   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
598   \r
599   if(status == HAL_OK)\r
600   {\r
601     useroptionmask = (FLASH_OPTCR_WWDG_SW | FLASH_OPTCR_IWDG_SW | FLASH_OPTCR_nRST_STOP | \\r
602                       FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_IWDG_STOP | FLASH_OPTCR_IWDG_STDBY | \\r
603                       FLASH_OPTCR_nDBOOT | FLASH_OPTCR_nDBANK);\r
604                       \r
605     useroptionvalue = (Iwdg | Wwdg | Stop | Stdby | Iwdgstop | Iwdgstdby | NDBoot | NDBank);\r
606         \r
607     /* Update User Option Byte */               \r
608     MODIFY_REG(FLASH->OPTCR, useroptionmask, useroptionvalue);\r
609   }\r
610   \r
611   return status; \r
612 }\r
613 \r
614 /**\r
615   * @brief  Return the FLASH User Option Byte value.\r
616   * @retval uint32_t FLASH User Option Bytes values: WWDG_SW(Bit4), IWDG_SW(Bit5), nRST_STOP(Bit6), \r
617   *         nRST_STDBY(Bit7), nDBOOT(Bit28), nDBANK(Bit29), IWDG_STDBY(Bit30) and IWDG_STOP(Bit31).\r
618   */\r
619 static uint32_t FLASH_OB_GetUser(void)\r
620 {\r
621   /* Return the User Option Byte */\r
622   return ((uint32_t)(FLASH->OPTCR & 0xF00000F0U));\r
623 }\r
624 #else\r
625 \r
626 /**\r
627   * @brief  Full erase of FLASH memory sectors \r
628   * @param  VoltageRange The device voltage range which defines the erase parallelism.  \r
629   *          This parameter can be one of the following values:\r
630   *            @arg VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, \r
631   *                                  the operation will be done by byte (8-bit) \r
632   *            @arg VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,\r
633   *                                  the operation will be done by half word (16-bit)\r
634   *            @arg VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,\r
635   *                                  the operation will be done by word (32-bit)\r
636   *            @arg VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, \r
637   *                                  the operation will be done by double word (64-bit)\r
638   *\r
639   * @retval HAL Status\r
640   */\r
641 static void FLASH_MassErase(uint8_t VoltageRange)\r
642 {\r
643   /* Check the parameters */\r
644   assert_param(IS_VOLTAGERANGE(VoltageRange));\r
645 \r
646   /* if the previous operation is completed, proceed to erase all sectors */\r
647   FLASH->CR &= CR_PSIZE_MASK;\r
648   FLASH->CR |= FLASH_CR_MER;\r
649   FLASH->CR |= FLASH_CR_STRT | ((uint32_t)VoltageRange <<8);\r
650   /* Data synchronous Barrier (DSB) Just after the write operation\r
651      This will force the CPU to respect the sequence of instruction (no optimization).*/\r
652   __DSB();\r
653 }\r
654 \r
655 /**\r
656   * @brief  Erase the specified FLASH memory sector\r
657   * @param  Sector FLASH sector to erase\r
658   *         The value of this parameter depend on device used within the same series      \r
659   * @param  VoltageRange The device voltage range which defines the erase parallelism.  \r
660   *          This parameter can be one of the following values:\r
661   *            @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, \r
662   *                                  the operation will be done by byte (8-bit) \r
663   *            @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V,\r
664   *                                  the operation will be done by half word (16-bit)\r
665   *            @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V,\r
666   *                                  the operation will be done by word (32-bit)\r
667   *            @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, \r
668   *                                  the operation will be done by double word (64-bit)\r
669   * \r
670   * @retval None\r
671   */\r
672 void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange)\r
673 {\r
674   uint32_t tmp_psize = 0;\r
675 \r
676   /* Check the parameters */\r
677   assert_param(IS_FLASH_SECTOR(Sector));\r
678   assert_param(IS_VOLTAGERANGE(VoltageRange));\r
679   \r
680   if(VoltageRange == FLASH_VOLTAGE_RANGE_1)\r
681   {\r
682      tmp_psize = FLASH_PSIZE_BYTE;\r
683   }\r
684   else if(VoltageRange == FLASH_VOLTAGE_RANGE_2)\r
685   {\r
686     tmp_psize = FLASH_PSIZE_HALF_WORD;\r
687   }\r
688   else if(VoltageRange == FLASH_VOLTAGE_RANGE_3)\r
689   {\r
690     tmp_psize = FLASH_PSIZE_WORD;\r
691   }\r
692   else\r
693   {\r
694     tmp_psize = FLASH_PSIZE_DOUBLE_WORD;\r
695   }\r
696 \r
697   /* If the previous operation is completed, proceed to erase the sector */\r
698   FLASH->CR &= CR_PSIZE_MASK;\r
699   FLASH->CR |= tmp_psize;\r
700   FLASH->CR &= SECTOR_MASK;\r
701   FLASH->CR |= FLASH_CR_SER | (Sector << FLASH_CR_SNB_Pos);\r
702   FLASH->CR |= FLASH_CR_STRT;\r
703   \r
704   /* Data synchronous Barrier (DSB) Just after the write operation\r
705      This will force the CPU to respect the sequence of instruction (no optimization).*/\r
706   __DSB();\r
707 }\r
708 \r
709 /**\r
710   * @brief  Return the FLASH Write Protection Option Bytes value.\r
711   * @retval uint32_t FLASH Write Protection Option Bytes value\r
712   */\r
713 static uint32_t FLASH_OB_GetWRP(void)\r
714 {\r
715   /* Return the FLASH write protection Register value */\r
716   return ((uint32_t)(FLASH->OPTCR & 0x00FF0000));\r
717 }\r
718 \r
719 /**\r
720   * @brief  Program the FLASH User Option Byte: IWDG_SW / RST_STOP / RST_STDBY.    \r
721   * @param  Wwdg Selects the IWDG mode\r
722   *          This parameter can be one of the following values:\r
723   *            @arg OB_WWDG_SW: Software WWDG selected\r
724   *            @arg OB_WWDG_HW: Hardware WWDG selected\r
725   * @param  Iwdg Selects the WWDG mode\r
726   *          This parameter can be one of the following values:\r
727   *            @arg OB_IWDG_SW: Software IWDG selected\r
728   *            @arg OB_IWDG_HW: Hardware IWDG selected\r
729   * @param  Stop Reset event when entering STOP mode.\r
730   *          This parameter  can be one of the following values:\r
731   *            @arg OB_STOP_NO_RST: No reset generated when entering in STOP\r
732   *            @arg OB_STOP_RST: Reset generated when entering in STOP\r
733   * @param  Stdby Reset event when entering Standby mode.\r
734   *          This parameter  can be one of the following values:\r
735   *            @arg OB_STDBY_NO_RST: No reset generated when entering in STANDBY\r
736   *            @arg OB_STDBY_RST: Reset generated when entering in STANDBY\r
737   * @param  Iwdgstop Independent watchdog counter freeze in Stop mode.\r
738   *          This parameter  can be one of the following values:\r
739   *            @arg OB_IWDG_STOP_FREEZE: Freeze IWDG counter in STOP\r
740   *            @arg OB_IWDG_STOP_ACTIVE: IWDG counter active in STOP\r
741   * @param  Iwdgstdby Independent watchdog counter freeze in standby mode.\r
742   *          This parameter  can be one of the following values:\r
743   *            @arg OB_IWDG_STDBY_FREEZE: Freeze IWDG counter in STANDBY\r
744   *            @arg OB_IWDG_STDBY_ACTIVE: IWDG counter active in STANDBY           \r
745   * @retval HAL Status\r
746   */\r
747 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t Wwdg, uint32_t Iwdg, uint32_t Stop, uint32_t Stdby, uint32_t Iwdgstop, uint32_t Iwdgstdby)\r
748 {\r
749   uint32_t useroptionmask = 0x00;\r
750   uint32_t useroptionvalue = 0x00;\r
751 \r
752   HAL_StatusTypeDef status = HAL_OK;\r
753 \r
754   /* Check the parameters */\r
755   assert_param(IS_OB_WWDG_SOURCE(Wwdg));\r
756   assert_param(IS_OB_IWDG_SOURCE(Iwdg));\r
757   assert_param(IS_OB_STOP_SOURCE(Stop));\r
758   assert_param(IS_OB_STDBY_SOURCE(Stdby));\r
759   assert_param(IS_OB_IWDG_STOP_FREEZE(Iwdgstop));\r
760   assert_param(IS_OB_IWDG_STDBY_FREEZE(Iwdgstdby));\r
761 \r
762   /* Wait for last operation to be completed */\r
763   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
764   \r
765   if(status == HAL_OK)\r
766   {\r
767     useroptionmask = (FLASH_OPTCR_WWDG_SW | FLASH_OPTCR_IWDG_SW | FLASH_OPTCR_nRST_STOP | \\r
768                       FLASH_OPTCR_nRST_STDBY | FLASH_OPTCR_IWDG_STOP | FLASH_OPTCR_IWDG_STDBY);\r
769                       \r
770     useroptionvalue = (Iwdg | Wwdg | Stop | Stdby | Iwdgstop | Iwdgstdby);\r
771         \r
772     /* Update User Option Byte */               \r
773     MODIFY_REG(FLASH->OPTCR, useroptionmask, useroptionvalue);\r
774   }\r
775   \r
776   return status; \r
777 \r
778 }\r
779 \r
780 /**\r
781   * @brief  Return the FLASH User Option Byte value.\r
782   * @retval uint32_t FLASH User Option Bytes values: WWDG_SW(Bit4), IWDG_SW(Bit5), nRST_STOP(Bit6), \r
783   *         nRST_STDBY(Bit7), IWDG_STDBY(Bit30) and IWDG_STOP(Bit31).\r
784   */\r
785 static uint32_t FLASH_OB_GetUser(void)\r
786 {\r
787   /* Return the User Option Byte */\r
788   return ((uint32_t)(FLASH->OPTCR & 0xC00000F0U));\r
789 }\r
790 #endif /* FLASH_OPTCR_nDBANK */\r
791 \r
792 /**\r
793   * @brief  Enable the write protection of the desired bank1 or bank2 sectors\r
794   *\r
795   * @note   When the memory read protection level is selected (RDP level = 1), \r
796   *         it is not possible to program or erase the flash sector i if CortexM7  \r
797   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1    \r
798   * \r
799   * @param  WRPSector specifies the sector(s) to be write protected.\r
800   *          This parameter can be one of the following values:\r
801   *            @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_7 (for STM32F74xxx/STM32F75xxx devices)\r
802   *              or a value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_11 (in Single Bank mode for STM32F76xxx/STM32F77xxx devices)\r
803   *              or a value between OB_WRP_DB_SECTOR_0 and OB_WRP_DB_SECTOR_23 (in Dual Bank mode for STM32F76xxx/STM32F77xxx devices)\r
804   *            @arg OB_WRP_SECTOR_All\r
805   *\r
806   * @retval HAL FLASH State   \r
807   */\r
808 static HAL_StatusTypeDef FLASH_OB_EnableWRP(uint32_t WRPSector)\r
809 {\r
810   HAL_StatusTypeDef status = HAL_OK;\r
811   \r
812   /* Check the parameters */\r
813   assert_param(IS_OB_WRP_SECTOR(WRPSector));\r
814     \r
815   /* Wait for last operation to be completed */\r
816   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
817 \r
818   if(status == HAL_OK)\r
819   {\r
820     /*Write protection enabled on sectors */\r
821     FLASH->OPTCR &= (~WRPSector);  \r
822   }\r
823   \r
824   return status;\r
825 }\r
826 \r
827 /**\r
828   * @brief  Disable the write protection of the desired bank1 or bank 2 sectors\r
829   *\r
830   * @note   When the memory read protection level is selected (RDP level = 1), \r
831   *         it is not possible to program or erase the flash sector i if CortexM4  \r
832   *         debug features are connected or boot code is executed in RAM, even if nWRPi = 1  \r
833   * \r
834   * @param  WRPSector specifies the sector(s) to be write protected.\r
835   *          This parameter can be one of the following values:\r
836   *            @arg WRPSector: A value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_7 (for STM32F74xxx/STM32F75xxx devices)\r
837   *              or a value between OB_WRP_SECTOR_0 and OB_WRP_SECTOR_11 (in Single Bank mode for STM32F76xxx/STM32F77xxx devices)\r
838   *              or a value between OB_WRP_DB_SECTOR_0 and OB_WRP_DB_SECTOR_23 (in Dual Bank mode for STM32F76xxx/STM32F77xxx devices)                      \r
839   *            @arg OB_WRP_Sector_All\r
840   *\r
841   *\r
842   * @retval HAL Status   \r
843   */\r
844 static HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector)\r
845 {\r
846   HAL_StatusTypeDef status = HAL_OK;\r
847   \r
848   /* Check the parameters */\r
849   assert_param(IS_OB_WRP_SECTOR(WRPSector));\r
850     \r
851   /* Wait for last operation to be completed */\r
852   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
853 \r
854   if(status == HAL_OK)\r
855   {\r
856     /* Write protection disabled on sectors */\r
857     FLASH->OPTCR |= (WRPSector); \r
858   }\r
859 \r
860   return status;\r
861 }\r
862 \r
863 /**\r
864   * @brief  Set the read protection level.\r
865   * @param  Level specifies the read protection level.\r
866   *          This parameter can be one of the following values:\r
867   *            @arg OB_RDP_LEVEL_0: No protection\r
868   *            @arg OB_RDP_LEVEL_1: Read protection of the memory\r
869   *            @arg OB_RDP_LEVEL_2: Full chip protection\r
870   *   \r
871   * @note WARNING: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0\r
872   *    \r
873   * @retval HAL Status\r
874   */\r
875 static HAL_StatusTypeDef FLASH_OB_RDP_LevelConfig(uint8_t Level)\r
876 {\r
877   HAL_StatusTypeDef status = HAL_OK;\r
878   \r
879   /* Check the parameters */\r
880   assert_param(IS_OB_RDP_LEVEL(Level));\r
881     \r
882   /* Wait for last operation to be completed */\r
883   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
884 \r
885   if(status == HAL_OK)\r
886   { \r
887     *(__IO uint8_t*)OPTCR_BYTE1_ADDRESS = Level;\r
888   }\r
889   \r
890   return status;\r
891 }\r
892 \r
893 /**\r
894   * @brief  Set the BOR Level. \r
895   * @param  Level specifies the Option Bytes BOR Reset Level.\r
896   *          This parameter can be one of the following values:\r
897   *            @arg OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V\r
898   *            @arg OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V\r
899   *            @arg OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V\r
900   *            @arg OB_BOR_OFF: Supply voltage ranges from 1.62 to 2.1 V\r
901   * @retval HAL Status\r
902   */\r
903 static HAL_StatusTypeDef FLASH_OB_BOR_LevelConfig(uint8_t Level)\r
904 {\r
905   /* Check the parameters */\r
906   assert_param(IS_OB_BOR_LEVEL(Level));\r
907 \r
908   /* Set the BOR Level */\r
909   MODIFY_REG(FLASH->OPTCR, FLASH_OPTCR_BOR_LEV, Level);\r
910   \r
911   return HAL_OK;\r
912   \r
913 }\r
914 \r
915 /**\r
916   * @brief  Configure Boot base address.\r
917   * \r
918   * @param   BootOption  specifies Boot base address depending from Boot pin = 0 or pin = 1\r
919   *          This parameter can be one of the following values:\r
920   *            @arg OPTIONBYTE_BOOTADDR_0 : Boot address based when Boot pin = 0                 \r
921   *            @arg OPTIONBYTE_BOOTADDR_1 : Boot address based when Boot pin = 1  \r
922   * @param   Address specifies Boot base address\r
923   *          This parameter can be one of the following values:\r
924   *            @arg OB_BOOTADDR_ITCM_RAM : Boot from ITCM RAM (0x00000000)                 \r
925   *            @arg OB_BOOTADDR_SYSTEM : Boot from System memory bootloader (0x00100000) \r
926   *            @arg OB_BOOTADDR_ITCM_FLASH : Boot from Flash on ITCM interface (0x00200000)  \r
927   *            @arg OB_BOOTADDR_AXIM_FLASH : Boot from Flash on AXIM interface (0x08000000)  \r
928   *            @arg OB_BOOTADDR_DTCM_RAM : Boot from DTCM RAM (0x20000000)                 \r
929   *            @arg OB_BOOTADDR_SRAM1 : Boot from SRAM1 (0x20010000)                    \r
930   *            @arg OB_BOOTADDR_SRAM2 : Boot from SRAM2 (0x2004C000)              \r
931   *    \r
932   * @retval HAL Status\r
933   */\r
934 static HAL_StatusTypeDef FLASH_OB_BootAddressConfig(uint32_t BootOption, uint32_t Address)\r
935 {\r
936   HAL_StatusTypeDef status = HAL_OK;\r
937   \r
938   /* Check the parameters */\r
939   assert_param(IS_OB_BOOT_ADDRESS(Address));\r
940     \r
941   /* Wait for last operation to be completed */\r
942   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
943   \r
944   if(status == HAL_OK)\r
945   {\r
946     if(BootOption == OPTIONBYTE_BOOTADDR_0)\r
947     {                   \r
948       MODIFY_REG(FLASH->OPTCR1, FLASH_OPTCR1_BOOT_ADD0, Address);\r
949     }\r
950     else\r
951     {\r
952       MODIFY_REG(FLASH->OPTCR1, FLASH_OPTCR1_BOOT_ADD1, (Address << 16));\r
953     }\r
954   }\r
955   \r
956   return status;\r
957 }\r
958 \r
959 /**\r
960   * @brief  Returns the FLASH Read Protection level.\r
961   * @retval FlagStatus FLASH ReadOut Protection Status:\r
962   *         This parameter can be one of the following values:\r
963   *            @arg OB_RDP_LEVEL_0: No protection\r
964   *            @arg OB_RDP_LEVEL_1: Read protection of the memory\r
965   *            @arg OB_RDP_LEVEL_2: Full chip protection\r
966   */\r
967 static uint8_t FLASH_OB_GetRDP(void)\r
968 {\r
969   uint8_t readstatus = OB_RDP_LEVEL_0;\r
970   \r
971   if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS)) == OB_RDP_LEVEL_0)\r
972   {\r
973     readstatus = OB_RDP_LEVEL_0;\r
974   }\r
975   else if ((*(__IO uint8_t*)(OPTCR_BYTE1_ADDRESS)) == OB_RDP_LEVEL_2)\r
976   {\r
977     readstatus = OB_RDP_LEVEL_2;\r
978   }\r
979   else \r
980   {\r
981     readstatus = OB_RDP_LEVEL_1;\r
982   }\r
983 \r
984   return readstatus;\r
985 }\r
986 \r
987 /**\r
988   * @brief  Returns the FLASH BOR level.\r
989   * @retval uint32_t The FLASH BOR level:\r
990   *           - OB_BOR_LEVEL3: Supply voltage ranges from 2.7 to 3.6 V\r
991   *           - OB_BOR_LEVEL2: Supply voltage ranges from 2.4 to 2.7 V\r
992   *           - OB_BOR_LEVEL1: Supply voltage ranges from 2.1 to 2.4 V\r
993   *           - OB_BOR_OFF   : Supply voltage ranges from 1.62 to 2.1 V  \r
994   */\r
995 static uint32_t FLASH_OB_GetBOR(void)\r
996 {\r
997   /* Return the FLASH BOR level */\r
998   return ((uint32_t)(FLASH->OPTCR & 0x0C));\r
999 }\r
1000 \r
1001 /**\r
1002   * @brief  Configure Boot base address.\r
1003   * \r
1004   * @param   BootOption  specifies Boot base address depending from Boot pin = 0 or pin = 1\r
1005   *          This parameter can be one of the following values:\r
1006   *            @arg OPTIONBYTE_BOOTADDR_0 : Boot address based when Boot pin = 0                 \r
1007   *            @arg OPTIONBYTE_BOOTADDR_1 : Boot address based when Boot pin = 1       \r
1008   *    \r
1009   * @retval uint32_t Boot Base Address:\r
1010   *            - OB_BOOTADDR_ITCM_RAM : Boot from ITCM RAM (0x00000000)                 \r
1011   *            - OB_BOOTADDR_SYSTEM : Boot from System memory bootloader (0x00100000) \r
1012   *            - OB_BOOTADDR_ITCM_FLASH : Boot from Flash on ITCM interface (0x00200000)  \r
1013   *            - OB_BOOTADDR_AXIM_FLASH : Boot from Flash on AXIM interface (0x08000000)  \r
1014   *            - OB_BOOTADDR_DTCM_RAM : Boot from DTCM RAM (0x20000000)                 \r
1015   *            - OB_BOOTADDR_SRAM1 : Boot from SRAM1 (0x20010000)                    \r
1016   *            - OB_BOOTADDR_SRAM2 : Boot from SRAM2 (0x2004C000) \r
1017   */\r
1018 static uint32_t FLASH_OB_GetBootAddress(uint32_t BootOption)\r
1019 {  \r
1020   uint32_t Address = 0;\r
1021     \r
1022         /* Return the Boot base Address */\r
1023   if(BootOption == OPTIONBYTE_BOOTADDR_0)\r
1024   {                     \r
1025     Address = FLASH->OPTCR1 & FLASH_OPTCR1_BOOT_ADD0;\r
1026         }\r
1027   else\r
1028         {\r
1029                 Address = ((FLASH->OPTCR1 & FLASH_OPTCR1_BOOT_ADD1) >> 16);\r
1030         }\r
1031 \r
1032   return Address;\r
1033 }\r
1034 \r
1035 #if defined (FLASH_OPTCR2_PCROP)\r
1036 /**\r
1037   * @brief  Set the PCROP protection for sectors.\r
1038   * @param  PCROPSector specifies the sector(s) to be PCROP protected.\r
1039   *         This parameter can be one of the following values:\r
1040   *            @arg OB_PCROP_SECTOR_x: A value between OB_PCROP_SECTOR_0 and OB_PCROP_SECTOR_7\r
1041   *            @arg OB_PCROP_SECTOR_ALL\r
1042   *    \r
1043   * @retval HAL Status\r
1044   */\r
1045 static HAL_StatusTypeDef FLASH_OB_PCROP_Config(uint32_t PCROPSector)\r
1046 {\r
1047   HAL_StatusTypeDef status = HAL_OK;\r
1048   \r
1049   /* Check the parameters */\r
1050   assert_param(IS_OB_PCROP_SECTOR(PCROPSector));\r
1051     \r
1052   /* Wait for last operation to be completed */\r
1053   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
1054 \r
1055   if(status == HAL_OK)\r
1056   { \r
1057     MODIFY_REG(FLASH->OPTCR2, FLASH_OPTCR2_PCROP, PCROPSector);\r
1058   }\r
1059   \r
1060   return status;\r
1061 }\r
1062 \r
1063 /**\r
1064   * @brief  Set the PCROP_RDP value\r
1065   * @param  Pcrop_Rdp specifies the PCROP_RDP bit value.\r
1066   *    \r
1067   * @retval HAL Status\r
1068   */\r
1069 static HAL_StatusTypeDef FLASH_OB_PCROP_RDP_Config(uint32_t Pcrop_Rdp)\r
1070 {\r
1071   HAL_StatusTypeDef status = HAL_OK;\r
1072   \r
1073   /* Check the parameters */\r
1074   assert_param(IS_OB_PCROP_RDP_VALUE(Pcrop_Rdp));\r
1075     \r
1076   /* Wait for last operation to be completed */\r
1077   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
1078 \r
1079   if(status == HAL_OK)\r
1080   { \r
1081     MODIFY_REG(FLASH->OPTCR2, FLASH_OPTCR2_PCROP_RDP, Pcrop_Rdp);\r
1082   }\r
1083   \r
1084   return status;\r
1085 }\r
1086 \r
1087 /**\r
1088   * @brief  Return the FLASH PCROP Protection Option Bytes value.\r
1089   * @retval uint32_t FLASH PCROP Protection Option Bytes value\r
1090   */\r
1091 static uint32_t FLASH_OB_GetPCROP(void)\r
1092 {\r
1093   /* Return the FLASH write protection Register value */\r
1094   return ((uint32_t)(FLASH->OPTCR2 & FLASH_OPTCR2_PCROP));\r
1095 }\r
1096 \r
1097 /**\r
1098   * @brief  Return the FLASH PCROP_RDP option byte value.\r
1099   * @retval uint32_t FLASH PCROP_RDP option byte value\r
1100   */\r
1101 static uint32_t FLASH_OB_GetPCROPRDP(void)\r
1102 {\r
1103   /* Return the FLASH write protection Register value */\r
1104   return ((uint32_t)(FLASH->OPTCR2 & FLASH_OPTCR2_PCROP_RDP));\r
1105 }\r
1106 #endif /* FLASH_OPTCR2_PCROP */\r
1107 \r
1108 /**\r
1109   * @}\r
1110   */\r
1111   \r
1112 #endif /* HAL_FLASH_MODULE_ENABLED */\r
1113 \r
1114 /**\r
1115   * @}\r
1116   */\r
1117 \r
1118 /**\r
1119   * @}\r
1120   */\r
1121 \r
1122 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r