1 /**
2   ******************************************************************************
3   * @file    stm32wlxx_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   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2020 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21  @verbatim
22  ==============================================================================
23                    ##### Flash Extended features #####
24   ==============================================================================
25 
26   [..] Comparing to other previous devices, the FLASH interface for STM32WLxx
27        devices contains the following additional features
28 
29        (+) Capacity up to 256kB with single bank architecture supporting read-while-write
30            capability (RWW)
31        (+) Single bank memory organization
32        (+) PCROP protection
33        (+) WRP protection
34        (+) CPU2 Security area
35        (+) Program Erase Suspend feature
36 
37                         ##### How to use this driver #####
38  ==============================================================================
39   [..] This driver provides functions to configure and program the FLASH memory
40        of all STM32WLxx devices. It includes
41       (#) Flash Memory Erase functions:
42            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
43                 HAL_FLASH_Lock() functions
44            (++) Erase function: Erase page, erase all sectors
45            (++) There are two modes of erase :
46              (+++) Polling Mode using HAL_FLASHEx_Erase()
47              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
48 
49       (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
50         (++) Set/Reset the write protection (per 4 KByte)
51         (++) Set the Read protection Level
52         (++) Program the user Option Bytes
53         (++) Configure the PCROP protection (per 2 KByte)
54         (++) Configure the IPCC Buffer start Address
55         (++) Configure the CPU2 boot region and reset vector start Address
56         (++) Configure the Flash and SRAM2 secure area
57 
58       (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
59         (++) Get the value of a write protection area
60         (++) Know if the read protection is activated
61         (++) Get the value of the user Option Bytes
62         (++) Get the value of a PCROP area
63         (++) Get the IPCC Buffer start Address
64         (++) Get the CPU2 boot region and reset vector start Address
65         (++) Get the Flash and SRAM2 secure area
66 
67       (#) Flash Suspend, Allow functions:
68            (++) Suspend or Allow new program or erase operation request using HAL_FLASHEx_SuspendOperation() and
69                 HAL_FLASHEx_AllowOperation() functions
70 
71       (#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck().
72           and modify this setting (for flash loader purpose e.g.) using
73           HAL_FLASHEx_ForceFlashEmpty().
74 
75       (#) Enable, Disable CPU2 debug access using HAL_FLASHEx_EnableC2Debug() or
76           HAL_FLASHEx_DisableC2Debug()
77 
78       (#) Enable Secure Hide Protection area access using HAL_FLASHEx_EnableSecHideProtection()
79          (++) Enable Secure Hide Protection area access done by hardware on a system reset
80 
81       (#) Privilege mode configuration function: Use HAL_FLASHEx_ConfigPrivMode()
82         (++) FLASH register can be protected against non-privilege accesses
83 
84       (#) Get the privilege mode configuration function: Use HAL_FLASHEx_GetPrivMode()
85         (++) Returns if the FLASH registers are protected against non-privilege accesses
86 
87  @endverbatim
88   ******************************************************************************
89   */
90 
91 /* Includes ------------------------------------------------------------------*/
92 #include "stm32wlxx_hal.h"
93 
94 /** @addtogroup STM32WLxx_HAL_Driver
95   * @{
96   */
97 
98 /** @defgroup FLASHEx FLASHEx
99   * @brief FLASH Extended HAL module driver
100   * @{
101   */
102 
103 #ifdef HAL_FLASH_MODULE_ENABLED
104 
105 /* Private typedef -----------------------------------------------------------*/
106 /* Private define ------------------------------------------------------------*/
107 /* Private macro -------------------------------------------------------------*/
108 /* Private variables ---------------------------------------------------------*/
109 /* Private function prototypes -----------------------------------------------*/
110 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
111  * @{
112  */
113 static void              FLASH_MassErase(void);
114 static void              FLASH_AcknowledgePageErase(void);
115 static void              FLASH_FlushCaches(void);
116 static void              FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
117 static void              FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
118 static void              FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr);
119 static void              FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr);
120 #if defined(DUAL_CORE)
121 static void              FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr);
122 static void              FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam);
123 #endif /* DUAL_CORE */
124 static void              FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
125 static uint32_t          FLASH_OB_GetRDP(void);
126 static uint32_t          FLASH_OB_GetUser(void);
127 static void              FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr, uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr);
128 #if defined(DUAL_CORE)
129 static uint32_t          FLASH_OB_GetIPCCBufferAddr(void);
130 static void              FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *HideProtectionStartAddr, uint32_t *SecureSRAM2StartAddr, uint32_t *SecureSRAM1StartAddr, uint32_t *SecureMode);
131 static void              FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion);
132 #endif /* DUAL_CORE */
133 static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void);
134 #if defined(DUAL_CORE)
135 static uint32_t          FLASH_OB_GetSUBGHZSPISecureAccess(void);
136 static uint32_t          FLASH_OB_GetC2DebugAccessMode(void);
137 static void              FLASH_OB_ConfigSecureMode(uint32_t SecureMode, uint32_t *Reg, uint32_t Bit, uint32_t ValueEnable);
138 static uint32_t          FLASH_OB_GetSecureMode(uint32_t Reg, uint32_t Bit, uint32_t ValueEnable, uint32_t ValueDisable);
139 #endif /* DUAL_CORE */
140 /**
141   * @}
142   */
143 
144 /* Exported functions -------------------------------------------------------*/
145 /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
146   * @{
147   */
148 
149 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
150  *  @brief   Extended IO operation functions
151  *
152 @verbatim
153  ===============================================================================
154                 ##### Extended programming operation functions #####
155  ===============================================================================
156     [..]
157     This subsection provides a set of functions allowing to manage the Extended FLASH
158     programming operations Operations.
159 
160 @endverbatim
161   * @{
162   */
163 /**
164   * @brief  Perform a mass erase or erase the specified FLASH memory pages.
165   * @note   Before any operation, it is possible to check there is no operation suspended
166   *         by call HAL_FLASHEx_IsOperationSuspended()
167   * @param[in]  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
168   *         contains the configuration information for the erasing.
169   * @param[out]  PageError Pointer to variable that contains the configuration
170   *         information on faulty page in case of error (0xFFFFFFFF means that all
171   *         the pages have been correctly erased)
172   * @retval HAL Status
173   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)174 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
175 {
176   HAL_StatusTypeDef status;
177   uint32_t index;
178 
179   /* Check the parameters */
180   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
181 
182   /* Process Locked */
183   __HAL_LOCK(&pFlash);
184 
185   /* Reset error code */
186   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
187 
188   /* Verify that next operation can be proceed */
189   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
190 
191   if (status == HAL_OK)
192   {
193     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
194     {
195       /* Mass erase to be done */
196       FLASH_MassErase();
197 
198       /* Wait for last operation to be completed */
199       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
200 
201       /* If operation is completed or interrupted, no need to clear the Mass Erase Bit */
202     }
203     else
204     {
205       /*Initialization of PageError variable*/
206       *PageError = 0xFFFFFFFFU;
207 
208       for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
209       {
210         /* Start erase page */
211         FLASH_PageErase(index);
212 
213         /* Wait for last operation to be completed */
214         status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
215 
216         if (status != HAL_OK)
217         {
218           /* In case of error, stop erase procedure and return the faulty address */
219           *PageError = index;
220           break;
221         }
222       }
223 
224       /* If operation is completed or interrupted, disable the Page Erase Bit */
225       FLASH_AcknowledgePageErase();
226     }
227 
228     /* Flush the caches to be sure of the data consistency */
229     FLASH_FlushCaches();
230   }
231 
232   /* Process Unlocked */
233   __HAL_UNLOCK(&pFlash);
234 
235   return status;
236 }
237 
238 /**
239   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
240   * @note   Before any operation, it is possible to check there is no operation suspended
241   *         by call HAL_FLASHEx_IsOperationSuspended()
242   * @param  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
243   *         contains the configuration information for the erasing.
244   * @retval HAL Status
245   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)246 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
247 {
248   HAL_StatusTypeDef status;
249 
250   /* Check the parameters */
251   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
252 
253   /* Process Locked */
254   __HAL_LOCK(&pFlash);
255 
256   /* Reset error code */
257   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
258 
259   /* save procedure for interrupt treatment */
260   pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
261 
262   /* Verify that next operation can be proceed */
263   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
264 
265   if (status != HAL_OK)
266   {
267     /* Process Unlocked */
268     __HAL_UNLOCK(&pFlash);
269   }
270   else
271   {
272     /* Enable End of Operation and Error interrupts */
273     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
274 
275     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
276     {
277       /* Set Page to 0 for Interrupt callback management */
278       pFlash.Page = 0;
279 
280       /* Proceed to Mass Erase */
281       FLASH_MassErase();
282     }
283     else
284     {
285       /* Erase by page to be done */
286       pFlash.NbPagesToErase = pEraseInit->NbPages;
287       pFlash.Page = pEraseInit->Page;
288 
289       /*Erase 1st page and wait for IT */
290       FLASH_PageErase(pEraseInit->Page);
291     }
292   }
293 
294   /* return status */
295   return status;
296 }
297 
298 /**
299   * @brief  Program Option bytes.
300   * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
301   *         contains the configuration information for the programming.
302   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
303   *         cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
304   * @note   New option bytes configuration will be taken into account only
305   *         - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
306   *         - a Power On Reset
307   *         - an exit from Standby or Shutdown mode.
308   * @retval HAL Status
309   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)310 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
311 {
312   uint32_t optr;
313   HAL_StatusTypeDef status;
314 
315   /* Check the parameters */
316   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
317 
318   /* Process Locked */
319   __HAL_LOCK(&pFlash);
320 
321   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
322 
323   /* Write protection configuration */
324   if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
325   {
326     /* Configure of Write protection on the selected area */
327     FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
328   }
329 
330   /* Option register */
331   if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
332   {
333     /* Fully modify OPTR register with RDP & user data */
334     FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, pOBInit->RDPLevel);
335   }
336   else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
337   {
338     /* Only modify RDP so get current user data */
339     optr = FLASH_OB_GetUser();
340 
341     /* Remove BOR LEVEL User Type*/
342     optr &= ~OB_USER_BOR_LEV;
343 
344     FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
345   }
346   else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
347   {
348     /* Only modify user so get current RDP level */
349     optr = FLASH_OB_GetRDP();
350     FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, optr);
351   }
352   else
353   {
354     /* Do Nothing */
355   }
356 
357   /* PCROP Configuration */
358   if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
359   {
360     /* Check the parameters */
361     assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig));
362 
363     if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0U)
364     {
365       /* Configure the Zone 1A Proprietary code readout protection */
366       FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr);
367     }
368 
369     if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0U)
370     {
371       /* Configure the Zone 1B Proprietary code readout protection */
372       FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr);
373     }
374   }
375 
376 #if defined(DUAL_CORE)
377   /*  Secure mode and CPU2 Boot Vector */
378   if ((pOBInit->OptionType & (OPTIONBYTE_SECURE_MODE | OPTIONBYTE_C2_BOOT_VECT | OPTIONBYTE_C2_DEBUG_ACCESS | OPTIONBYTE_SUBGHZSPI_SECURE_ACCESS)) != 0U)
379   {
380     /* Set the secure flash, SRAM memory start address, CPU2 boot reset vector or CPU2 debug access */
381     FLASH_OB_SecureConfig(pOBInit);
382   }
383 
384   /* IPCC mailbox data buffer address */
385   if ((pOBInit->OptionType & OPTIONBYTE_IPCC_BUF_ADDR) != 0U)
386   {
387     /* Configure the IPCC data buffer address */
388     FLASH_OB_IPCCBufferAddrConfig(pOBInit->IPCCdataBufAddr);
389   }
390 #endif /* DUAL_CORE */
391 
392   /* Proceed the OB Write Operation */
393   status = FLASH_OB_ProceedWriteOperation();
394 
395   /* Process Unlocked */
396   __HAL_UNLOCK(&pFlash);
397 
398   /* return status */
399   return status;
400 }
401 
402 /**
403   * @brief  Get the Option bytes configuration.
404   * @note   warning: this API only read flash register, it does not reflect any
405   *         change that would have been programmed between previous Option byte
406   *         loading and current call.
407   * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
408   *                  configuration information. The fields pOBInit->WRPArea and
409   *                  pOBInit->PCROPConfig should indicate which area is requested
410   *                  for the WRP and PCROP.
411   * @retval None
412   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)413 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
414 {
415   pOBInit->OptionType = OPTIONBYTE_ALL;
416 
417   if ((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))
418   {
419     /* Get write protection on the selected area */
420     FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
421   }
422 
423   /* Get Read protection level */
424   pOBInit->RDPLevel = FLASH_OB_GetRDP();
425 
426   /* Get the user option bytes */
427   pOBInit->UserConfig = FLASH_OB_GetUser();
428   pOBInit->UserType = OB_USER_ALL;
429 
430   /* Get the Zone 1A and 1B Proprietary code readout protection */
431   FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr), &(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr));
432   pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B);
433 
434 #if defined(DUAL_CORE)
435   /* Get the IPCC start Address */
436   pOBInit->IPCCdataBufAddr = FLASH_OB_GetIPCCBufferAddr();
437 
438   /* Get the Secure Flash start address, Secure Hide Protection start address Secure Backup SRAM2 start address, Secure non-Backup SRAM1 start address and the Security Mode, */
439   FLASH_OB_GetSecureMemoryConfig(&(pOBInit->SecureFlashStartAddr), &(pOBInit->HideProtectionStartAddr), &(pOBInit->SecureSRAM2StartAddr), &(pOBInit->SecureSRAM1StartAddr), &(pOBInit->SecureMode));
440 
441   /* Get the M0+ Secure Boot reset vector address and Secure Boot memory selection */
442   FLASH_OB_GetC2BootResetConfig(&(pOBInit->C2SecureBootVectAddr), &(pOBInit->C2BootRegion));
443 
444   /* Get the Sub-GHz radio SPI Secure Access */
445   pOBInit->SUBGHZSPISecureAccess = FLASH_OB_GetSUBGHZSPISecureAccess();
446 
447   /* Get the CPU2 Debug Access Mode */
448   pOBInit->C2DebugAccessMode = FLASH_OB_GetC2DebugAccessMode();
449 #endif /* DUAL_CORE */
450 }
451 
452 /**
453   * @brief  Flash Empty check
454   * @note   This API checks if first location in Flash is programmed or not.
455   *         This check is done once by Option Byte Loader.
456   * @retval Returned value can be one of the following values:
457   *         @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed
458   *         @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty
459   */
HAL_FLASHEx_FlashEmptyCheck(void)460 uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
461 {
462   return (READ_BIT(FLASH->ACR, FLASH_ACR_EMPTY));
463 }
464 
465 
466 /**
467   * @brief  Force Empty check value.
468   * @note   Allows to modify program empty check value in order to force this
469   *         information in Flash Interface, for all next reset that do not launch
470   *         Option Byte Loader.
471   * @param  FlashEmpty Specifies the empty check value
472   *          This parameter can be one of the following values:
473   *            @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed
474   *            @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty
475   * @retval None
476   */
HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)477 void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
478 {
479   assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));
480 
481   MODIFY_REG(FLASH->ACR, FLASH_ACR_EMPTY, FlashEmpty);
482 }
483 
484 /**
485   * @brief  Suspend new program or erase operation request.
486   * @note   Any new Flash program and erase operation on both CPU side will be suspended
487   *         until this bit and the same bit in Flash CPU2 access control register (FLASH_C2ACR) are
488   *         cleared. The PESD bit in both the Flash status register (FLASH_SR) and Flash
489   *         CPU2 status register (FLASH_C2SR) register will be set when at least one PES
490   *         bit in FLASH_ACR or FLASH_C2ACR is set.
491   * @retval None
492   */
HAL_FLASHEx_SuspendOperation(void)493 void HAL_FLASHEx_SuspendOperation(void)
494 {
495 #if defined(CORE_CM0PLUS)
496   SET_BIT(FLASH->C2ACR, FLASH_C2ACR_PES);
497 #else
498   SET_BIT(FLASH->ACR, FLASH_ACR_PES);
499 #endif
500 }
501 
502 /**
503   * @brief  Allow new program or erase operation request.
504   * @note   Any new Flash program and erase operation on both CPU side will be allowed
505   *         until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is
506   *         set. The PESD bit in both the Flash status register (FLASH_SR) and Flash
507   *         CPU2 status register (FLASH_C2SR) register will be clear when both PES
508   *         bit in FLASH_ACR or FLASH_C2ACR is cleared.
509   * @retval None
510   */
HAL_FLASHEx_AllowOperation(void)511 void HAL_FLASHEx_AllowOperation(void)
512 {
513 #if defined(CORE_CM0PLUS)
514   CLEAR_BIT(FLASH->C2ACR, FLASH_C2ACR_PES);
515 #else
516   CLEAR_BIT(FLASH->ACR, FLASH_ACR_PES);
517 #endif
518 }
519 
520 /**
521   * @brief  Check if new program or erase operation request from CPU1 or CPU2 is suspended
522   * @note   Any new Flash program and erase operation on both CPU side will be allowed
523   *         until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is
524   *         set. The PESD bit in both the Flash status register (FLASH_SR) and Flash
525   *         CPU2 status register (FLASH_C2SR) register will be cleared when both PES
526   *         bit in FLASH_ACR and FLASH_C2ACR are cleared.
527   * @retval Status
528   *          - 0 : No suspended flash operation
529   *          - 1 : Flash operation is suspended
530   */
HAL_FLASHEx_IsOperationSuspended(void)531 uint32_t HAL_FLASHEx_IsOperationSuspended(void)
532 {
533   uint32_t status = 0U;
534 
535 #if defined(CORE_CM0PLUS)
536   if (READ_BIT(FLASH->C2SR, FLASH_C2SR_PESD) == FLASH_C2SR_PESD)
537 #else
538   if (READ_BIT(FLASH->SR, FLASH_SR_PESD) == FLASH_SR_PESD)
539 #endif
540   {
541     status = 1U;
542   }
543 
544   return status;
545 }
546 
547 #if defined(DUAL_CORE)
548 /**
549   * @brief  Disable CPU2 debug access.
550   * @note   This feature can only be accessed by a secure privileged CPU2
551   *         When FLASH_SFR_HDPAD = 0 (Secure Hide Protection area enabled) the CPU2 software debug is disabled after a system reset.
552   *         When FLASH_SFR_HDPAD = 1 (Secure Hide Protection area disabled) the CPU2 software debug is enabled, after a system reset.
553   * @retval None
554   */
HAL_FLASHEx_DisableC2Debug(void)555 void HAL_FLASHEx_DisableC2Debug(void)
556 {
557   CLEAR_BIT(FLASH->ACR2, FLASH_ACR2_C2SWDBGEN);
558 }
559 
560 /**
561   * @brief  Enable CPU2 debug access (When also enabled in FLASH_SFR_DDS).
562   * @note   This feature can only be accessed by a secure privileged CPU2
563   *         When FLASH_SFR_HDPAD = 0 (Secure Hide Protection area enabled) the CPU2 software debug is disabled after a system reset.
564   *         When FLASH_SFR_HDPAD = 1 (Secure Hide Protection area disabled) the CPU2 software debug is enabled, after a system reset.
565   * @retval None
566   */
HAL_FLASHEx_EnableC2Debug(void)567 void HAL_FLASHEx_EnableC2Debug(void)
568 {
569   SET_BIT(FLASH->ACR2, FLASH_ACR2_C2SWDBGEN);
570 }
571 
572 /**
573   * @brief  Enable Secure Hide Protection Area access.
574   * @note   This feature can only be accessed by a secure privileged CPU2
575   *         This bit is set by software and will only be reset by hardware on a system reset.
576   * @retval None
577   */
HAL_FLASHEx_EnableSecHideProtection(void)578 void HAL_FLASHEx_EnableSecHideProtection(void)
579 {
580   SET_BIT(FLASH->ACR2, FLASH_ACR2_HDPADIS);
581 }
582 
583 /**
584   * @brief  Configuration of the privilege attribute.
585   * @note   This feature can only be accessed by a secure privileged CPU2
586   * @param  PrivMode indicate privilege mode configuration
587   *          This parameter can be one of the following values:
588   *            @arg @ref FLASH_PRIV_GRANTED Access to Flash registers is granted
589   *            @arg @ref FLASH_PRIV_DENIED Access to Flash registers is denied to non-privilege access
590   * @retval None
591   */
HAL_FLASHEx_ConfigPrivMode(uint32_t PrivMode)592 void HAL_FLASHEx_ConfigPrivMode(uint32_t PrivMode)
593 {
594   /* Check the parameters */
595   assert_param(IS_FLASH_CFGPRIVMODE(PrivMode));
596 
597   MODIFY_REG(FLASH->ACR2, FLASH_ACR2_PRIVMODE, PrivMode);
598 }
599 
600 /**
601   * @brief  Return the value of the privilege attribute.
602   * @note   This feature can only be accessed by a secure privileged CPU2
603   * @retval It indicates privilege mode configuration.
604   *          This return value can be one of the following values:
605   *            @arg @ref FLASH_PRIV_GRANTED Access to Flash registers is granted
606   *            @arg @ref FLASH_PRIV_DENIED Access to Flash registers is denied to non-privilege access
607   */
HAL_FLASHEx_GetPrivMode(void)608 uint32_t HAL_FLASHEx_GetPrivMode(void)
609 {
610   return (FLASH->ACR2 & FLASH_ACR2_PRIVMODE);
611 }
612 #endif /* DUAL_CORE */
613 
614 /**
615   * @}
616   */
617 
618 /**
619   * @}
620   */
621 
622 /* Private functions ---------------------------------------------------------*/
623 /** @addtogroup FLASHEx_Private_Functions
624   * @{
625   */
626 
627 /**
628   * @brief  Mass erase of FLASH memory.
629   * @retval None
630   */
FLASH_MassErase(void)631 static void FLASH_MassErase(void)
632 {
633   /* Set the Mass Erase Bit and start bit */
634 #ifdef CORE_CM0PLUS
635   SET_BIT(FLASH->C2CR, (FLASH_CR_MER | FLASH_CR_STRT));
636 #else
637   SET_BIT(FLASH->CR, (FLASH_CR_MER | FLASH_CR_STRT));
638 #endif
639 }
640 
641 /**
642   * @brief  Erase the specified FLASH memory page.
643   * @param  Page FLASH page to erase
644   *         This parameter must be a value between 0 and (max number of pages in Flash - 1)
645   * @retval None
646   */
FLASH_PageErase(uint32_t Page)647 void FLASH_PageErase(uint32_t Page)
648 {
649   /* Check the parameters */
650   assert_param(IS_FLASH_PAGE(Page));
651 
652   /* Proceed to erase the page */
653 #ifdef CORE_CM0PLUS
654   MODIFY_REG(FLASH->C2CR, FLASH_CR_PNB, ((Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER | FLASH_CR_STRT));
655 #else
656   MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER | FLASH_CR_STRT));
657 #endif
658 }
659 
660 /**
661   * @brief  Flush the instruction and data caches.
662   * @retval None
663   */
FLASH_FlushCaches(void)664 void FLASH_FlushCaches(void)
665 {
666   /* Flush instruction cache  */
667   if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) == 1U)
668   {
669     /* Disable instruction cache  */
670     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
671     /* Reset instruction cache */
672     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
673     /* Enable instruction cache */
674     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
675   }
676 
677 #ifdef CORE_CM0PLUS
678 #else
679   /* Flush data cache */
680   if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) == 1U)
681   {
682     /* Disable data cache  */
683     __HAL_FLASH_DATA_CACHE_DISABLE();
684     /* Reset data cache */
685     __HAL_FLASH_DATA_CACHE_RESET();
686     /* Enable data cache */
687     __HAL_FLASH_DATA_CACHE_ENABLE();
688   }
689 #endif
690 }
691 
692 /**
693   * @brief  Acknlowldge the page erase operation.
694   * @retval None
695   */
FLASH_AcknowledgePageErase(void)696 static void FLASH_AcknowledgePageErase(void)
697 {
698 #ifdef CORE_CM0PLUS
699   CLEAR_BIT(FLASH->C2CR, (FLASH_CR_PER | FLASH_CR_PNB));
700 #else
701   CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
702 #endif
703 }
704 
705 /**
706   * @brief  Configure the write protection of the desired pages.
707   * @note   When WRP is active in a zone, it cannot be erased or programmed.
708   *         Consequently, a software mass erase cannot be performed if one zone
709   *         is write-protected.
710   * @note   When the memory read protection level is selected (RDP level = 1),
711   *         it is not possible to program or erase Flash memory if the CPU debug
712   *         features are connected (JTAG or single wire) or boot code is being
713   *         executed from RAM or System flash, even if WRP is not activated.
714   * @note   To configure the WRP options, the option lock bit OPTLOCK must be
715   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
716   * @note   To validate the WRP options, the option bytes must be reloaded
717   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
718   * @param  WRPArea Specifies the area to be configured.
719   *          This parameter can be one of the following values:
720   *            @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A
721   *            @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B
722   * @param  WRPStartOffset Specifies the start page of the write protected area
723   *          This parameter can be page number between 0 and (max number of pages in the Flash - 1)
724   * @param  WRDPEndOffset Specifies the end page of the write protected area
725   *          This parameter can be page number between WRPStartOffset and (max number of pages in the Flash - 1)
726   * @retval None
727   */
FLASH_OB_WRPConfig(uint32_t WRPArea,uint32_t WRPStartOffset,uint32_t WRDPEndOffset)728 static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
729 {
730   /* Check the parameters */
731   assert_param(IS_OB_WRPAREA(WRPArea));
732   assert_param(IS_FLASH_PAGE(WRPStartOffset));
733   assert_param(IS_FLASH_PAGE(WRDPEndOffset));
734 
735   /* Configure the write protected area */
736   if (WRPArea == OB_WRPAREA_BANK1_AREAA)
737   {
738     MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),
739                (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos)));
740   }
741   else /* OB_WRPAREA_BANK1_AREAB */
742   {
743     MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),
744                (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos)));
745   }
746 }
747 
748 #if defined(DUAL_CORE) /* Comment duplicated for Document generation */
749 /**
750   * @brief  Set user & RDP configuration
751   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
752   *         to go back to level 1 or 0 !!!
753   * @param  UserType The FLASH User Option Bytes to be modified
754   *         This parameter can be a combination of all the following values:
755   *         @arg @ref OB_USER_BOR_LEV or @ref OB_USER_nRST_STOP or @ref OB_USER_nRST_STDBY or
756   *         @arg @ref OB_USER_nRST_SHDW or @ref OB_USER_IWDG_SW or @ref OB_USER_IWDG_STOP or
757   *         @arg @ref OB_USER_IWDG_STDBY or @ref OB_USER_WWDG_SW or @ref OB_USER_nBOOT1 or
758   *         @arg @ref OB_USER_SRAM2_PE or @ref OB_USER_SRAM_RST or @ref OB_USER_nSWBOOT0 or
759   *         @arg @ref OB_USER_nBOOT0 or @ref OB_USER_BOOT_LOCK or @ref OB_USER_BOOT_LOCK or @ref OB_USER_ALL
760   * @param  UserConfig The FLASH User Option Bytes values.
761   *         This parameter can be a combination of all the following values:
762   *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
763   *         @arg @ref OB_STOP_RST or @ref OB_STOP_NORST
764   *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
765   *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
766   *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
767   *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
768   *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
769   *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
770   *         @arg @ref OB_BOOT1_RESET or @ref OB_BOOT1_SET
771   *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
772   *         @arg @ref OB_SRAM_RST_ERASE or @ref OB_SRAM_RST_NOT_ERASE
773   *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
774   *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
775   *         @arg @ref OB_BOOT_LOCK_DISABLE or @ref OB_BOOT_LOCK_ENABLE
776   *         @arg @ref OB_C2BOOT_LOCK_DISABLE or @ref OB_C2BOOT_LOCK_ENABLE
777   * @param  RDPLevel: specifies the read protection level.
778   *         This parameter can be one of the following values:
779   *            @arg @ref OB_RDP_LEVEL_0 No protection
780   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
781   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
782   * @retval None
783   */
784 #else
785 /**
786   * @brief  Set user & RDP configuration
787   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
788   *         to go back to level 1 or 0 !!!
789   * @param  UserType The FLASH User Option Bytes to be modified
790   *         This parameter can be a combination of all the following values:
791   *         @arg @ref OB_USER_BOR_LEV or @ref OB_USER_nRST_STOP or @ref OB_USER_nRST_STDBY or
792   *         @arg @ref OB_USER_nRST_SHDW or @ref OB_USER_IWDG_SW or @ref OB_USER_IWDG_STOP or
793   *         @arg @ref OB_USER_IWDG_STDBY or @ref OB_USER_WWDG_SW or @ref OB_USER_nBOOT1 or
794   *         @arg @ref OB_USER_SRAM2_PE or @ref OB_USER_SRAM_RST or @ref OB_USER_nSWBOOT0 or
795   *         @arg @ref OB_USER_nBOOT0 or @ref OB_USER_BOOT_LOCK or @ref OB_USER_BOOT_LOCK or @ref OB_USER_ALL
796   * @param  UserConfig The FLASH User Option Bytes values.
797   *         This parameter can be a combination of all the following values:
798   *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
799   *         @arg @ref OB_STOP_RST or @ref OB_STOP_NORST
800   *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
801   *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
802   *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
803   *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
804   *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
805   *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
806   *         @arg @ref OB_BOOT1_RESET or @ref OB_BOOT1_SET
807   *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
808   *         @arg @ref OB_SRAM_RST_ERASE or @ref OB_SRAM_RST_NOT_ERASE
809   *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
810   *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
811   *         @arg @ref OB_BOOT_LOCK_DISABLE or @ref OB_BOOT_LOCK_ENABLE
812   * @param  RDPLevel: specifies the read protection level.
813   *         This parameter can be one of the following values:
814   *            @arg @ref OB_RDP_LEVEL_0 No protection
815   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
816   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
817   * @retval None
818   */
819 #endif
FLASH_OB_OptrConfig(uint32_t UserType,uint32_t UserConfig,uint32_t RDPLevel)820 static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
821 {
822   uint32_t optr;
823 
824   /* Check the parameters */
825   assert_param(IS_OB_USER_TYPE(UserType));
826   assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
827   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
828 
829   /* Configure the RDP level in the option bytes register */
830   optr = FLASH->OPTR;
831   optr &= ~(UserType | FLASH_OPTR_RDP);
832   FLASH->OPTR = (optr | UserConfig | RDPLevel);
833 }
834 
835 /**
836   * @brief  Configure the Zone 1A Proprietary code readout protection of the desired addresses,
837   *         and erase configuration on RDP regression.
838   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
839   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
840   * @note   To validate the PCROP options, the option bytes must be reloaded
841   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
842   * @param  PCROPConfig: specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE)
843   *         on RDP level 1 regression.
844   * @param  PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection
845   *         This parameter can be an address between begin and end of the flash
846   * @param  PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection
847   *         This parameter can be an address between PCROP1AStartAddr and end of the flash
848   * @retval None
849   */
FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig,uint32_t PCROP1AStartAddr,uint32_t PCROP1AEndAddr)850 static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr)
851 {
852   uint32_t startoffset;
853   uint32_t endoffset;
854   uint32_t pcrop1aend;
855 
856   /* Check the parameters */
857   assert_param(IS_OB_PCROP_CONFIG(PCROPConfig));
858   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AStartAddr));
859   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AEndAddr));
860 
861   /* get pcrop 1A end register */
862   pcrop1aend = FLASH->PCROP1AER;
863 
864   /* Configure the Proprietary code readout protection offset */
865   if ((PCROPConfig & OB_PCROP_ZONE_A) != 0U)
866   {
867     /* Compute offset depending on pcrop granularity */
868     startoffset = ((PCROP1AStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
869     endoffset = ((PCROP1AEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
870 
871     /* Set Zone A start offset */
872     WRITE_REG(FLASH->PCROP1ASR, startoffset);
873 
874     /* Set Zone A end offset */
875     pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END;
876     pcrop1aend |= endoffset;
877   }
878 
879   /* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */
880   if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0U)
881   {
882     pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP;
883   }
884 
885   /* set 1A End register */
886   WRITE_REG(FLASH->PCROP1AER, pcrop1aend);
887 }
888 
889 /**
890   * @brief  Configure the Zone 1B Proprietary code readout protection of the desired addresses.
891   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
892   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
893   * @note   To validate the PCROP options, the option bytes must be reloaded
894   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
895   * @param  PCROP1BStartAddr Specifies the Zone 1B Start address of the Proprietary code readout protection
896   *         This parameter can be an address between begin and end of the flash
897   * @param  PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection
898   *         This parameter can be an address between PCROP1BStartAddr and end of the flash
899   * @retval None
900   */
FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr,uint32_t PCROP1BEndAddr)901 static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr)
902 {
903   uint32_t startoffset;
904   uint32_t endoffset;
905 
906   /* Check the parameters */
907   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BStartAddr));
908   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BEndAddr));
909 
910   /* Compute offset depending on pcrop granularity */
911   startoffset = ((PCROP1BStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
912   endoffset = ((PCROP1BEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
913 
914   /* Configure the Proprietary code readout protection start address */
915   WRITE_REG(FLASH->PCROP1BSR, startoffset);
916 
917   /* Configure the Proprietary code readout protection end address */
918   WRITE_REG(FLASH->PCROP1BER, endoffset);
919 }
920 
921 #if defined(DUAL_CORE)
922 /**
923   * @brief  Program the FLASH IPCC data buffer address.
924   * @note   To configure the extra user option bytes, the option lock bit OPTLOCK must
925   *         be cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
926   * @note   To validate the extra user option bytes, the option bytes must be reloaded
927   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
928   * @param  IPCCDataBufAddr IPCC data buffer start address area in SRAM1 or SRAM2
929   *         This parameter must be the double-word aligned
930   * @retval None
931   */
FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr)932 static void FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr)
933 {
934   assert_param(IS_OB_IPCC_BUF_ADDR(IPCCDataBufAddr));
935 
936   /* Configure the option bytes register */
937   WRITE_REG(FLASH->IPCCBR, (uint32_t)((IPCCDataBufAddr - SRAM1_BASE) >> 4));
938 }
939 
940 /**
941   * @brief  Configure the secure start address of the different memories,
942   *         the secure mode, the CPU2 Secure Boot reset vector and the CPU2 debug access
943   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
944   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
945   * @param  pOBParam Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
946   *         contains the configuration information for the programming
947   * @retval void
948   */
FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef * pOBParam)949 static void FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam)
950 {
951   uint32_t sfr_reg_val = READ_REG(FLASH->SFR);
952   uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR);
953 
954   if ((pOBParam->OptionType & OPTIONBYTE_SECURE_MODE) != 0U)
955   {
956     assert_param(IS_OB_SFSA_START_ADDR(pOBParam->SecureFlashStartAddr));
957     assert_param(IS_OB_SBRSA_START_ADDR(pOBParam->SecureSRAM2StartAddr));
958     assert_param(IS_OB_SNBRSA_START_ADDR(pOBParam->SecureSRAM1StartAddr));
959     assert_param(IS_OB_HDPSA_START_ADDR(pOBParam->HideProtectionStartAddr));
960     assert_param(IS_OB_SECURE_MODE(pOBParam->SecureMode));
961 
962     /* Configure SFR register content with start FLASH PAGE index to secure and start FLASH PAGE index for hide protection area */
963     MODIFY_REG(sfr_reg_val, (FLASH_SFR_SFSA | FLASH_SFR_HDPSA), \
964                ((((pOBParam->SecureFlashStartAddr - FLASH_BASE) / FLASH_PAGE_SIZE) << FLASH_SFR_SFSA_Pos) | \
965                 (((pOBParam->HideProtectionStartAddr - FLASH_BASE) / FLASH_PAGE_SIZE) << FLASH_SFR_HDPSA_Pos)));
966 
967     /* Configure SRRVR register */
968     MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRSA | FLASH_SRRVR_SNBRSA), \
969                (((((pOBParam->SecureSRAM2StartAddr - SRAM2_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_Pos)) | \
970                 ((((pOBParam->SecureSRAM1StartAddr - SRAM1_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SNBRSA_Pos))));
971 
972     /* If Full System Secure mode is requested, clear all the corresponding bit */
973     /* Else set the corresponding bit */
974     if (pOBParam->SecureMode == OB_SECURE_SYSTEM_AND_ALL_AREAS_ENABLE)
975     {
976       CLEAR_BIT(sfr_reg_val, (FLASH_SFR_FSD | FLASH_SFR_HDPAD));
977       CLEAR_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD));
978     }
979     else if (pOBParam->SecureMode == OB_SECURE_SYSTEM_AND_ALL_AREAS_DISABLE)
980     {
981       SET_BIT(sfr_reg_val, (FLASH_SFR_FSD | FLASH_SFR_HDPAD));
982       SET_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD));
983     }
984     else /* Enable Secure Area bit per bit */
985     {
986       /* Set Flash Area in secure if requested */
987       FLASH_OB_ConfigSecureMode(pOBParam->SecureMode, &sfr_reg_val, FLASH_SFR_FSD, OB_SECURE_SYSTEM_AND_FLASH_ENABLE);
988 
989       /* Set Hide Protection Area in secure if requested */
990       FLASH_OB_ConfigSecureMode(pOBParam->SecureMode, &sfr_reg_val, FLASH_SFR_HDPAD, OB_SECURE_HIDE_PROTECTION_ENABLE);
991 
992       /* Set SRAM1 Area in secure if requested */
993       FLASH_OB_ConfigSecureMode(pOBParam->SecureMode, &srrvr_reg_val, FLASH_SRRVR_NBRSD, OB_SECURE_SRAM1_ENABLE);
994 
995       /* Set SRAM2 Area in secure if requested */
996       FLASH_OB_ConfigSecureMode(pOBParam->SecureMode, &srrvr_reg_val, FLASH_SRRVR_BRSD, OB_SECURE_SRAM2_ENABLE);
997     }
998   }
999 
1000   /* Boot vector */
1001   if ((pOBParam->OptionType & OPTIONBYTE_C2_BOOT_VECT) != 0U)
1002   {
1003     /* Check the parameters */
1004     assert_param(IS_OB_BOOT_VECTOR_ADDR(pOBParam->C2SecureBootVectAddr));
1005     assert_param(IS_OB_BOOT_REGION(pOBParam->C2BootRegion));
1006 
1007     /* Set the boot vector */
1008     if (pOBParam->C2BootRegion == OB_C2_BOOT_FROM_FLASH)
1009     {
1010       MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT), (((pOBParam->C2SecureBootVectAddr - FLASH_BASE) >> 2) | pOBParam->C2BootRegion));
1011     }
1012     else
1013     {
1014       MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT), (((pOBParam->C2SecureBootVectAddr - SRAM1_BASE) >> 2) | pOBParam->C2BootRegion));
1015     }
1016   }
1017 
1018   /* CPU2 Debug Access */
1019   if ((pOBParam->OptionType & OPTIONBYTE_C2_DEBUG_ACCESS) != 0U)
1020   {
1021     /* Check the parameters */
1022     assert_param(IS_OB_C2_DEBUG_MODE(pOBParam->C2DebugAccessMode));
1023 
1024     /* Set the CPU2 Debug Access */
1025     MODIFY_REG(sfr_reg_val, FLASH_SFR_DDS, (uint32_t)pOBParam->C2DebugAccessMode);
1026   }
1027 
1028   /* Sub-GHz radio SPI Access */
1029   if ((pOBParam->OptionType & OPTIONBYTE_SUBGHZSPI_SECURE_ACCESS) != 0U)
1030   {
1031     /* Check the parameters */
1032     assert_param(IS_OB_SUBGHZSPI_SECURE_ACCESS(pOBParam->SUBGHZSPISecureAccess));
1033 
1034     /* Set the Sub-GHz radio SPI Secure Access */
1035     MODIFY_REG(sfr_reg_val, FLASH_SFR_SUBGHZSPISD, (uint32_t)pOBParam->SUBGHZSPISecureAccess);
1036   }
1037 
1038   /* Update Flash registers */
1039   WRITE_REG(FLASH->SFR, sfr_reg_val);
1040   WRITE_REG(FLASH->SRRVR, srrvr_reg_val);
1041 }
1042 #endif /* DUAL_CORE */
1043 
1044 /**
1045   * @brief  Return the FLASH Write Protection Option Bytes value.
1046   * @param[in]   WRPArea Specifies the area to be returned.
1047   *              This parameter can be one of the following values:
1048   *              @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A
1049   *              @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B
1050   * @param[out]  WRPStartOffset Specifies the address where to copied the start page
1051   *                             of the write protected area
1052   * @param[out]  WRDPEndOffset Specifies the address where to copied the end page of
1053   *                            the write protected area
1054   * @retval None
1055   */
FLASH_OB_GetWRP(uint32_t WRPArea,uint32_t * WRPStartOffset,uint32_t * WRDPEndOffset)1056 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
1057 {
1058   /* Check the parameters */
1059   assert_param(IS_OB_WRPAREA(WRPArea));
1060 
1061   /* Get the configuration of the write protected area */
1062   if (WRPArea == OB_WRPAREA_BANK1_AREAA)
1063   {
1064     *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
1065     *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
1066   }
1067   else /* OB_WRPAREA_BANK1_AREAB */
1068   {
1069     *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
1070     *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
1071   }
1072 }
1073 
1074 /**
1075   * @brief  Return the FLASH Read Protection level.
1076   * @retval FLASH ReadOut Protection Status:
1077   *         This return value can be one of the following values:
1078   *            @arg @ref OB_RDP_LEVEL_0 No protection
1079   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
1080   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
1081   */
FLASH_OB_GetRDP(void)1082 static uint32_t FLASH_OB_GetRDP(void)
1083 {
1084   uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
1085 
1086   if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
1087   {
1088     return (OB_RDP_LEVEL_1);
1089   }
1090   else
1091   {
1092     return rdplvl;
1093   }
1094 }
1095 
1096 #if defined(DUAL_CORE) /* Comment duplicated for Document generation */
1097 /**
1098   * @brief  Return the FLASH User Option Byte value.
1099   * @retval This return value can be a combination of all the following values:
1100   *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
1101   *         @arg @ref OB_STOP_RST or @ref OB_STOP_RST
1102   *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
1103   *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
1104   *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
1105   *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
1106   *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
1107   *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
1108   *         @arg @ref OB_BOOT1_RESET or @ref OB_BOOT1_SET
1109   *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
1110   *         @arg @ref OB_SRAM_RST_ERASE or @ref OB_SRAM_RST_NOT_ERASE
1111   *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
1112   *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
1113   *         @arg @ref OB_BOOT_LOCK_DISABLE or @ref OB_BOOT_LOCK_ENABLE
1114   *         @arg @ref OB_C2BOOT_LOCK_DISABLE or @ref OB_C2BOOT_LOCK_ENABLE
1115   */
1116 #else
1117 /**
1118   * @brief  Return the FLASH User Option Byte value.
1119   * @retval This return value can be a combination of all the following values:
1120   *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
1121   *         @arg @ref OB_STOP_RST or @ref OB_STOP_RST
1122   *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
1123   *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
1124   *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
1125   *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
1126   *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
1127   *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
1128   *         @arg @ref OB_BOOT1_RESET or @ref OB_BOOT1_SET
1129   *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
1130   *         @arg @ref OB_SRAM_RST_ERASE or @ref OB_SRAM_RST_NOT_ERASE
1131   *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
1132   *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
1133   *         @arg @ref OB_BOOT_LOCK_DISABLE or @ref OB_BOOT_LOCK_ENABLE
1134   */
1135 #endif
FLASH_OB_GetUser(void)1136 static uint32_t FLASH_OB_GetUser(void)
1137 {
1138   uint32_t user_config = (READ_REG(FLASH->OPTR) & OB_USER_ALL);
1139   CLEAR_BIT(user_config, (FLASH_OPTR_RDP | FLASH_OPTR_ESE));
1140 
1141   return user_config;
1142 }
1143 
1144 /**
1145   * @brief  Return the FLASH Write Protection Option Bytes value.
1146   * @param PCROPConfig [out] Specifies the address where to copied the configuration of PCROP_RDP option
1147   * @param PCROP1AStartAddr [out] Specifies the address where to copied the start address
1148   *                         of the Zone 1A Proprietary code readout protection
1149   * @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of
1150   *                       the Zone 1A Proprietary code readout protection
1151   * @param PCROP1BStartAddr [out] Specifies the address where to copied the start address
1152   *                         of the Zone 1B Proprietary code readout protection
1153   * @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of
1154   *                       the Zone 1B Proprietary code readout protection
1155   * @retval None
1156   */
FLASH_OB_GetPCROP(uint32_t * PCROPConfig,uint32_t * PCROP1AStartAddr,uint32_t * PCROP1AEndAddr,uint32_t * PCROP1BStartAddr,uint32_t * PCROP1BEndAddr)1157 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr, uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr)
1158 {
1159   uint32_t pcrop;
1160 
1161   pcrop             = (READ_BIT(FLASH->PCROP1BSR, FLASH_PCROP1BSR_PCROP1B_STRT));
1162   *PCROP1BStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
1163 
1164   pcrop             = (READ_BIT(FLASH->PCROP1BER, FLASH_PCROP1BER_PCROP1B_END));
1165   *PCROP1BEndAddr   = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
1166 
1167   pcrop             = (READ_BIT(FLASH->PCROP1ASR, FLASH_PCROP1ASR_PCROP1A_STRT));
1168   *PCROP1AStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
1169 
1170   pcrop             = (READ_BIT(FLASH->PCROP1AER, FLASH_PCROP1AER_PCROP1A_END));
1171   *PCROP1AEndAddr   = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
1172 
1173   *PCROPConfig      = (READ_REG(FLASH->PCROP1AER) & FLASH_PCROP1AER_PCROP_RDP);
1174 }
1175 
1176 #if defined(DUAL_CORE)
1177 /**
1178   * @brief  Return the FLASH IPCC data buffer base address Option Byte value.
1179   * @retval Returned value is the address where to copied the IPCC data buffer address.
1180   *           Value return between Min_Data = 0x0 and Max_Data = 0x3FFF
1181   *           This value correspond to the first double-word of the IPCC mailbox data buffer area
1182   *           in SRAM starting from 0x20000000 (SRAM1 start address to SRAM2 end address).
1183   */
FLASH_OB_GetIPCCBufferAddr(void)1184 static uint32_t FLASH_OB_GetIPCCBufferAddr(void)
1185 {
1186   return (uint32_t)((READ_BIT(FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA) << 4) + SRAM1_BASE);
1187 }
1188 
1189 /**
1190   * @brief  Return the Secure Flash start address, Secure Hide Protection Area start address, Secure Backup SRAM2 start address,
1191   *                     Secure non-Backup SRAM1 start address and the SecureMode
1192   * @param  SecureFlashStartAddr  Specifies the address where to copied the Secure Flash start address
1193   * @param  HideProtectionStartAddr Specifies the address where to copied the Secure Hide Protection Area start address
1194   * @param  SecureSRAM2StartAddr  Specifies the address where to copied the Secure Backup SRAM2 start address
1195   * @param  SecureSRAM1StartAddr  Specifies the address where to copied the Secure non-Backup SRAM1 start address
1196   * @param  SecureMode            Specifies the Secure area enabled or disabled.
1197   *                               This return value can be one of the following values:
1198   *                               @arg @ref OB_SECURE_SYSTEM_AND_ALL_AREAS_DISABLE : All System Security disabled
1199   *                               @arg @ref OB_SECURE_SYSTEM_AND_FLASH_ENABLE : Flash Security enabled
1200   *                               @arg @ref OB_SECURE_HIDE_PROTECTION_ENABLE : Hide Protection Security enabled
1201   *                               @arg @ref OB_SECURE_SRAM1_ENABLE : SRAM1 Security enabled
1202   *                               @arg @ref OB_SECURE_SRAM2_ENABLE : SRAM2 Security enabled
1203   *                               @arg @ref OB_SECURE_SYSTEM_AND_FLASH_DISABLE : Flash Security disabled
1204   *                               @arg @ref OB_SECURE_HIDE_PROTECTION_DISABLE : Hide Protection Security disabled
1205   *                               @arg @ref OB_SECURE_SRAM1_DISABLE : SRAM1 Security disabled
1206   *                               @arg @ref OB_SECURE_SRAM2_DISABLE : SRAM2 Security disabled
1207   *                               @arg @ref OB_SECURE_SYSTEM_AND_ALL_AREAS_ENABLE : All System Security enabled
1208   * @retval None
1209   */
FLASH_OB_GetSecureMemoryConfig(uint32_t * SecureFlashStartAddr,uint32_t * HideProtectionStartAddr,uint32_t * SecureSRAM2StartAddr,uint32_t * SecureSRAM1StartAddr,uint32_t * SecureMode)1210 static void FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *HideProtectionStartAddr, uint32_t *SecureSRAM2StartAddr, uint32_t *SecureSRAM1StartAddr, uint32_t *SecureMode)
1211 {
1212   uint32_t sfr_reg_val = READ_REG(FLASH->SFR);
1213   uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR);
1214 
1215   /* Get Secure Flash start address */
1216   uint32_t user_config = (READ_BIT(sfr_reg_val, FLASH_SFR_SFSA) >> FLASH_SFR_SFSA_Pos);
1217 
1218   *SecureFlashStartAddr = ((user_config * FLASH_PAGE_SIZE) + FLASH_BASE);
1219 
1220   /* Get Hide Protection Area start address */
1221   user_config = (READ_BIT(sfr_reg_val, FLASH_SFR_HDPSA) >> FLASH_SFR_HDPSA_Pos);
1222 
1223   *HideProtectionStartAddr = ((user_config * FLASH_PAGE_SIZE) + FLASH_BASE);
1224 
1225   /* Get Secure SRAM2 start address */
1226   user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA) >> FLASH_SRRVR_SBRSA_Pos);
1227 
1228   *SecureSRAM2StartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2_BASE);
1229 
1230   /* Get Secure SRAM1 start address */
1231   user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SNBRSA) >> FLASH_SRRVR_SNBRSA_Pos);
1232 
1233   *SecureSRAM1StartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM1_BASE);
1234 
1235   /* Get Secure Area mode */
1236   *SecureMode = (FLASH_OB_GetSecureMode(sfr_reg_val, FLASH_SFR_FSD, OB_SECURE_SYSTEM_AND_FLASH_ENABLE, OB_SECURE_SYSTEM_AND_FLASH_DISABLE) | \
1237                  FLASH_OB_GetSecureMode(sfr_reg_val, FLASH_SFR_HDPAD, OB_SECURE_HIDE_PROTECTION_ENABLE, OB_SECURE_HIDE_PROTECTION_DISABLE) | \
1238                  FLASH_OB_GetSecureMode(srrvr_reg_val, FLASH_SRRVR_NBRSD, OB_SECURE_SRAM1_ENABLE, OB_SECURE_SRAM1_DISABLE)                 | \
1239                  FLASH_OB_GetSecureMode(srrvr_reg_val, FLASH_SRRVR_BRSD, OB_SECURE_SRAM2_ENABLE, OB_SECURE_SRAM2_DISABLE));
1240 }
1241 
1242 /**
1243   * @brief  Return the CPU2 Secure Boot reset vector address and the CPU2 Secure Boot Region
1244   * @param  C2BootResetVectAddr Specifies the address where to copied the CPU2 Secure Boot reset vector address
1245   * @param  C2BootResetRegion   Specifies the Secure Boot reset memory region
1246   * @retval None
1247   */
FLASH_OB_GetC2BootResetConfig(uint32_t * C2BootResetVectAddr,uint32_t * C2BootResetRegion)1248 static void FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion)
1249 {
1250   *C2BootResetRegion = (READ_BIT(FLASH->SRRVR, FLASH_SRRVR_C2OPT));
1251 
1252   if (*C2BootResetRegion == OB_C2_BOOT_FROM_FLASH)
1253   {
1254     *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + FLASH_BASE);
1255   }
1256   else
1257   {
1258     *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + SRAM1_BASE);
1259   }
1260 }
1261 
1262 /**
1263   * @brief  Return the Sub-GHz radio SPI Secure Access mode
1264   * @retval Returned value can be one of the following values:
1265   *           @arg @ref OB_SUBGHZSPI_SECURE_ACCESS_DISABLE : Sub-GHz radio SPI Secure access disabled
1266   *           @arg @ref OB_SUBGHZSPI_SECURE_ACCESS_ENABLE : Sub-GHz radio SPI Secure access enabled
1267   */
FLASH_OB_GetSUBGHZSPISecureAccess(void)1268 static uint32_t FLASH_OB_GetSUBGHZSPISecureAccess(void)
1269 {
1270   return (READ_BIT(FLASH->SFR, FLASH_SFR_SUBGHZSPISD));
1271 }
1272 
1273 /**
1274   * @brief  Return the CPU2 Debug Access mode
1275   * @retval Returned value can be one of the following values:
1276   *           @arg @ref OB_C2_DEBUG_ACCESS_DISABLE : CPU2 debug access disabled
1277   *           @arg @ref OB_C2_DEBUG_ACCESS_ENABLE : CPU2 debug access enabled
1278   */
FLASH_OB_GetC2DebugAccessMode(void)1279 static uint32_t FLASH_OB_GetC2DebugAccessMode(void)
1280 {
1281   return (READ_BIT(FLASH->SFR, FLASH_SFR_DDS));
1282 }
1283 #endif /* DUAL_CORE */
1284 
1285 /**
1286   * @brief  Proceed the OB Write Operation.
1287   * @retval HAL Status
1288   */
FLASH_OB_ProceedWriteOperation(void)1289 static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void)
1290 {
1291   HAL_StatusTypeDef status;
1292 
1293   /* Verify that next operation can be proceed */
1294   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1295 
1296   if (status == HAL_OK)
1297   {
1298     /* Set OPTSTRT Bit */
1299     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
1300 
1301     /* Wait for last operation to be completed */
1302     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1303   }
1304 
1305   return status;
1306 }
1307 
1308 #if defined(DUAL_CORE)
1309 /**
1310   * @brief Update the security bit in a FLASH register.
1311   * @param SecureMode Parameter to check as disabled or enabled
1312   * @param Reg FLASH register to update
1313   * @param Bit Bit in FLASH register to update
1314   * @param ValueEnable Constant to check in comparison with SecureMode as enabled
1315   * @retval None
1316   */
FLASH_OB_ConfigSecureMode(uint32_t SecureMode,uint32_t * Reg,uint32_t Bit,uint32_t ValueEnable)1317 static void FLASH_OB_ConfigSecureMode(uint32_t SecureMode, uint32_t *Reg, uint32_t Bit, uint32_t ValueEnable)
1318 {
1319   /* Check if SecureMode is requested */
1320   if ((SecureMode & ValueEnable) == ValueEnable)
1321   {
1322     CLEAR_BIT(*Reg, Bit);
1323   }
1324   else
1325   {
1326     SET_BIT(*Reg, Bit);
1327   }
1328 }
1329 
1330 /**
1331   * @brief Get the security bit in a FLASH register.
1332   * @param Reg FLASH register to check
1333   * @param Bit Bit in FLASH register to check
1334   * @param ValueEnable Constant to check in comparison with SecureMode as enabled
1335   * @param ValueDisable Constant to check in comparison with SecureMode as disabled
1336   * @retval SecureMode Specifies the Secure area enabled or disabled.
1337   *                               This return value can be one of the following values:
1338   *                               ValueEnable
1339   *                               ValueDisable
1340   *                               Null
1341   */
FLASH_OB_GetSecureMode(uint32_t Reg,uint32_t Bit,uint32_t ValueEnable,uint32_t ValueDisable)1342 static uint32_t FLASH_OB_GetSecureMode(uint32_t Reg, uint32_t Bit, uint32_t ValueEnable, uint32_t ValueDisable)
1343 {
1344   /* Return status of bit (set as enable, set as disable) */
1345   if (READ_BIT(Reg, Bit) == 0U)
1346   {
1347     return ValueEnable;
1348   }
1349   else
1350   {
1351     return ValueDisable;
1352   }
1353 }
1354 #endif /* DUAL_CORE */
1355 
1356 /**
1357   * @}
1358   */
1359 
1360 /**
1361   * @}
1362   */
1363 
1364 #endif /* HAL_FLASH_MODULE_ENABLED */
1365 
1366 /**
1367   * @}
1368   */
1369 
1370 /**
1371   * @}
1372   */
1373 
1374