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   {
481     SET_BIT(FLASH->CR, FLASH_CR_SEC_PROT1);
482   }
483 #else
484   /* Prevent unused argument(s) compilation warning */
485   UNUSED(Bank);
486   SET_BIT(FLASH->CR, FLASH_CR_SEC_PROT1);
487 #endif /* FLASH_OPTR_DBANK */
488 
489   return HAL_OK;
490 }
491 
492 /**
493   * @brief  Enable Debugger.
494   * @note   After calling this API, flash interface allow debugger intrusion.
495   * @retval None
496   */
HAL_FLASHEx_EnableDebugger(void)497 void HAL_FLASHEx_EnableDebugger(void)
498 {
499   FLASH->ACR |= FLASH_ACR_DBG_SWEN;
500 }
501 
502 
503 /**
504   * @brief  Disable Debugger.
505   * @note   After calling this API, Debugger is disabled: it's no more possible to
506   *         break, see CPU register, etc...
507   * @retval None
508   */
HAL_FLASHEx_DisableDebugger(void)509 void HAL_FLASHEx_DisableDebugger(void)
510 {
511   FLASH->ACR &= ~FLASH_ACR_DBG_SWEN;
512 }
513 
514 /**
515   * @}
516   */
517 
518 /**
519   * @}
520   */
521 
522 /* Private functions ---------------------------------------------------------*/
523 
524 /** @addtogroup FLASHEx_Private_Functions
525   * @{
526   */
527 /**
528   * @brief  Mass erase of FLASH memory.
529   * @param  Banks Banks to be erased.
530   *         This parameter can be one of the following values:
531   *            @arg FLASH_BANK_1: Bank1 to be erased
532   *            @arg FLASH_BANK_2: Bank2 to be erased (*)
533   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased (*)
534   * @note   (*) availability depends on devices
535   * @retval None
536   */
FLASH_MassErase(uint32_t Banks)537 static void FLASH_MassErase(uint32_t Banks)
538 {
539 #if defined (FLASH_OPTR_DBANK)
540   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) != 0U)
541 #endif
542   {
543     /* Check the parameters */
544     assert_param(IS_FLASH_BANK(Banks));
545 
546     /* Set the Mass Erase Bit for the bank 1 if requested */
547     if ((Banks & FLASH_BANK_1) != 0U)
548     {
549       SET_BIT(FLASH->CR, FLASH_CR_MER1);
550     }
551 
552 #if defined (FLASH_OPTR_DBANK)
553     /* Set the Mass Erase Bit for the bank 2 if requested */
554     if ((Banks & FLASH_BANK_2) != 0U)
555     {
556       SET_BIT(FLASH->CR, FLASH_CR_MER2);
557     }
558 #endif
559   }
560 #if defined (FLASH_OPTR_DBANK)
561   else
562   {
563     SET_BIT(FLASH->CR, (FLASH_CR_MER1 | FLASH_CR_MER2));
564   }
565 #endif
566 
567   /* Proceed to erase all sectors */
568   SET_BIT(FLASH->CR, FLASH_CR_STRT);
569 }
570 
571 /**
572   * @brief  Erase the specified FLASH memory page.
573   * @param  Page FLASH page to erase.
574   *         This parameter must be a value between 0 and (max number of pages in the bank - 1).
575   * @param  Banks Bank where the page will be erased.
576   *         This parameter can be one of the following values:
577   *            @arg FLASH_BANK_1: Page in bank 1 to be erased
578   *            @arg FLASH_BANK_2: Page in bank 2 to be erased (*)
579   * @note   (*) availability depends on devices
580   * @retval None
581   */
FLASH_PageErase(uint32_t Page,uint32_t Banks)582 void FLASH_PageErase(uint32_t Page, uint32_t Banks)
583 {
584   /* Check the parameters */
585   assert_param(IS_FLASH_PAGE(Page));
586 
587 #if defined (FLASH_OPTR_DBANK)
588   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
589   {
590     CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
591   }
592   else
593   {
594     assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
595 
596     if ((Banks & FLASH_BANK_1) != 0U)
597     {
598       CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
599     }
600     else
601     {
602       SET_BIT(FLASH->CR, FLASH_CR_BKER);
603     }
604   }
605 #else
606   /* Prevent unused argument(s) compilation warning */
607   UNUSED(Banks);
608 #endif /* FLASH_OPTR_DBANK */
609 
610   /* Proceed to erase the page */
611   MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page & 0xFFU) << FLASH_CR_PNB_Pos));
612   SET_BIT(FLASH->CR, FLASH_CR_PER);
613   SET_BIT(FLASH->CR, FLASH_CR_STRT);
614 }
615 
616 /**
617   * @brief  Flush the instruction and data caches.
618   * @retval None
619   */
FLASH_FlushCaches(void)620 void FLASH_FlushCaches(void)
621 {
622   FLASH_CacheTypeDef cache = pFlash.CacheToReactivate;
623 
624   /* Flush instruction cache  */
625   if ((cache == FLASH_CACHE_ICACHE_ENABLED) ||
626       (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))
627   {
628     /* Disable instruction cache */
629     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
630     /* Reset instruction cache */
631     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
632     /* Enable instruction cache */
633     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
634   }
635 
636   /* Flush data cache */
637   if ((cache == FLASH_CACHE_DCACHE_ENABLED) ||
638       (cache == FLASH_CACHE_ICACHE_DCACHE_ENABLED))
639   {
640     /* Reset data cache */
641     __HAL_FLASH_DATA_CACHE_RESET();
642     /* Enable data cache */
643     __HAL_FLASH_DATA_CACHE_ENABLE();
644   }
645 
646   /* Reset internal variable */
647   pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
648 }
649 
650 /**
651   * @brief  Configure the write protection area into Option Bytes.
652   * @note   When the memory read protection level is selected (RDP level = 1),
653   *         it is not possible to program or erase Flash memory if the CPU debug
654   *         features are connected (JTAG or single wire) or boot code is being
655   *         executed from RAM or System flash, even if WRP is not activated.
656   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
657   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
658   * @note   New option bytes configuration will be taken into account in two cases:
659   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
660   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
661   * @param  WRPArea specifies the area to be configured.
662   *         This parameter can be one of the following values:
663   *            @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
664   *            @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
665   *            @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (*)
666   *            @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (*)
667   * @note   (*) availability depends on devices
668   * @param  WRPStartOffset specifies the start page of the write protected area.
669   *         This parameter can be page number between 0 and (max number of pages in the bank - 1).
670   * @param  WRDPEndOffset specifies the end page of the write protected area.
671   *         This parameter can be page number between WRPStartOffset and (max number of pages in the bank - 1).
672   * @retval HAL_Status
673   */
FLASH_OB_WRPConfig(uint32_t WRPArea,uint32_t WRPStartOffset,uint32_t WRDPEndOffset)674 static HAL_StatusTypeDef FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
675 {
676   HAL_StatusTypeDef status;
677 
678   /* Check the parameters */
679   assert_param(IS_OB_WRPAREA(WRPArea));
680   assert_param(IS_FLASH_PAGE(WRPStartOffset));
681   assert_param(IS_FLASH_PAGE(WRDPEndOffset));
682 
683   /* Wait for last operation to be completed */
684   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
685 
686   if (status == HAL_OK)
687   {
688     /* Configure the write protected area */
689     if (WRPArea == OB_WRPAREA_BANK1_AREAA)
690     {
691       FLASH->WRP1AR = ((WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos) | WRPStartOffset);
692     }
693     else if (WRPArea == OB_WRPAREA_BANK1_AREAB)
694     {
695       FLASH->WRP1BR = ((WRDPEndOffset << FLASH_WRP1BR_WRP1B_END_Pos) | WRPStartOffset);
696     }
697 #if defined (FLASH_OPTR_DBANK)
698     else if (WRPArea == OB_WRPAREA_BANK2_AREAA)
699     {
700       FLASH->WRP2AR = ((WRDPEndOffset << FLASH_WRP2AR_WRP2A_END_Pos) | WRPStartOffset);
701     }
702     else if (WRPArea == OB_WRPAREA_BANK2_AREAB)
703     {
704       FLASH->WRP2BR = ((WRDPEndOffset << FLASH_WRP2BR_WRP2B_END_Pos) | WRPStartOffset);
705     }
706 #endif
707     else
708     {
709       /* Nothing to do */
710     }
711 
712     /* Set OPTSTRT Bit */
713     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
714 
715     /* Wait for last operation to be completed */
716     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
717   }
718 
719   return status;
720 }
721 
722 /**
723   * @brief  Set the read protection level into Option Bytes.
724   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
725   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
726   * @note   New option bytes configuration will be taken into account in two cases:
727   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
728   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
729   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
730   *         to go back to level 1 or 0 !!!
731   * @param  RDPLevel specifies the read protection level.
732   *         This parameter can be one of the following values:
733   *            @arg OB_RDP_LEVEL_0: No protection
734   *            @arg OB_RDP_LEVEL_1: Memory Read protection
735   *            @arg OB_RDP_LEVEL_2: Full chip protection
736   *
737   * @retval HAL_Status
738   */
FLASH_OB_RDPConfig(uint32_t RDPLevel)739 static HAL_StatusTypeDef FLASH_OB_RDPConfig(uint32_t RDPLevel)
740 {
741   HAL_StatusTypeDef status;
742 
743   /* Check the parameters */
744   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
745 
746   /* Wait for last operation to be completed */
747   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
748 
749   if (status == HAL_OK)
750   {
751     /* Configure the RDP level in the option bytes register */
752     MODIFY_REG(FLASH->OPTR, FLASH_OPTR_RDP, RDPLevel);
753 
754     /* Set OPTSTRT Bit */
755     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
756 
757     /* Wait for last operation to be completed */
758     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
759   }
760 
761   return status;
762 }
763 
764 /**
765   * @brief  Program the FLASH User Option Bytes.
766   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
767   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
768   * @note   New option bytes configuration will be taken into account in two cases:
769   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
770   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
771   * @param  UserType The FLASH User Option Bytes to be modified.
772   *         This parameter can be a combination of @ref FLASH_OB_USER_Type.
773   * @param  UserConfig The selected User Option Bytes values:
774   *         This parameter can be a combination of @ref FLASH_OB_USER_BOR_LEVEL,
775   *         @ref FLASH_OB_USER_nRST_STOP, @ref FLASH_OB_USER_nRST_STANDBY ,
776   *         @ref FLASH_OB_USER_nRST_SHUTDOWN, @ref FLASH_OB_USER_IWDG_SW,
777   *         @ref FLASH_OB_USER_IWDG_STOP, @ref FLASH_OB_USER_IWDG_STANDBY,
778   *         @ref FLASH_OB_USER_WWDG_SW, @ref FLASH_OB_USER_WWDG_SW,
779   *         @ref FLASH_OB_USER_BFB2 (*), @ref FLASH_OB_USER_nBOOT1,
780   *         @ref FLASH_OB_USER_SRAM_PE, @ref FLASH_OB_USER_CCMSRAM_RST,
781   *         @ref FLASH_OB_USER_nSWBOOT0, @ref FLASH_OB_USER_nBOOT0,
782   *         @ref FLASH_OB_USER_NRST_MODE, @ref FLASH_OB_USER_INTERNAL_RESET_HOLDER
783   * @note   (*) availability depends on devices
784   * @retval HAL_Status
785   */
FLASH_OB_UserConfig(uint32_t UserType,uint32_t UserConfig)786 static HAL_StatusTypeDef FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
787 {
788   uint32_t optr_reg_val = 0;
789   uint32_t optr_reg_mask = 0;
790   HAL_StatusTypeDef status;
791 
792   /* Check the parameters */
793   assert_param(IS_OB_USER_TYPE(UserType));
794 
795   /* Wait for last operation to be completed */
796   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
797 
798   if (status == HAL_OK)
799   {
800 #if defined(FLASH_OPTR_PB4_PUPEN)
801     if ((UserType & OB_USER_PB4_PUPEN) != 0U)
802     {
803       /* PB4_PUPEN option byte should be modified */
804       assert_param(IS_OB_USER_PB4_PUPEN(UserConfig & FLASH_OPTR_PB4_PUPEN));
805 
806       /* Set value and mask for PB4_PUPEN option byte */
807       optr_reg_val |= (UserConfig & FLASH_OPTR_PB4_PUPEN);
808       optr_reg_mask |= FLASH_OPTR_PB4_PUPEN;
809     }
810 #endif /* FLASH_OPTR_PB4_PUPEN */
811 
812     if ((UserType & OB_USER_BOR_LEV) != 0U)
813     {
814       /* BOR level option byte should be modified */
815       assert_param(IS_OB_USER_BOR_LEVEL(UserConfig & FLASH_OPTR_BOR_LEV));
816 
817       /* Set value and mask for BOR level option byte */
818       optr_reg_val |= (UserConfig & FLASH_OPTR_BOR_LEV);
819       optr_reg_mask |= FLASH_OPTR_BOR_LEV;
820     }
821 
822     if ((UserType & OB_USER_nRST_STOP) != 0U)
823     {
824       /* nRST_STOP option byte should be modified */
825       assert_param(IS_OB_USER_STOP(UserConfig & FLASH_OPTR_nRST_STOP));
826 
827       /* Set value and mask for nRST_STOP option byte */
828       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STOP);
829       optr_reg_mask |= FLASH_OPTR_nRST_STOP;
830     }
831 
832     if ((UserType & OB_USER_nRST_STDBY) != 0U)
833     {
834       /* nRST_STDBY option byte should be modified */
835       assert_param(IS_OB_USER_STANDBY(UserConfig & FLASH_OPTR_nRST_STDBY));
836 
837       /* Set value and mask for nRST_STDBY option byte */
838       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_STDBY);
839       optr_reg_mask |= FLASH_OPTR_nRST_STDBY;
840     }
841 
842     if ((UserType & OB_USER_nRST_SHDW) != 0U)
843     {
844       /* nRST_SHDW option byte should be modified */
845       assert_param(IS_OB_USER_SHUTDOWN(UserConfig & FLASH_OPTR_nRST_SHDW));
846 
847       /* Set value and mask for nRST_SHDW option byte */
848       optr_reg_val |= (UserConfig & FLASH_OPTR_nRST_SHDW);
849       optr_reg_mask |= FLASH_OPTR_nRST_SHDW;
850     }
851 
852     if ((UserType & OB_USER_IWDG_SW) != 0U)
853     {
854       /* IWDG_SW option byte should be modified */
855       assert_param(IS_OB_USER_IWDG(UserConfig & FLASH_OPTR_IWDG_SW));
856 
857       /* Set value and mask for IWDG_SW option byte */
858       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_SW);
859       optr_reg_mask |= FLASH_OPTR_IWDG_SW;
860     }
861 
862     if ((UserType & OB_USER_IWDG_STOP) != 0U)
863     {
864       /* IWDG_STOP option byte should be modified */
865       assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTR_IWDG_STOP));
866 
867       /* Set value and mask for IWDG_STOP option byte */
868       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STOP);
869       optr_reg_mask |= FLASH_OPTR_IWDG_STOP;
870     }
871 
872     if ((UserType & OB_USER_IWDG_STDBY) != 0U)
873     {
874       /* IWDG_STDBY option byte should be modified */
875       assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTR_IWDG_STDBY));
876 
877       /* Set value and mask for IWDG_STDBY option byte */
878       optr_reg_val |= (UserConfig & FLASH_OPTR_IWDG_STDBY);
879       optr_reg_mask |= FLASH_OPTR_IWDG_STDBY;
880     }
881 
882     if ((UserType & OB_USER_WWDG_SW) != 0U)
883     {
884       /* WWDG_SW option byte should be modified */
885       assert_param(IS_OB_USER_WWDG(UserConfig & FLASH_OPTR_WWDG_SW));
886 
887       /* Set value and mask for WWDG_SW option byte */
888       optr_reg_val |= (UserConfig & FLASH_OPTR_WWDG_SW);
889       optr_reg_mask |= FLASH_OPTR_WWDG_SW;
890     }
891 
892 #if defined (FLASH_OPTR_BFB2)
893     if ((UserType & OB_USER_BFB2) != 0U)
894     {
895       /* BFB2 option byte should be modified */
896       assert_param(IS_OB_USER_BFB2(UserConfig & FLASH_OPTR_BFB2));
897 
898       /* Set value and mask for BFB2 option byte */
899       optr_reg_val |= (UserConfig & FLASH_OPTR_BFB2);
900       optr_reg_mask |= FLASH_OPTR_BFB2;
901     }
902 #endif
903 
904     if ((UserType & OB_USER_nBOOT1) != 0U)
905     {
906       /* nBOOT1 option byte should be modified */
907       assert_param(IS_OB_USER_BOOT1(UserConfig & FLASH_OPTR_nBOOT1));
908 
909       /* Set value and mask for nBOOT1 option byte */
910       optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT1);
911       optr_reg_mask |= FLASH_OPTR_nBOOT1;
912     }
913 
914     if ((UserType & OB_USER_SRAM_PE) != 0U)
915     {
916       /* SRAM_PE option byte should be modified */
917       assert_param(IS_OB_USER_SRAM_PARITY(UserConfig & FLASH_OPTR_SRAM_PE));
918 
919       /* Set value and mask for SRAM_PE option byte */
920       optr_reg_val |= (UserConfig & FLASH_OPTR_SRAM_PE);
921       optr_reg_mask |= FLASH_OPTR_SRAM_PE;
922     }
923     if ((UserType & OB_USER_CCMSRAM_RST) != 0U)
924     {
925       /* CCMSRAM_RST option byte should be modified */
926       assert_param(IS_OB_USER_CCMSRAM_RST(UserConfig & FLASH_OPTR_CCMSRAM_RST));
927 
928       /* Set value and mask for CCMSRAM_RST option byte */
929       optr_reg_val |= (UserConfig & FLASH_OPTR_CCMSRAM_RST);
930       optr_reg_mask |= FLASH_OPTR_CCMSRAM_RST;
931     }
932     if ((UserType & OB_USER_nSWBOOT0) != 0U)
933     {
934       /* nSWBOOT0 option byte should be modified */
935       assert_param(IS_OB_USER_SWBOOT0(UserConfig & FLASH_OPTR_nSWBOOT0));
936 
937       /* Set value and mask for nSWBOOT0 option byte */
938       optr_reg_val |= (UserConfig & FLASH_OPTR_nSWBOOT0);
939       optr_reg_mask |= FLASH_OPTR_nSWBOOT0;
940     }
941 
942     if ((UserType & OB_USER_nBOOT0) != 0U)
943     {
944       /* nBOOT0 option byte should be modified */
945       assert_param(IS_OB_USER_BOOT0(UserConfig & FLASH_OPTR_nBOOT0));
946 
947       /* Set value and mask for nBOOT0 option byte */
948       optr_reg_val |= (UserConfig & FLASH_OPTR_nBOOT0);
949       optr_reg_mask |= FLASH_OPTR_nBOOT0;
950     }
951 
952     if ((UserType & OB_USER_NRST_MODE) != 0U)
953     {
954       /* Reset Configuration option byte should be modified */
955       assert_param(IS_OB_USER_NRST_MODE(UserConfig & FLASH_OPTR_NRST_MODE));
956 
957       /* Set value and mask for Reset Configuration option byte */
958       optr_reg_val |= (UserConfig & FLASH_OPTR_NRST_MODE);
959       optr_reg_mask |= FLASH_OPTR_NRST_MODE;
960     }
961 
962     if ((UserType & OB_USER_IRHEN) != 0U)
963     {
964       /* IRH option byte should be modified */
965       assert_param(IS_OB_USER_IRHEN(UserConfig & FLASH_OPTR_IRHEN));
966 
967       /* Set value and mask for IRH option byte */
968       optr_reg_val |= (UserConfig & FLASH_OPTR_IRHEN);
969       optr_reg_mask |= FLASH_OPTR_IRHEN;
970     }
971 
972     /* Configure the option bytes register */
973     MODIFY_REG(FLASH->OPTR, optr_reg_mask, optr_reg_val);
974 
975     /* Set OPTSTRT Bit */
976     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
977 
978     /* Wait for last operation to be completed */
979     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
980   }
981 
982   return status;
983 }
984 
985 /**
986   * @brief  Configure the Proprietary code readout protection area into Option Bytes.
987   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
988   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
989   * @note   New option bytes configuration will be taken into account in two cases:
990   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
991   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
992   * @param  PCROPConfig specifies the configuration (Bank to be configured and PCROP_RDP option).
993   *         This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2 (*)
994   *         with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE.
995   * @note   (*) availability depends on devices
996   * @param  PCROPStartAddr specifies the start address of the Proprietary code readout protection.
997   *         This parameter can be an address between begin and end of the bank.
998   * @param  PCROPEndAddr specifies the end address of the Proprietary code readout protection.
999   *         This parameter can be an address between PCROPStartAddr and end of the bank.
1000   * @retval HAL_Status
1001   */
FLASH_OB_PCROPConfig(uint32_t PCROPConfig,uint32_t PCROPStartAddr,uint32_t PCROPEndAddr)1002 static HAL_StatusTypeDef FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr)
1003 {
1004   HAL_StatusTypeDef status;
1005   uint32_t reg_value;
1006   uint32_t bank1_addr;
1007 #if defined (FLASH_OPTR_DBANK)
1008   uint32_t bank2_addr;
1009 #endif
1010 
1011   /* Check the parameters */
1012   assert_param(IS_FLASH_BANK_EXCLUSIVE(PCROPConfig & FLASH_BANK_BOTH));
1013   assert_param(IS_OB_PCROP_RDP(PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
1014   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPStartAddr));
1015   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROPEndAddr));
1016 
1017   /* Wait for last operation to be completed */
1018   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1019 
1020   if (status == HAL_OK)
1021   {
1022 #if defined (FLASH_OPTR_DBANK)
1023     /* Get the information about the bank swapping */
1024     if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
1025     {
1026       bank1_addr = FLASH_BASE;
1027       bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
1028     }
1029     else
1030     {
1031       bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
1032       bank2_addr = FLASH_BASE;
1033     }
1034 #else
1035     bank1_addr = FLASH_BASE;
1036 #endif
1037 
1038 #if defined (FLASH_OPTR_DBANK)
1039     if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
1040     {
1041       /* Configure the Proprietary code readout protection */
1042       if ((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
1043       {
1044         reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);
1045         MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
1046 
1047         reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);
1048         MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
1049       }
1050       else if ((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
1051       {
1052         reg_value = ((PCROPStartAddr - FLASH_BASE) >> 4);
1053         MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
1054 
1055         reg_value = ((PCROPEndAddr - FLASH_BASE) >> 4);
1056         MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
1057       }
1058       else
1059       {
1060         /* Nothing to do */
1061       }
1062     }
1063     else
1064 #endif
1065     {
1066       /* Configure the Proprietary code readout protection */
1067       if ((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_1)
1068       {
1069         reg_value = ((PCROPStartAddr - bank1_addr) >> 3);
1070         MODIFY_REG(FLASH->PCROP1SR, FLASH_PCROP1SR_PCROP1_STRT, reg_value);
1071 
1072         reg_value = ((PCROPEndAddr - bank1_addr) >> 3);
1073         MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP1_END, reg_value);
1074       }
1075 #if defined (FLASH_OPTR_DBANK)
1076       else if ((PCROPConfig & FLASH_BANK_BOTH) == FLASH_BANK_2)
1077       {
1078         reg_value = ((PCROPStartAddr - bank2_addr) >> 3);
1079         MODIFY_REG(FLASH->PCROP2SR, FLASH_PCROP2SR_PCROP2_STRT, reg_value);
1080 
1081         reg_value = ((PCROPEndAddr - bank2_addr) >> 3);
1082         MODIFY_REG(FLASH->PCROP2ER, FLASH_PCROP2ER_PCROP2_END, reg_value);
1083       }
1084 #endif
1085       else
1086       {
1087         /* Nothing to do */
1088       }
1089     }
1090 
1091     MODIFY_REG(FLASH->PCROP1ER, FLASH_PCROP1ER_PCROP_RDP, (PCROPConfig & FLASH_PCROP1ER_PCROP_RDP));
1092 
1093     /* Set OPTSTRT Bit */
1094     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
1095 
1096     /* Wait for last operation to be completed */
1097     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1098   }
1099 
1100   return status;
1101 }
1102 
1103 /**
1104   * @brief  Configure the Securable memory area into Option Bytes.
1105   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
1106   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
1107   * @note   New option bytes configuration will be taken into account in two cases:
1108   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
1109   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
1110   * @param  SecBank specifies bank of securable memory area to be configured.
1111   *          This parameter can be one of the following values:
1112   *            @arg FLASH_BANK_1: Securable memory in Bank1 to be configured
1113   *            @arg FLASH_BANK_2: Securable memory in Bank2 to be configured (*)
1114   * @note   (*) availability depends on devices
1115   * @param  SecSize specifies the number of pages of the Securable memory area,
1116   *         starting from first page of the bank.
1117   *         This parameter can be page number between 0 and (max number of pages in the bank - 1)
1118   * @retval HAL Status
1119   */
FLASH_OB_SecMemConfig(uint32_t SecBank,uint32_t SecSize)1120 static HAL_StatusTypeDef FLASH_OB_SecMemConfig(uint32_t SecBank, uint32_t SecSize)
1121 {
1122   HAL_StatusTypeDef status;
1123 
1124   /* Check the parameters */
1125   assert_param(IS_FLASH_BANK_EXCLUSIVE(SecBank));
1126   assert_param(IS_OB_SECMEM_SIZE(SecSize));
1127 
1128   /* Wait for last operation to be completed */
1129   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1130 
1131   if (status == HAL_OK)
1132   {
1133     /* Configure the write protected area */
1134     if (SecBank == FLASH_BANK_1)
1135     {
1136       MODIFY_REG(FLASH->SEC1R, FLASH_SEC1R_SEC_SIZE1, SecSize);
1137     }
1138 #if defined (FLASH_OPTR_DBANK)
1139     else if (SecBank == FLASH_BANK_2)
1140     {
1141       MODIFY_REG(FLASH->SEC2R, FLASH_SEC2R_SEC_SIZE2, SecSize);
1142     }
1143     else
1144     {
1145       /* Nothing to do */
1146     }
1147 #endif
1148 
1149     /* Set OPTSTRT Bit */
1150     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
1151 
1152     /* Wait for last operation to be completed */
1153     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1154   }
1155 
1156   return status;
1157 }
1158 
1159 /**
1160   * @brief  Configure the Boot Lock into Option Bytes.
1161   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
1162   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
1163   * @note   New option bytes configuration will be taken into account in two cases:
1164   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
1165   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
1166   * @param  BootLockConfig specifies the boot lock configuration.
1167   *          This parameter can be one of the following values:
1168   *            @arg OB_BOOT_LOCK_ENABLE: Enable Boot Lock
1169   *            @arg OB_BOOT_LOCK_DISABLE: Disable Boot Lock
1170   *
1171   * @retval HAL_Status
1172   */
FLASH_OB_BootLockConfig(uint32_t BootLockConfig)1173 static HAL_StatusTypeDef FLASH_OB_BootLockConfig(uint32_t BootLockConfig)
1174 {
1175   HAL_StatusTypeDef status;
1176 
1177   /* Check the parameters */
1178   assert_param(IS_OB_BOOT_LOCK(BootLockConfig));
1179 
1180   /* Wait for last operation to be completed */
1181   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1182 
1183   if (status == HAL_OK)
1184   {
1185     MODIFY_REG(FLASH->SEC1R, FLASH_SEC1R_BOOT_LOCK, BootLockConfig);
1186 
1187     /* Set OPTSTRT Bit */
1188     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
1189 
1190     /* Wait for last operation to be completed */
1191     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
1192   }
1193 
1194   return status;
1195 }
1196 
1197 /**
1198   * @brief  Return the Securable memory area configuration into Option Bytes.
1199   * @param[in]  SecBank specifies the bank where securable memory area is located.
1200   *          This parameter can be one of the following values:
1201   *            @arg FLASH_BANK_1: Securable memory in Bank1
1202   *            @arg FLASH_BANK_2: Securable memory in Bank2 (*)
1203   * @note   (*) availability depends on devices
1204   * @param[out]  SecSize specifies the number of pages used in the securable
1205                  memory area of the bank.
1206   * @retval None
1207   */
FLASH_OB_GetSecMem(uint32_t SecBank,uint32_t * SecSize)1208 static void FLASH_OB_GetSecMem(uint32_t SecBank, uint32_t *SecSize)
1209 {
1210   /* Get the configuration of the securable memory area */
1211   if (SecBank == FLASH_BANK_1)
1212   {
1213     *SecSize = READ_BIT(FLASH->SEC1R, FLASH_SEC1R_SEC_SIZE1);
1214   }
1215 #if defined (FLASH_OPTR_DBANK)
1216   else if (SecBank == FLASH_BANK_2)
1217   {
1218     *SecSize = READ_BIT(FLASH->SEC2R, FLASH_SEC2R_SEC_SIZE2);
1219   }
1220   else
1221   {
1222     /* Nothing to do */
1223   }
1224 #endif
1225 }
1226 
1227 /**
1228   * @brief  Return the Boot Lock configuration into Option Byte.
1229   * @retval BootLockConfig.
1230   *         This return value can be one of the following values:
1231   *            @arg OB_BOOT_LOCK_ENABLE: Boot lock enabled
1232   *            @arg OB_BOOT_LOCK_DISABLE: Boot lock disabled
1233   */
FLASH_OB_GetBootLock(void)1234 static uint32_t FLASH_OB_GetBootLock(void)
1235 {
1236   return (READ_REG(FLASH->SEC1R) & FLASH_SEC1R_BOOT_LOCK);
1237 }
1238 
1239 /**
1240   * @brief  Return the Write Protection configuration into Option Bytes.
1241   * @param[in]  WRPArea specifies the area to be returned.
1242   *          This parameter can be one of the following values:
1243   *            @arg OB_WRPAREA_BANK1_AREAA: Flash Bank 1 Area A
1244   *            @arg OB_WRPAREA_BANK1_AREAB: Flash Bank 1 Area B
1245   *            @arg OB_WRPAREA_BANK2_AREAA: Flash Bank 2 Area A (don't apply to STM32G43x/STM32G44x devices)
1246   *            @arg OB_WRPAREA_BANK2_AREAB: Flash Bank 2 Area B (don't apply to STM32G43x/STM32G44x devices)
1247   * @param[out]  WRPStartOffset specifies the address where to copied the start page
1248   *              of the write protected area.
1249   * @param[out]  WRDPEndOffset specifies the address where to copied the end page of
1250   *              the write protected area.
1251   * @retval None
1252   */
FLASH_OB_GetWRP(uint32_t WRPArea,uint32_t * WRPStartOffset,uint32_t * WRDPEndOffset)1253 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
1254 {
1255   /* Get the configuration of the write protected area */
1256   if (WRPArea == OB_WRPAREA_BANK1_AREAA)
1257   {
1258     *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
1259     *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
1260   }
1261   else if (WRPArea == OB_WRPAREA_BANK1_AREAB)
1262   {
1263     *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
1264     *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
1265   }
1266 #if defined (FLASH_OPTR_DBANK)
1267   else if (WRPArea == OB_WRPAREA_BANK2_AREAA)
1268   {
1269     *WRPStartOffset = READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_STRT);
1270     *WRDPEndOffset = (READ_BIT(FLASH->WRP2AR, FLASH_WRP2AR_WRP2A_END) >> FLASH_WRP2AR_WRP2A_END_Pos);
1271   }
1272   else if (WRPArea == OB_WRPAREA_BANK2_AREAB)
1273   {
1274     *WRPStartOffset = READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_STRT);
1275     *WRDPEndOffset = (READ_BIT(FLASH->WRP2BR, FLASH_WRP2BR_WRP2B_END) >> FLASH_WRP2BR_WRP2B_END_Pos);
1276   }
1277 #endif
1278   else
1279   {
1280     /* Nothing to do */
1281   }
1282 }
1283 
1284 /**
1285   * @brief  Return the FLASH Read Protection level into Option Bytes.
1286   * @retval RDP_Level
1287   *         This return value can be one of the following values:
1288   *            @arg OB_RDP_LEVEL_0: No protection
1289   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
1290   *            @arg OB_RDP_LEVEL_2: Full chip protection
1291   */
FLASH_OB_GetRDP(void)1292 static uint32_t FLASH_OB_GetRDP(void)
1293 {
1294   uint32_t rdp_level = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
1295 
1296   if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
1297   {
1298     return (OB_RDP_LEVEL_1);
1299   }
1300   else
1301   {
1302     return rdp_level;
1303   }
1304 }
1305 
1306 /**
1307   * @brief  Return the FLASH User Option Byte value.
1308   * @retval OB_user_config
1309   *         This return value is a combination of @ref FLASH_OB_USER_BOR_LEVEL,
1310   *         @ref FLASH_OB_USER_nRST_STOP, @ref FLASH_OB_USER_nRST_STANDBY,
1311   *         @ref FLASH_OB_USER_nRST_SHUTDOWN, @ref FLASH_OB_USER_IWDG_SW,
1312   *         @ref FLASH_OB_USER_IWDG_STOP, @ref FLASH_OB_USER_IWDG_STANDBY,
1313   *         @ref FLASH_OB_USER_WWDG_SW, @ref FLASH_OB_USER_WWDG_SW,
1314   *         @ref FLASH_OB_USER_BFB2 (*), @ref FLASH_OB_USER_DBANK (*),
1315   *         @ref FLASH_OB_USER_nBOOT1, @ref FLASH_OB_USER_SRAM_PE,
1316   *         @ref FLASH_OB_USER_CCMSRAM_RST, @ref OB_USER_nSWBOOT0,@ref FLASH_OB_USER_nBOOT0,
1317   *         @ref FLASH_OB_USER_NRST_MODE, @ref FLASH_OB_USER_INTERNAL_RESET_HOLDER
1318   * @note  (*) availability depends on devices
1319   */
FLASH_OB_GetUser(void)1320 static uint32_t FLASH_OB_GetUser(void)
1321 {
1322   uint32_t user_config = READ_REG(FLASH->OPTR);
1323   CLEAR_BIT(user_config, FLASH_OPTR_RDP);
1324 
1325   return user_config;
1326 }
1327 
1328 /**
1329   * @brief  Return the FLASH PCROP configuration into Option Bytes.
1330   * @param[in,out] PCROPConfig specifies the configuration (Bank to be configured and PCROP_RDP option).
1331   *        This parameter must be a combination of FLASH_BANK_1 or FLASH_BANK_2
1332   *        with OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE.
1333   * @param[out] PCROPStartAddr specifies the address where to copied the start address
1334   *        of the Proprietary code readout protection.
1335   * @param[out] PCROPEndAddr specifies the address where to copied the end address of
1336   *        the Proprietary code readout protection.
1337   * @retval None
1338   */
FLASH_OB_GetPCROP(uint32_t * PCROPConfig,uint32_t * PCROPStartAddr,uint32_t * PCROPEndAddr)1339 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr)
1340 {
1341   uint32_t reg_value;
1342   uint32_t bank1_addr;
1343 #if defined (FLASH_OPTR_DBANK)
1344   uint32_t bank2_addr;
1345 
1346   /* Get the information about the bank swapping */
1347   if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0U)
1348   {
1349     bank1_addr = FLASH_BASE;
1350     bank2_addr = FLASH_BASE + FLASH_BANK_SIZE;
1351   }
1352   else
1353   {
1354     bank1_addr = FLASH_BASE + FLASH_BANK_SIZE;
1355     bank2_addr = FLASH_BASE;
1356   }
1357 #else
1358   bank1_addr = FLASH_BASE;
1359 #endif
1360 
1361 #if defined (FLASH_OPTR_DBANK)
1362   if (READ_BIT(FLASH->OPTR, FLASH_OPTR_DBANK) == 0U)
1363   {
1364     if (((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
1365     {
1366       reg_value       = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
1367       *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;
1368 
1369       reg_value     = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
1370       *PCROPEndAddr = (reg_value << 4) + FLASH_BASE;
1371     }
1372     else if (((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
1373     {
1374       reg_value       = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
1375       *PCROPStartAddr = (reg_value << 4) + FLASH_BASE;
1376 
1377       reg_value     = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
1378       *PCROPEndAddr = (reg_value << 4) + FLASH_BASE;
1379     }
1380     else
1381     {
1382       /* Nothing to do */
1383     }
1384   }
1385   else
1386 #endif
1387   {
1388     if (((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_1)
1389     {
1390       reg_value       = (READ_REG(FLASH->PCROP1SR) & FLASH_PCROP1SR_PCROP1_STRT);
1391       *PCROPStartAddr = (reg_value << 3) + bank1_addr;
1392 
1393       reg_value     = (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP1_END);
1394       *PCROPEndAddr = (reg_value << 3) + bank1_addr;
1395     }
1396 #if defined (FLASH_OPTR_DBANK)
1397     else if (((*PCROPConfig) & FLASH_BANK_BOTH) == FLASH_BANK_2)
1398     {
1399       reg_value       = (READ_REG(FLASH->PCROP2SR) & FLASH_PCROP2SR_PCROP2_STRT);
1400       *PCROPStartAddr = (reg_value << 3) + bank2_addr;
1401 
1402       reg_value     = (READ_REG(FLASH->PCROP2ER) & FLASH_PCROP2ER_PCROP2_END);
1403       *PCROPEndAddr = (reg_value << 3) + bank2_addr;
1404     }
1405 #endif
1406     else
1407     {
1408       /* Nothing to do */
1409     }
1410   }
1411 
1412   *PCROPConfig |= (READ_REG(FLASH->PCROP1ER) & FLASH_PCROP1ER_PCROP_RDP);
1413 }
1414 /**
1415   * @}
1416   */
1417 
1418 /**
1419   * @}
1420   */
1421 
1422 #endif /* HAL_FLASH_MODULE_ENABLED */
1423 
1424 /**
1425   * @}
1426   */
1427 
1428 /**
1429   * @}
1430   */
1431 
1432