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