]> git.sur5r.net Git - freertos/blob
5a30708b57fba7eb847204c1f46ba3213266be72
[freertos] /
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32l4xx_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 extended peripheral:\r
8   *           + Extended programming operations functions\r
9   *\r
10  @verbatim\r
11  ==============================================================================\r
12                    ##### Flash Extended features #####\r
13   ==============================================================================\r
14 \r
15   [..] Comparing to other previous devices, the FLASH interface for STM32L4xx\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        (+) PCROP protection for all banks\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 STM32L4xx 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 page, 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 function: Use HAL_FLASHEx_OBProgram() to :\r
36         (++) Set/Reset the write protection\r
37         (++) Set the Read protection Level\r
38         (++) Program the user Option Bytes\r
39         (++) Configure the PCROP protection\r
40 \r
41       (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :\r
42         (++) Get the value of a write protection area\r
43         (++) Know if the read protection is activated\r
44         (++) Get the value of the user Option Bytes\r
45         (++) Get the value of a PCROP area\r
46 \r
47  @endverbatim\r
48   ******************************************************************************\r
49   * @attention\r
50   *\r
51   * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.\r
52   * All rights reserved.</center></h2>\r
53   *\r
54   * This software component is licensed by ST under BSD 3-Clause license,\r
55   * the "License"; You may not use this file except in compliance with the\r
56   * License. You may obtain a copy of the License at:\r
57   *                       opensource.org/licenses/BSD-3-Clause\r
58   *\r
59   ******************************************************************************\r
60   */\r
61 \r
62 /* Includes ------------------------------------------------------------------*/\r
63 #include "stm32l4xx_hal.h"\r
64 \r
65 /** @addtogroup STM32L4xx_HAL_Driver\r
66   * @{\r
67   */\r
68 \r
69 /** @defgroup FLASHEx FLASHEx\r
70   * @brief FLASH Extended HAL module driver\r
71   * @{\r
72   */\r
73 \r
74 #ifdef HAL_FLASH_MODULE_ENABLED\r
75 \r
76 /* Private typedef -----------------------------------------------------------*/\r
77 /* Private define ------------------------------------------------------------*/\r
78 /* Private macro -------------------------------------------------------------*/\r
79 /* Private variables ---------------------------------------------------------*/\r
80 /* Private function prototypes -----------------------------------------------*/\r
81 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions\r
82  * @{\r
83  */\r
84 static void              FLASH_MassErase(uint32_t Banks);\r
85 static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);\r
86 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel);\r
87 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);\r
88 static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr);\r
89 static void              FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset);\r
90 static uint32_t          FLASH_OB_GetRDP(void);\r
91 static uint32_t          FLASH_OB_GetUser(void);\r
92 static void              FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr);\r
93 /**\r
94   * @}\r
95   */\r
96 \r
97 /* Exported functions -------------------------------------------------------*/\r
98 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions\r
99   * @{\r
100   */\r
101 \r
102 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions\r
103  *  @brief   Extended IO operation functions\r
104  *\r
105 @verbatim\r
106  ===============================================================================\r
107                 ##### Extended programming operation functions #####\r
108  ===============================================================================\r
109     [..]\r
110     This subsection provides a set of functions allowing to manage the Extended FLASH\r
111     programming operations Operations.\r
112 \r
113 @endverbatim\r
114   * @{\r
115   */\r
116 /**\r
117   * @brief  Perform a mass erase or erase the specified FLASH memory pages.\r
118   * @param[in]  pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that\r
119   *         contains the configuration information for the erasing.\r
120   *\r
121   * @param[out]  PageError  : pointer to variable that contains the configuration\r
122   *         information on faulty page in case of error (0xFFFFFFFF means that all\r
123   *         the pages have been correctly erased)\r
124   *\r
125   * @retval HAL Status\r
126   */\r
127 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)\r
128 {\r
129   HAL_StatusTypeDef status;\r
130   uint32_t page_index;\r
131 \r
132   /* Process Locked */\r
133   __HAL_LOCK(&pFlash);\r
134 \r
135   /* Check the parameters */\r
136   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
137 \r
138   /* Wait for last operation to be completed */\r
139   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
140 \r
141   if (status == HAL_OK)\r
142   {\r
143     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
144 \r
145     /* Deactivate the cache if they are activated to avoid data misbehavior */\r
146     if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)\r
147     {\r
148       /* Disable instruction cache  */\r
149       __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();\r
150 \r
151       if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
152       {\r
153         /* Disable data cache  */\r
154         __HAL_FLASH_DATA_CACHE_DISABLE();\r
155         pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;\r
156       }\r
157       else\r
158       {\r
159         pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;\r
160       }\r
161     }\r
162     else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
163     {\r
164       /* Disable data cache  */\r
165       __HAL_FLASH_DATA_CACHE_DISABLE();\r
166       pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;\r
167     }\r
168     else\r
169     {\r
170       pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;\r
171     }\r
172 \r
173     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)\r
174     {\r
175       /* Mass erase to be done */\r
176       FLASH_MassErase(pEraseInit->Banks);\r
177 \r
178       /* Wait for last operation to be completed */\r
179       status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
180 \r
181 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
182     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
183     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
184       /* If the erase operation is completed, disable the MER1 and MER2 Bits */\r
185       CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));\r
186 #else\r
187       /* If the erase operation is completed, disable the MER1 Bit */\r
188       CLEAR_BIT(FLASH->CR, (FLASH_CR_MER1));\r
189 #endif\r
190     }\r
191     else\r
192     {\r
193       /*Initialization of PageError variable*/\r
194       *PageError = 0xFFFFFFFFU;\r
195 \r
196       for(page_index = pEraseInit->Page; page_index < (pEraseInit->Page + pEraseInit->NbPages); page_index++)\r
197       {\r
198         FLASH_PageErase(page_index, pEraseInit->Banks);\r
199 \r
200         /* Wait for last operation to be completed */\r
201         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
202 \r
203         /* If the erase operation is completed, disable the PER Bit */\r
204         CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));\r
205 \r
206         if (status != HAL_OK)\r
207         {\r
208           /* In case of error, stop erase procedure and return the faulty address */\r
209           *PageError = page_index;\r
210           break;\r
211         }\r
212       }\r
213     }\r
214 \r
215     /* Flush the caches to be sure of the data consistency */\r
216     FLASH_FlushCaches();\r
217   }\r
218 \r
219   /* Process Unlocked */\r
220   __HAL_UNLOCK(&pFlash);\r
221 \r
222   return status;\r
223 }\r
224 \r
225 /**\r
226   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.\r
227   * @param  pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that\r
228   *         contains the configuration information for the erasing.\r
229   *\r
230   * @retval HAL Status\r
231   */\r
232 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)\r
233 {\r
234   HAL_StatusTypeDef status = HAL_OK;\r
235 \r
236   /* Process Locked */\r
237   __HAL_LOCK(&pFlash);\r
238 \r
239   /* Check the parameters */\r
240   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));\r
241 \r
242   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
243 \r
244   /* Deactivate the cache if they are activated to avoid data misbehavior */\r
245   if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) != 0U)\r
246   {\r
247     /* Disable instruction cache  */\r
248     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();\r
249 \r
250     if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
251     {\r
252       /* Disable data cache  */\r
253       __HAL_FLASH_DATA_CACHE_DISABLE();\r
254       pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_DCACHE_ENABLED;\r
255     }\r
256     else\r
257     {\r
258       pFlash.CacheToReactivate = FLASH_CACHE_ICACHE_ENABLED;\r
259     }\r
260   }\r
261   else if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)\r
262   {\r
263     /* Disable data cache  */\r
264     __HAL_FLASH_DATA_CACHE_DISABLE();\r
265     pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;\r
266   }\r
267   else\r
268   {\r
269     pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;\r
270   }\r
271 \r
272   /* Enable End of Operation and Error interrupts */\r
273   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);\r
274 \r
275   pFlash.Bank = pEraseInit->Banks;\r
276 \r
277   if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)\r
278   {\r
279     /* Mass erase to be done */\r
280     pFlash.ProcedureOnGoing = FLASH_PROC_MASS_ERASE;\r
281     FLASH_MassErase(pEraseInit->Banks);\r
282   }\r
283   else\r
284   {\r
285     /* Erase by page to be done */\r
286     pFlash.ProcedureOnGoing = FLASH_PROC_PAGE_ERASE;\r
287     pFlash.NbPagesToErase = pEraseInit->NbPages;\r
288     pFlash.Page = pEraseInit->Page;\r
289 \r
290     /*Erase 1st page and wait for IT */\r
291     FLASH_PageErase(pEraseInit->Page, pEraseInit->Banks);\r
292   }\r
293 \r
294   return status;\r
295 }\r
296 \r
297 /**\r
298   * @brief  Program Option bytes.\r
299   * @param  pOBInit: pointer to an FLASH_OBInitStruct structure that\r
300   *         contains the configuration information for the programming.\r
301   *\r
302   * @retval HAL Status\r
303   */\r
304 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)\r
305 {\r
306   HAL_StatusTypeDef status = HAL_OK;\r
307 \r
308   /* Process Locked */\r
309   __HAL_LOCK(&pFlash);\r
310 \r
311   /* Check the parameters */\r
312   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));\r
313 \r
314   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;\r
315 \r
316   /* Write protection configuration */\r
317   if((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)\r
318   {\r
319     /* Configure of Write protection on the selected area */\r
320     if(FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset) != HAL_OK)\r
321     {\r
322       status = HAL_ERROR;\r
323     }\r
324 \r
325   }\r
326 \r
327   /* Read protection configuration */\r
328   if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)\r
329   {\r
330     /* Configure the Read protection level */\r
331     if(FLASH_OB_RDPConfig(pOBInit->RDPLevel) != HAL_OK)\r
332     {\r
333       status = HAL_ERROR;\r
334     }\r
335   }\r
336 \r
337   /* User Configuration */\r
338   if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)\r
339   {\r
340     /* Configure the user option bytes */\r
341     if(FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig) != HAL_OK)\r
342     {\r
343       status = HAL_ERROR;\r
344     }\r
345   }\r
346 \r
347   /* PCROP Configuration */\r
348   if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)\r
349   {\r
350     if (pOBInit->PCROPStartAddr != pOBInit->PCROPEndAddr)\r
351     {\r
352       /* Configure the Proprietary code readout protection */\r
353       if(FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr) != HAL_OK)\r
354       {\r
355         status = HAL_ERROR;\r
356       }\r
357     }\r
358   }\r
359 \r
360   /* Process Unlocked */\r
361   __HAL_UNLOCK(&pFlash);\r
362 \r
363   return status;\r
364 }\r
365 \r
366 /**\r
367   * @brief  Get the Option bytes configuration.\r
368   * @param  pOBInit: pointer to an FLASH_OBInitStruct structure that contains the\r
369   *                  configuration information.\r
370   * @note   The fields pOBInit->WRPArea and pOBInit->PCROPConfig should indicate\r
371   *         which area is requested for the WRP and PCROP, else no information will be returned\r
372   *\r
373   * @retval None\r
374   */\r
375 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)\r
376 {\r
377   pOBInit->OptionType = (OPTIONBYTE_RDP | OPTIONBYTE_USER);\r
378 \r
379 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
380     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
381     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
382   if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB) ||\r
383      (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK2_AREAB))\r
384 #else\r
385   if((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))\r
386 #endif\r
387   {\r
388     pOBInit->OptionType |= OPTIONBYTE_WRP;\r
389     /* Get write protection on the selected area */\r
390     FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));\r
391   }\r
392 \r
393   /* Get Read protection level */\r
394   pOBInit->RDPLevel = FLASH_OB_GetRDP();\r
395 \r
396   /* Get the user option bytes */\r
397   pOBInit->USERConfig = FLASH_OB_GetUser();\r
398 \r
399 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
400     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
401     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
402   if((pOBInit->PCROPConfig == FLASH_BANK_1) || (pOBInit->PCROPConfig == FLASH_BANK_2))\r
403 #else\r
404   if(pOBInit->PCROPConfig == FLASH_BANK_1)\r
405 #endif\r
406   {\r
407     pOBInit->OptionType |= OPTIONBYTE_PCROP;\r
408     /* Get the Proprietary code readout protection */\r
409     FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr));\r
410   }\r
411 }\r
412 \r
413 /**\r
414   * @}\r
415   */\r
416 \r
417 #if defined (FLASH_CFGR_LVEN)\r
418 /** @defgroup FLASHEx_Exported_Functions_Group2 Extended specific configuration functions\r
419  *  @brief   Extended specific configuration functions\r
420  *\r
421 @verbatim\r
422  ===============================================================================\r
423                 ##### Extended specific configuration functions #####\r
424  ===============================================================================\r
425     [..]\r
426     This subsection provides a set of functions allowing to manage the Extended FLASH\r
427     specific configurations.\r
428 \r
429 @endverbatim\r
430   * @{\r
431   */\r
432 \r
433 /**\r
434   * @brief  Configuration of the LVE pin of the Flash (managed by power controller\r
435   *         or forced to low in order to use an external SMPS)\r
436   * @param  ConfigLVE: Configuration of the LVE pin,\r
437   *              This parameter can be one of the following values:\r
438   *                @arg FLASH_LVE_PIN_CTRL: LVE FLASH pin controlled by power controller\r
439   *                @arg FLASH_LVE_PIN_FORCED: LVE FLASH pin enforced to low (external SMPS used)\r
440   *\r
441   * @note   Before enforcing the LVE pin to low, the SOC should be in low voltage\r
442   *         range 2 and the voltage VDD12 should be higher than 1.08V and SMPS is ON.\r
443   *\r
444   * @retval HAL Status\r
445   */\r
446 HAL_StatusTypeDef HAL_FLASHEx_ConfigLVEPin(uint32_t ConfigLVE)\r
447 {\r
448   HAL_StatusTypeDef status;\r
449 \r
450   /* Process Locked */\r
451   __HAL_LOCK(&pFlash);\r
452 \r
453   /* Check the parameters */\r
454   assert_param(IS_FLASH_LVE_PIN(ConfigLVE));\r
455 \r
456   /* Wait for last operation to be completed */\r
457   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
458 \r
459   if (status == HAL_OK)\r
460   {\r
461     /* Check that the voltage scaling is range 2 */\r
462     if (HAL_PWREx_GetVoltageRange() == PWR_REGULATOR_VOLTAGE_SCALE2)\r
463     {\r
464       /* Configure the LVEN bit */\r
465       MODIFY_REG(FLASH->CFGR, FLASH_CFGR_LVEN, ConfigLVE);\r
466 \r
467       /* Check that the bit has been correctly configured */\r
468       if (READ_BIT(FLASH->CFGR, FLASH_CFGR_LVEN) != ConfigLVE)\r
469       {\r
470         status = HAL_ERROR;\r
471       }\r
472     }\r
473     else\r
474     {\r
475       /* Not allow to force Flash LVE pin if not in voltage range 2 */\r
476       status = HAL_ERROR;\r
477     }\r
478   }\r
479 \r
480   /* Process Unlocked */\r
481   __HAL_UNLOCK(&pFlash);\r
482 \r
483   return status;\r
484 }\r
485 \r
486 /**\r
487   * @}\r
488   */\r
489 #endif /* FLASH_CFGR_LVEN */\r
490 \r
491 /**\r
492   * @}\r
493   */\r
494 \r
495 /* Private functions ---------------------------------------------------------*/\r
496 \r
497 /** @addtogroup FLASHEx_Private_Functions\r
498   * @{\r
499   */\r
500 /**\r
501   * @brief  Mass erase of FLASH memory.\r
502   * @param  Banks: Banks to be erased\r
503   *          This parameter can be one of the following values:\r
504   *            @arg FLASH_BANK_1: Bank1 to be erased\r
505   *            @arg FLASH_BANK_2: Bank2 to be erased\r
506   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased\r
507   * @retval None\r
508   */\r
509 static void FLASH_MassErase(uint32_t Banks)\r
510 {\r
511 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
512   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) != 0U)\r
513 #endif\r
514   {\r
515     /* Check the parameters */\r
516     assert_param(IS_FLASH_BANK(Banks));\r
517 \r
518     /* Set the Mass Erase Bit for the bank 1 if requested */\r
519     if((Banks & FLASH_BANK_1) != 0U)\r
520     {\r
521       SET_BIT(FLASH->CR, FLASH_CR_MER1);\r
522     }\r
523 \r
524 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
525     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
526     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
527     /* Set the Mass Erase Bit for the bank 2 if requested */\r
528     if((Banks & FLASH_BANK_2) != 0U)\r
529     {\r
530       SET_BIT(FLASH->CR, FLASH_CR_MER2);\r
531     }\r
532 #endif\r
533   }\r
534 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
535   else\r
536   {\r
537     SET_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));\r
538   }\r
539 #endif\r
540 \r
541   /* Proceed to erase all sectors */\r
542   SET_BIT(FLASH->CR, FLASH_CR_STRT);\r
543 }\r
544 \r
545 /**\r
546   * @brief  Erase the specified FLASH memory page.\r
547   * @param  Page: FLASH page to erase\r
548   *         This parameter must be a value between 0 and (max number of pages in the bank - 1)\r
549   * @param  Banks: Bank(s) where the page will be erased\r
550   *          This parameter can be one of the following values:\r
551   *            @arg FLASH_BANK_1: Page in bank 1 to be erased\r
552   *            @arg FLASH_BANK_2: Page in bank 2 to be erased\r
553   * @retval None\r
554   */\r
555 void FLASH_PageErase(uint32_t Page, uint32_t Banks)\r
556 {\r
557   /* Check the parameters */\r
558   assert_param(IS_FLASH_PAGE(Page));\r
559 \r
560 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
561     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
562     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
563 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
564   if(READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)\r
565   {\r
566     CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);\r
567   }\r
568   else\r
569 #endif\r
570   {\r
571     assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));\r
572 \r
573     if((Banks & FLASH_BANK_1) != 0U)\r
574     {\r
575       CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);\r
576     }\r
577     else\r
578     {\r
579       SET_BIT(FLASH->CR, FLASH_CR_BKER);\r
580     }\r
581   }\r
582 #else\r
583   /* Prevent unused argument(s) compilation warning */\r
584   UNUSED(Banks);\r
585 #endif\r
586 \r
587   /* Proceed to erase the page */\r
588   MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page & 0xFFU) << FLASH_CR_PNB_Pos));\r
589   SET_BIT(FLASH->CR, FLASH_CR_PER);\r
590   SET_BIT(FLASH->CR, FLASH_CR_STRT);\r
591 }\r
592 \r
593 /**\r
594   * @brief  Flush the instruction and data caches.\r
595   * @retval None\r
596   */\r
597 void FLASH_FlushCaches(void)\r
598 {\r
599   FLASH_CacheTypeDef cache = pFlash.CacheToReactivate;\r
600 \r
601   /* Flush instruction cache  */\r
602   if((cache == FLASH_CACHE_ICACHE_ENABLED) ||\r
603      (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))\r
604   {\r
605     /* Reset instruction cache */\r
606     __HAL_FLASH_INSTRUCTION_CACHE_RESET();\r
607     /* Enable instruction cache */\r
608     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();\r
609   }\r
610 \r
611   /* Flush data cache */\r
612   if((cache == FLASH_CACHE_DCACHE_ENABLED) ||\r
613      (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))\r
614   {\r
615     /* Reset data cache */\r
616     __HAL_FLASH_DATA_CACHE_RESET();\r
617     /* Enable data cache */\r
618     __HAL_FLASH_DATA_CACHE_ENABLE();\r
619   }\r
620 \r
621   /* Reset internal variable */\r
622   pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;\r
623 }\r
624 \r
625 /**\r
626   * @brief  Configure the write protection of the desired pages.\r
627   *\r
628   * @note   When the memory read protection level is selected (RDP level = 1),\r
629   *         it is not possible to program or erase Flash memory if the CPU debug\r
630   *         features are connected (JTAG or single wire) or boot code is being\r
631   *         executed from RAM or System flash, even if WRP is not activated.\r
632   * @note   To configure the WRP options, the option lock bit OPTLOCK must be\r
633   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
634   * @note   To validate the WRP options, the option bytes must be reloaded\r
635   *         through the call of the HAL_FLASH_OB_Launch() function.\r
636   *\r
637   * @param  WRPArea: specifies the area to be configured.\r
638   *          This parameter can be one of the following values:\r
639   *            @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A\r
640   *            @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B\r
641   *            @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A  (don't apply for STM32L43x/STM32L44x devices)\r
642   *            @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B  (don't apply for STM32L43x/STM32L44x devices)\r
643   *\r
644   * @param  WRPStartOffset: specifies the start page of the write protected area\r
645   *          This parameter can be page number between 0 and (max number of pages in the bank - 1)\r
646   *\r
647   * @param  WRDPEndOffset: specifies the end page of the write protected area\r
648   *          This parameter can be page number between WRPStartOffset and (max number of pages in the bank - 1)\r
649   *\r
650   * @retval HAL Status\r
651   */\r
652 static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)\r
653 {\r
654   HAL_StatusTypeDef status;\r
655 \r
656   /* Check the parameters */\r
657   assert_param(IS_OB_WRPAREA(WRPArea));\r
658   assert_param(IS_FLASH_PAGE(WRPStartOffset));\r
659   assert_param(IS_FLASH_PAGE(WRDPEndOffset));\r
660 \r
661   /* Wait for last operation to be completed */\r
662   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
663 \r
664   if(status == HAL_OK)\r
665   {\r
666     /* Configure the write protected area */\r
667     if(WRPArea == OB_WRPAREA_BANK1_AREAA)\r
668     {\r
669       MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),\r
670                  (WRPStartOffset | (WRDPEndOffset << 16)));\r
671     }\r
672     else if(WRPArea == OB_WRPAREA_BANK1_AREAB)\r
673     {\r
674       MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),\r
675                  (WRPStartOffset | (WRDPEndOffset << 16)));\r
676     }\r
677 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
678     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
679     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
680     else if(WRPArea == OB_WRPAREA_BANK2_AREAA)\r
681     {\r
682       MODIFY_REG(FLASH->WRP2AR, (FLASH_WRP2AR_WRP2A_STRT | FLASH_WRP2AR_WRP2A_END),\r
683                  (WRPStartOffset | (WRDPEndOffset << 16)));\r
684     }\r
685     else if(WRPArea == OB_WRPAREA_BANK2_AREAB)\r
686     {\r
687       MODIFY_REG(FLASH->WRP2BR, (FLASH_WRP2BR_WRP2B_STRT | FLASH_WRP2BR_WRP2B_END),\r
688                  (WRPStartOffset | (WRDPEndOffset << 16)));\r
689     }\r
690 #endif\r
691     else\r
692     {\r
693       /* Nothing to do */\r
694     }\r
695 \r
696     /* Set OPTSTRT Bit */\r
697     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
698 \r
699     /* Wait for last operation to be completed */\r
700     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
701 \r
702     /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
703     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
704   }\r
705 \r
706   return status;\r
707 }\r
708 \r
709 /**\r
710   * @brief  Set the read protection level.\r
711   *\r
712   * @note   To configure the RDP level, the option lock bit OPTLOCK must be\r
713   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
714   * @note   To validate the RDP level, the option bytes must be reloaded\r
715   *         through the call of the HAL_FLASH_OB_Launch() function.\r
716   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible\r
717   *         to go back to level 1 or 0 !!!\r
718   *\r
719   * @param  RDPLevel: specifies the read protection level.\r
720   *         This parameter can be one of the following values:\r
721   *            @arg OB_RDP_LEVEL_0: No protection\r
722   *            @arg OB_RDP_LEVEL_1: Read protection of the memory\r
723   *            @arg OB_RDP_LEVEL_2: Full chip protection\r
724   *\r
725   * @retval HAL status\r
726   */\r
727 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel)\r
728 {\r
729   HAL_StatusTypeDef status;\r
730 \r
731   /* Check the parameters */\r
732   assert_param(IS_OB_RDP_LEVEL(RDPLevel));\r
733 \r
734   /* Wait for last operation to be completed */\r
735   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
736 \r
737   if(status == HAL_OK)\r
738   {\r
739     /* Configure the RDP level in the option bytes register */\r
740     MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, RDPLevel);\r
741 \r
742     /* Set OPTSTRT Bit */\r
743     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
744 \r
745     /* Wait for last operation to be completed */\r
746     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
747 \r
748     /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
749     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
750   }\r
751 \r
752   return status;\r
753 }\r
754 \r
755 /**\r
756   * @brief  Program the FLASH User Option Byte.\r
757   *\r
758   * @note   To configure the user option bytes, the option lock bit OPTLOCK must\r
759   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
760   * @note   To validate the user option bytes, the option bytes must be reloaded\r
761   *         through the call of the HAL_FLASH_OB_Launch() function.\r
762   *\r
763   * @param  UserType: The FLASH User Option Bytes to be modified\r
764   * @param  UserConfig: The FLASH User Option Bytes values:\r
765   *         BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), IWDG_SW(Bit16),\r
766   *         IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19), BFB2(Bit20),\r
767   *         DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).\r
768   *\r
769   * @retval HAL status\r
770   */\r
771 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)\r
772 {\r
773   uint32_t optr_reg_val = 0;\r
774   uint32_t optr_reg_mask = 0;\r
775   HAL_StatusTypeDef status;\r
776 \r
777   /* Check the parameters */\r
778   assert_param(IS_OB_USER_TYPE(UserType));\r
779 \r
780   /* Wait for last operation to be completed */\r
781   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
782 \r
783   if(status == HAL_OK)\r
784   {\r
785     if((UserType & OB_USER_BOR_LEV) != 0U)\r
786     {\r
787       /* BOR level option byte should be modified */\r
788       assert_param(IS_OB_USER_BOR_LEVEL(UserConfig & FLASH_OPTR_BOR_LEV));\r
789 \r
790       /* Set value and mask for BOR level option byte */\r
791       optr_reg_val |= (UserConfig & FLASH_OPTR_BOR_LEV);\r
792       optr_reg_mask |= FLASH_OPTR_BOR_LEV;\r
793     }\r
794 \r
795     if((UserType & OB_USER_nRST_STOP) != 0U)\r
796     {\r
797       /* nRST_STOP option byte should be modified */\r
798       assert_param(IS_OB_USER_STOP(UserConfig & FLASH_OPTR_nRST_STOP));\r
799 \r
800       /* Set value and mask for nRST_STOP option byte */\r
801       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STOP);\r
802       optr_reg_mask |= FLASH_OPTR_nRST_STOP;\r
803     }\r
804 \r
805     if((UserType & OB_USER_nRST_STDBY) != 0U)\r
806     {\r
807       /* nRST_STDBY option byte should be modified */\r
808       assert_param(IS_OB_USER_STANDBY(UserConfig & FLASH_OPTR_nRST_STDBY));\r
809 \r
810       /* Set value and mask for nRST_STDBY option byte */\r
811       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STDBY);\r
812       optr_reg_mask |= FLASH_OPTR_nRST_STDBY;\r
813     }\r
814 \r
815     if((UserType & OB_USER_nRST_SHDW) != 0U)\r
816     {\r
817       /* nRST_SHDW option byte should be modified */\r
818       assert_param(IS_OB_USER_SHUTDOWN(UserConfig & FLASH_OPTR_nRST_SHDW));\r
819 \r
820       /* Set value and mask for nRST_SHDW option byte */\r
821       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_SHDW);\r
822       optr_reg_mask |= FLASH_OPTR_nRST_SHDW;\r
823     }\r
824 \r
825     if((UserType & OB_USER_IWDG_SW) != 0U)\r
826     {\r
827       /* IWDG_SW option byte should be modified */\r
828       assert_param(IS_OB_USER_IWDG(UserConfig & FLASH_OPTR_IWDG_SW));\r
829 \r
830       /* Set value and mask for IWDG_SW option byte */\r
831       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_SW);\r
832       optr_reg_mask |= FLASH_OPTR_IWDG_SW;\r
833     }\r
834 \r
835     if((UserType & OB_USER_IWDG_STOP) != 0U)\r
836     {\r
837       /* IWDG_STOP option byte should be modified */\r
838       assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTR_IWDG_STOP));\r
839 \r
840       /* Set value and mask for IWDG_STOP option byte */\r
841       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STOP);\r
842       optr_reg_mask |= FLASH_OPTR_IWDG_STOP;\r
843     }\r
844 \r
845     if((UserType & OB_USER_IWDG_STDBY) != 0U)\r
846     {\r
847       /* IWDG_STDBY option byte should be modified */\r
848       assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTR_IWDG_STDBY));\r
849 \r
850       /* Set value and mask for IWDG_STDBY option byte */\r
851       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STDBY);\r
852       optr_reg_mask |= FLASH_OPTR_IWDG_STDBY;\r
853     }\r
854 \r
855     if((UserType & OB_USER_WWDG_SW) != 0U)\r
856     {\r
857       /* WWDG_SW option byte should be modified */\r
858       assert_param(IS_OB_USER_WWDG(UserConfig & FLASH_OPTR_WWDG_SW));\r
859 \r
860       /* Set value and mask for WWDG_SW option byte */\r
861       optr_reg_val |= (UserConfig & FLASH_OPTR_WWDG_SW);\r
862       optr_reg_mask |= FLASH_OPTR_WWDG_SW;\r
863     }\r
864 \r
865 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
866     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
867     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
868     if((UserType & OB_USER_BFB2) != 0U)\r
869     {\r
870       /* BFB2 option byte should be modified */\r
871       assert_param(IS_OB_USER_BFB2(UserConfig & FLASH_OPTR_BFB2));\r
872 \r
873       /* Set value and mask for BFB2 option byte */\r
874       optr_reg_val |= (UserConfig & FLASH_OPTR_BFB2);\r
875       optr_reg_mask |= FLASH_OPTR_BFB2;\r
876     }\r
877 \r
878     if((UserType & OB_USER_DUALBANK) != 0U)\r
879     {\r
880 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
881       /* DUALBANK option byte should be modified */\r
882       assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DB1M));\r
883 \r
884       /* Set value and mask for DUALBANK option byte */\r
885       optr_reg_val |= (UserConfig & FLASH_OPTR_DB1M);\r
886       optr_reg_mask |= FLASH_OPTR_DB1M;\r
887 #else\r
888       /* DUALBANK option byte should be modified */\r
889       assert_param(IS_OB_USER_DUALBANK(UserConfig & FLASH_OPTR_DUALBANK));\r
890 \r
891       /* Set value and mask for DUALBANK option byte */\r
892       optr_reg_val |= (UserConfig & FLASH_OPTR_DUALBANK);\r
893       optr_reg_mask |= FLASH_OPTR_DUALBANK;\r
894 #endif\r
895     }\r
896 #endif\r
897 \r
898     if((UserType & OB_USER_nBOOT1) != 0U)\r
899     {\r
900       /* nBOOT1 option byte should be modified */\r
901       assert_param(IS_OB_USER_BOOT1(UserConfig & FLASH_OPTR_nBOOT1));\r
902 \r
903       /* Set value and mask for nBOOT1 option byte */\r
904       optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT1);\r
905       optr_reg_mask |= FLASH_OPTR_nBOOT1;\r
906     }\r
907 \r
908     if((UserType & OB_USER_SRAM2_PE) != 0U)\r
909     {\r
910       /* SRAM2_PE option byte should be modified */\r
911       assert_param(IS_OB_USER_SRAM2_PARITY(UserConfig & FLASH_OPTR_SRAM2_PE));\r
912 \r
913       /* Set value and mask for SRAM2_PE option byte */\r
914       optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_PE);\r
915       optr_reg_mask |= FLASH_OPTR_SRAM2_PE;\r
916     }\r
917 \r
918     if((UserType & OB_USER_SRAM2_RST) != 0U)\r
919     {\r
920       /* SRAM2_RST option byte should be modified */\r
921       assert_param(IS_OB_USER_SRAM2_RST(UserConfig & FLASH_OPTR_SRAM2_RST));\r
922 \r
923       /* Set value and mask for SRAM2_RST option byte */\r
924       optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM2_RST);\r
925       optr_reg_mask |= FLASH_OPTR_SRAM2_RST;\r
926     }\r
927 \r
928 #if defined (STM32L412xx) || defined (STM32L422xx) || defined (STM32L431xx) || defined (STM32L432xx) || defined (STM32L433xx) || \\r
929     defined (STM32L442xx) || defined (STM32L443xx) || defined (STM32L451xx) || defined (STM32L452xx) || defined (STM32L462xx) || \\r
930     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
931     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
932     if((UserType & OB_USER_nSWBOOT0) != 0U)\r
933     {\r
934       /* nSWBOOT0 option byte should be modified */\r
935       assert_param(IS_OB_USER_SWBOOT0(UserConfig & FLASH_OPTR_nSWBOOT0));\r
936 \r
937       /* Set value and mask for nSWBOOT0 option byte */\r
938       optr_reg_val |= (UserConfig & FLASH_OPTR_nSWBOOT0);\r
939       optr_reg_mask |= FLASH_OPTR_nSWBOOT0;\r
940     }\r
941 \r
942     if((UserType & OB_USER_nBOOT0) != 0U)\r
943     {\r
944       /* nBOOT0 option byte should be modified */\r
945       assert_param(IS_OB_USER_BOOT0(UserConfig & FLASH_OPTR_nBOOT0));\r
946 \r
947       /* Set value and mask for nBOOT0 option byte */\r
948       optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT0);\r
949       optr_reg_mask |= FLASH_OPTR_nBOOT0;\r
950     }\r
951 #endif\r
952 \r
953     /* Configure the option bytes register */\r
954     MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);\r
955 \r
956     /* Set OPTSTRT Bit */\r
957     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
958 \r
959     /* Wait for last operation to be completed */\r
960     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
961 \r
962     /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
963     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
964   }\r
965 \r
966   return status;\r
967 }\r
968 \r
969 /**\r
970   * @brief  Configure the Proprietary code readout protection of the desired addresses.\r
971   *\r
972   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be\r
973   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.\r
974   * @note   To validate the PCROP options, the option bytes must be reloaded\r
975   *         through the call of the HAL_FLASH_OB_Launch() function.\r
976   *\r
977   * @param  PCROPConfig: specifies the configuration (Bank to be configured and PCROP_RDP option).\r
978   *          This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2\r
979   *          with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE\r
980   *\r
981   * @param  PCROPStartAddr: specifies the start address of the Proprietary code readout protection\r
982   *          This parameter can be an address between begin and end of the bank\r
983   *\r
984   * @param  PCROPEndAddr: specifies the end address of the Proprietary code readout protection\r
985   *          This parameter can be an address between PCROPStartAddr and end of the bank\r
986   *\r
987   * @retval HAL Status\r
988   */\r
989 static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr)\r
990 {\r
991   HAL_StatusTypeDef status;\r
992   uint32_t reg_value;\r
993   uint32_t bank1_addr;\r
994 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
995     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
996     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
997   uint32_t bank2_addr;\r
998 #endif\r
999 \r
1000   /* Check the parameters */\r
1001   assert_param(IS_FLASH_BANK_EXCLUSIVE(PCROPConfig & FLASH_BANK_BOTH));\r
1002   assert_param(IS_OB_PCROP_RDP(PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));\r
1003   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPStartAddr));\r
1004   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPEndAddr));\r
1005 \r
1006   /* Wait for last operation to be completed */\r
1007   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
1008 \r
1009   if(status == HAL_OK)\r
1010   {\r
1011 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
1012     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
1013     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1014     /* Get the information about the bank swapping */\r
1015     if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)\r
1016     {\r
1017       bank1_addr = FLASH_BASE;\r
1018       bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
1019     }\r
1020     else\r
1021     {\r
1022       bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
1023       bank2_addr = FLASH_BASE;\r
1024     }\r
1025 #else\r
1026     bank1_addr = FLASH_BASE;\r
1027 #endif\r
1028 \r
1029 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1030     if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)\r
1031     {\r
1032       /* Configure the Proprietary code readout protection */\r
1033       if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
1034       {\r
1035         reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);\r
1036         MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);\r
1037 \r
1038         reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);\r
1039         MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);\r
1040       }\r
1041       else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
1042       {\r
1043         reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);\r
1044         MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);\r
1045 \r
1046         reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);\r
1047         MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);\r
1048       }\r
1049       else\r
1050       {\r
1051         /* Nothing to do */\r
1052       }\r
1053     }\r
1054     else\r
1055 #endif\r
1056     {\r
1057       /* Configure the Proprietary code readout protection */\r
1058       if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
1059       {\r
1060         reg_value = ((PCROPStartAddr - bank1_addr) >> 3);\r
1061         MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);\r
1062 \r
1063         reg_value = ((PCROPEndAddr - bank1_addr) >> 3);\r
1064         MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);\r
1065       }\r
1066 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
1067     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
1068     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1069       else if((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
1070       {\r
1071         reg_value = ((PCROPStartAddr - bank2_addr) >> 3);\r
1072         MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);\r
1073 \r
1074         reg_value = ((PCROPEndAddr - bank2_addr) >> 3);\r
1075         MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);\r
1076       }\r
1077 #endif\r
1078       else\r
1079       {\r
1080         /* Nothing to do */\r
1081       }\r
1082     }\r
1083 \r
1084     MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP_RDP, (PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));\r
1085 \r
1086     /* Set OPTSTRT Bit */\r
1087     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
1088 \r
1089     /* Wait for last operation to be completed */\r
1090     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);\r
1091 \r
1092     /* If the option byte program operation is completed, disable the OPTSTRT Bit */\r
1093     CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT);\r
1094   }\r
1095 \r
1096   return status;\r
1097 }\r
1098 \r
1099 /**\r
1100   * @brief  Return the FLASH Write Protection Option Bytes value.\r
1101   *\r
1102   * @param[in]  WRPArea: specifies the area to be returned.\r
1103   *          This parameter can be one of the following values:\r
1104   *            @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A\r
1105   *            @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B\r
1106   *            @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply to STM32L43x/STM32L44x devices)\r
1107   *            @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply to STM32L43x/STM32L44x devices)\r
1108   *\r
1109   * @param[out]  WRPStartOffset: specifies the address where to copied the start page\r
1110   *                         of the write protected area\r
1111   *\r
1112   * @param[out]  WRDPEndOffset: specifies the address where to copied the end page of\r
1113   *                        the write protected area\r
1114   *\r
1115   * @retval None\r
1116   */\r
1117 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t * WRPStartOffset, uint32_t * WRDPEndOffset)\r
1118 {\r
1119   /* Get the configuration of the write protected area */\r
1120   if(WRPArea == OB_WRPAREA_BANK1_AREAA)\r
1121   {\r
1122     *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);\r
1123     *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> 16);\r
1124   }\r
1125   else if(WRPArea == OB_WRPAREA_BANK1_AREAB)\r
1126   {\r
1127     *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);\r
1128     *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> 16);\r
1129   }\r
1130 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
1131     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
1132     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1133   else if(WRPArea == OB_WRPAREA_BANK2_AREAA)\r
1134   {\r
1135     *WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);\r
1136     *WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> 16);\r
1137   }\r
1138   else if(WRPArea == OB_WRPAREA_BANK2_AREAB)\r
1139   {\r
1140     *WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);\r
1141     *WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> 16);\r
1142   }\r
1143 #endif\r
1144   else\r
1145   {\r
1146     /* Nothing to do */\r
1147   }\r
1148 }\r
1149 \r
1150 /**\r
1151   * @brief  Return the FLASH Read Protection level.\r
1152   * @retval FLASH ReadOut Protection Status:\r
1153   *         This return value can be one of the following values:\r
1154   *            @arg OB_RDP_LEVEL_0: No protection\r
1155   *            @arg OB_RDP_LEVEL_1: Read protection of the memory\r
1156   *            @arg OB_RDP_LEVEL_2: Full chip protection\r
1157   */\r
1158 static uint32_t FLASH_OB_GetRDP(void)\r
1159 {\r
1160   uint32_t rdp_level = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);\r
1161 \r
1162   if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))\r
1163   {\r
1164     return (OB_RDP_LEVEL_1);\r
1165   }\r
1166   else\r
1167   {\r
1168     return (READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP));\r
1169   }\r
1170 }\r
1171 \r
1172 /**\r
1173   * @brief  Return the FLASH User Option Byte value.\r
1174   * @retval The FLASH User Option Bytes values:\r
1175   *      For STM32L47x/STM32L48x devices :\r
1176   *         BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),\r
1177   *         IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),\r
1178   *         BFB2(Bit20), DUALBANK(Bit21), nBOOT1(Bit23), SRAM2_PE(Bit24) and SRAM2_RST(Bit25).\r
1179   *      For STM32L43x/STM32L44x devices :\r
1180   *         BOR_LEV(Bit8-10), nRST_STOP(Bit12), nRST_STDBY(Bit13), nRST_SHDW(Bit14),\r
1181   *         IWDG_SW(Bit16), IWDG_STOP(Bit17), IWDG_STDBY(Bit18), WWDG_SW(Bit19),\r
1182   *         nBOOT1(Bit23), SRAM2_PE(Bit24), SRAM2_RST(Bit25), nSWBOOT0(Bit26) and nBOOT0(Bit27).\r
1183   */\r
1184 static uint32_t FLASH_OB_GetUser(void)\r
1185 {\r
1186   uint32_t user_config = READ_REG(FLASH->OPTR);\r
1187   CLEAR_BIT(user_config, FLASH_OPTR_RDP);\r
1188 \r
1189   return user_config;\r
1190 }\r
1191 \r
1192 /**\r
1193   * @brief  Return the FLASH Write Protection Option Bytes value.\r
1194   *\r
1195   * @param PCROPConfig [inout]: specifies the configuration (Bank to be configured and PCROP_RDP option).\r
1196   *          This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2\r
1197   *          with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE\r
1198   *\r
1199   * @param PCROPStartAddr [out]: specifies the address where to copied the start address\r
1200   *                         of the Proprietary code readout protection\r
1201   *\r
1202   * @param PCROPEndAddr [out]: specifies the address where to copied the end address of\r
1203   *                       the Proprietary code readout protection\r
1204   *\r
1205   * @retval None\r
1206   */\r
1207 static void FLASH_OB_GetPCROP(uint32_t * PCROPConfig, uint32_t * PCROPStartAddr, uint32_t * PCROPEndAddr)\r
1208 {\r
1209   uint32_t reg_value;\r
1210   uint32_t bank1_addr;\r
1211 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
1212     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
1213     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1214   uint32_t bank2_addr;\r
1215 #endif\r
1216 \r
1217 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
1218     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
1219     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1220   /* Get the information about the bank swapping */\r
1221   if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)\r
1222   {\r
1223     bank1_addr = FLASH_BASE;\r
1224     bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
1225   }\r
1226   else\r
1227   {\r
1228     bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;\r
1229     bank2_addr = FLASH_BASE;\r
1230   }\r
1231 #else\r
1232   bank1_addr = FLASH_BASE;\r
1233 #endif\r
1234 \r
1235 #if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1236   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)\r
1237   {\r
1238     if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
1239     {\r
1240       reg_value       = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);\r
1241       *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;\r
1242 \r
1243       reg_value     = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);\r
1244       *PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;\r
1245     }\r
1246     else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
1247     {\r
1248       reg_value       = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);\r
1249       *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;\r
1250 \r
1251       reg_value     = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);\r
1252       *PCROPEndAddr = (reg_value << 4) + FLASH_BASE + 0xFU;;\r
1253     }\r
1254     else\r
1255     {\r
1256       /* Nothing to do */\r
1257     }\r
1258   }\r
1259   else\r
1260 #endif\r
1261   {\r
1262     if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)\r
1263     {\r
1264       reg_value       = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);\r
1265       *PCROPStartAddr = (reg_value << 3) + bank1_addr;\r
1266 \r
1267       reg_value     = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);\r
1268       *PCROPEndAddr = (reg_value << 3) + bank1_addr + 0x7U;\r
1269     }\r
1270 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \\r
1271     defined (STM32L496xx) || defined (STM32L4A6xx) || \\r
1272     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)\r
1273     else if(((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)\r
1274     {\r
1275       reg_value       = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);\r
1276       *PCROPStartAddr = (reg_value << 3) + bank2_addr;\r
1277 \r
1278       reg_value     = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);\r
1279       *PCROPEndAddr = (reg_value << 3) + bank2_addr + 0x7U;\r
1280     }\r
1281 #endif\r
1282     else\r
1283     {\r
1284       /* Nothing to do */\r
1285     }\r
1286   }\r
1287 \r
1288   *PCROPConfig |= (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP_RDP);\r
1289 }\r
1290 /**\r
1291   * @}\r
1292   */\r
1293 \r
1294 /**\r
1295   * @}\r
1296   */\r
1297 \r
1298 #endif /* HAL_FLASH_MODULE_ENABLED */\r
1299 \r
1300 /**\r
1301   * @}\r
1302   */\r
1303 \r
1304 /**\r
1305   * @}\r
1306   */\r
1307 \r
1308 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r