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