1 /**
2   ******************************************************************************
3   * @file    stm32wbxx_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 STM32WBxx
16        devices contains the following additional features
17 
18        (+) Capacity up to 1 Mbyte with single bank architecture supporting read-while-write
19            capability (RWW)
20        (+) Single bank memory organization
21        (+) PCROP protection
22        (+) WRP protection
23        (+) CPU2 Security area
24        (+) Program Erase Suspend feature
25 
26                         ##### How to use this driver #####
27  ==============================================================================
28   [..] This driver provides functions to configure and program the FLASH memory
29        of all STM32WBxx devices. It includes
30       (#) Flash Memory Erase functions:
31            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
32                 HAL_FLASH_Lock() functions
33            (++) Erase function: Erase page, erase all sectors
34            (++) There are two modes of erase :
35              (+++) Polling Mode using HAL_FLASHEx_Erase()
36              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
37 
38       (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to :
39         (++) Set/Reset the write protection (per 4 KByte)
40         (++) Set the Read protection Level
41         (++) Program the user Option Bytes
42         (++) Configure the PCROP protection (per 2 KByte)
43         (++) Configure the IPCC Buffer start Address
44         (++) Configure the CPU2 boot region and reset vector start Address
45         (++) Configure the Flash and SRAM2 secure area
46 
47       (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to :
48         (++) Get the value of a write protection area
49         (++) Know if the read protection is activated
50         (++) Get the value of the user Option Bytes
51         (++) Get the value of a PCROP area
52         (++) Get the IPCC Buffer start Address
53         (++) Get the CPU2 boot region and reset vector start Address
54         (++) Get the Flash and SRAM2 secure area
55 
56       (#) Flash Suspend, Allow functions:
57            (++) Suspend or Allow new program or erase operation request using HAL_FLASHEx_SuspendOperation() and
58                 HAL_FLASHEx_AllowOperation() functions
59 
60       (#) Check is flash content is empty or not using HAL_FLASHEx_FlashEmptyCheck().
61           and modify this setting (for flash loader purpose e.g.) using
62           HAL_FLASHEx_ForceFlashEmpty().
63 
64  @endverbatim
65   ******************************************************************************
66   * @attention
67   *
68   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
69   * All rights reserved.</center></h2>
70   *
71   * This software component is licensed by ST under BSD 3-Clause license,
72   * the "License"; You may not use this file except in compliance with the
73   * License. You may obtain a copy of the License at:
74   *                        opensource.org/licenses/BSD-3-Clause
75   *
76   ******************************************************************************
77   */
78 
79 /* Includes ------------------------------------------------------------------*/
80 #include "stm32wbxx_hal.h"
81 
82 /** @addtogroup STM32WBxx_HAL_Driver
83   * @{
84   */
85 
86 /** @defgroup FLASHEx FLASHEx
87   * @brief FLASH Extended HAL module driver
88   * @{
89   */
90 
91 #ifdef HAL_FLASH_MODULE_ENABLED
92 
93 /* Private typedef -----------------------------------------------------------*/
94 /* Private define ------------------------------------------------------------*/
95 /* Private macro -------------------------------------------------------------*/
96 /* Private variables ---------------------------------------------------------*/
97 /* Private function prototypes -----------------------------------------------*/
98 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
99  * @{
100  */
101 static void              FLASH_MassErase(void);
102 static void              FLASH_AcknowledgePageErase(void);
103 static void              FLASH_FlushCaches(void);
104 static void              FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset);
105 static void              FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel);
106 static void              FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr);
107 static void              FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr);
108 static void              FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr);
109 static void              FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam);
110 static void              FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset);
111 static uint32_t          FLASH_OB_GetRDP(void);
112 static uint32_t          FLASH_OB_GetUser(void);
113 static void              FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr, uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr);
114 static uint32_t          FLASH_OB_GetIPCCBufferAddr(void);
115 static void              FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *SecureRAM2aStartAddr, uint32_t *SecureRAM2bStartAddr, uint32_t *SecureMode);
116 static void              FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion);
117 static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void);
118 /**
119   * @}
120   */
121 
122 /* Exported functions -------------------------------------------------------*/
123 /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
124   * @{
125   */
126 
127 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
128  *  @brief   Extended IO operation functions
129  *
130 @verbatim
131  ===============================================================================
132                 ##### Extended programming operation functions #####
133  ===============================================================================
134     [..]
135     This subsection provides a set of functions allowing to manage the Extended FLASH
136     programming operations Operations.
137 
138 @endverbatim
139   * @{
140   */
141 /**
142   * @brief  Perform a mass erase or erase the specified FLASH memory pages.
143   * @note   Before any operation, it is possible to check there is no operation suspended
144   *         by call HAL_FLASHEx_IsOperationSuspended()
145   * @param[in]  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
146   *         contains the configuration information for the erasing.
147   * @param[out]  PageError Pointer to variable that contains the configuration
148   *         information on faulty page in case of error (0xFFFFFFFF means that all
149   *         the pages have been correctly erased)
150   * @retval HAL Status
151   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * PageError)152 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageError)
153 {
154   HAL_StatusTypeDef status;
155   uint32_t index;
156 
157   /* Check the parameters */
158   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
159 
160   /* Process Locked */
161   __HAL_LOCK(&pFlash);
162 
163   /* Reset error code */
164   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
165 
166   /* Verify that next operation can be proceed */
167   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
168 
169   if (status == HAL_OK)
170   {
171     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
172     {
173       /* Mass erase to be done */
174       FLASH_MassErase();
175 
176       /* Wait for last operation to be completed */
177       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
178 
179       /* If operation is completed or interrupted, no need to clear the Mass Erase Bit */
180     }
181     else
182     {
183       /*Initialization of PageError variable*/
184       *PageError = 0xFFFFFFFFU;
185 
186       for (index = pEraseInit->Page; index < (pEraseInit->Page + pEraseInit->NbPages); index++)
187       {
188         /* Start erase page */
189         FLASH_PageErase(index);
190 
191         /* Wait for last operation to be completed */
192         status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
193 
194         if (status != HAL_OK)
195         {
196           /* In case of error, stop erase procedure and return the faulty address */
197           *PageError = index;
198           break;
199         }
200       }
201 
202       /* If operation is completed or interrupted, disable the Page Erase Bit */
203       FLASH_AcknowledgePageErase();
204     }
205 
206     /* Flush the caches to be sure of the data consistency */
207     FLASH_FlushCaches();
208   }
209 
210   /* Process Unlocked */
211   __HAL_UNLOCK(&pFlash);
212 
213   return status;
214 }
215 
216 /**
217   * @brief  Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
218   * @note   Before any operation, it is possible to check there is no operation suspended
219   *         by call HAL_FLASHEx_IsOperationSuspended()
220   * @param  pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
221   *         contains the configuration information for the erasing.
222   * @retval HAL Status
223   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)224 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
225 {
226   HAL_StatusTypeDef status;
227 
228   /* Check the parameters */
229   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
230 
231   /* Process Locked */
232   __HAL_LOCK(&pFlash);
233 
234   /* Reset error code */
235   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
236 
237   /* save procedure for interrupt treatment */
238   pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
239 
240   /* Verify that next operation can be proceed */
241   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
242 
243   if (status != HAL_OK)
244   {
245     /* Process Unlocked */
246     __HAL_UNLOCK(&pFlash);
247   }
248   else
249   {
250     /* Enable End of Operation and Error interrupts */
251     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
252 
253     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
254     {
255       /* Set Page to 0 for Interrupt callback managment */
256       pFlash.Page = 0;
257 
258       /* Proceed to Mass Erase */
259       FLASH_MassErase();
260     }
261     else
262     {
263       /* Erase by page to be done */
264       pFlash.NbPagesToErase = pEraseInit->NbPages;
265       pFlash.Page = pEraseInit->Page;
266 
267       /*Erase 1st page and wait for IT */
268       FLASH_PageErase(pEraseInit->Page);
269     }
270   }
271 
272   /* return status */
273   return status;
274 }
275 
276 /**
277   * @brief  Program Option bytes.
278   * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
279   *         contains the configuration information for the programming.
280   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
281   *         cleared with the call of @ref HAL_FLASH_OB_Unlock() function.
282   * @note   New option bytes configuration will be taken into account only
283   *         - after an option bytes launch through the call of @ref HAL_FLASH_OB_Launch()
284   *         - a Power On Reset
285   *         - an exit from Standby or Shutdown mode.
286   * @retval HAL Status
287   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)288 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
289 {
290   uint32_t optr;
291   HAL_StatusTypeDef status;
292 
293   /* Check the parameters */
294   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
295 
296   /* Process Locked */
297   __HAL_LOCK(&pFlash);
298 
299   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
300 
301   /* Write protection configuration */
302   if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
303   {
304     /* Configure of Write protection on the selected area */
305     FLASH_OB_WRPConfig(pOBInit->WRPArea, pOBInit->WRPStartOffset, pOBInit->WRPEndOffset);
306   }
307 
308   /* Option register */
309   if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
310   {
311     /* Fully modify OPTR register with RDP & user datas */
312     FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, pOBInit->RDPLevel);
313   }
314   else if ((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
315   {
316     /* Only modify RDP so get current user data */
317     optr = FLASH_OB_GetUser();
318 
319     /* Remove BOR LEVEL User Type*/
320     optr &= ~OB_USER_BOR_LEV;
321 
322     FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
323   }
324   else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
325   {
326     /* Only modify user so get current RDP level */
327     optr = FLASH_OB_GetRDP();
328     FLASH_OB_OptrConfig(pOBInit->UserType, pOBInit->UserConfig, optr);
329   }
330   else
331   {
332     /* Do Nothing */
333   }
334 
335   /* PCROP Configuration */
336   if ((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
337   {
338     /* Check the parameters */
339     assert_param(IS_OB_PCROP_CONFIG(pOBInit->PCROPConfig));
340 
341     if ((pOBInit->PCROPConfig & (OB_PCROP_ZONE_A | OB_PCROP_RDP_ERASE)) != 0U)
342     {
343       /* Configure the Zone 1A Proprietary code readout protection */
344       FLASH_OB_PCROP1AConfig(pOBInit->PCROPConfig, pOBInit->PCROP1AStartAddr, pOBInit->PCROP1AEndAddr);
345     }
346 
347     if ((pOBInit->PCROPConfig & OB_PCROP_ZONE_B) != 0U)
348     {
349       /* Configure the Zone 1B Proprietary code readout protection */
350       FLASH_OB_PCROP1BConfig(pOBInit->PCROP1BStartAddr, pOBInit->PCROP1BEndAddr);
351     }
352   }
353 
354   /*  Secure mode and CPU2 Boot Vector */
355   if ((pOBInit->OptionType & (OPTIONBYTE_SECURE_MODE | OPTIONBYTE_C2_BOOT_VECT)) != 0U)
356   {
357     /* Set the secure flash and SRAM memory start address */
358     FLASH_OB_SecureConfig(pOBInit);
359   }
360 
361   /* IPCC mailbox data buffer address */
362   if ((pOBInit->OptionType & OPTIONBYTE_IPCC_BUF_ADDR) != 0U)
363   {
364     /* Configure the IPCC data buffer address */
365     FLASH_OB_IPCCBufferAddrConfig(pOBInit->IPCCdataBufAddr);
366   }
367 
368   /* Proceed the OB Write Operation */
369   status = FLASH_OB_ProceedWriteOperation();
370 
371   /* Process Unlocked */
372   __HAL_UNLOCK(&pFlash);
373 
374   /* return status */
375   return status;
376 }
377 
378 /**
379   * @brief  Get the Option bytes configuration.
380   * @note   warning: this API only read flash register, it does not reflect any
381   *         change that would have been programmed between previous Option byte
382   *         loading and current call.
383   * @param  pOBInit Pointer to an @ref FLASH_OBProgramInitTypeDef structure that contains the
384   *                  configuration information. The fields pOBInit->WRPArea and
385   *                  pOBInit->PCROPConfig should indicate which area is requested
386   *                  for the WRP and PCROP.
387   * @retval None
388   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)389 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
390 {
391   pOBInit->OptionType = OPTIONBYTE_ALL;
392 
393   if ((pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAA) || (pOBInit->WRPArea == OB_WRPAREA_BANK1_AREAB))
394   {
395     /* Get write protection on the selected area */
396     FLASH_OB_GetWRP(pOBInit->WRPArea, &(pOBInit->WRPStartOffset), &(pOBInit->WRPEndOffset));
397   }
398 
399   /* Get Read protection level */
400   pOBInit->RDPLevel = FLASH_OB_GetRDP();
401 
402   /* Get the user option bytes */
403   pOBInit->UserConfig = FLASH_OB_GetUser();
404   pOBInit->UserType = OB_USER_ALL;
405 
406   /* Get the Zone 1A and 1B Proprietary code readout protection */
407   FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROP1AStartAddr), &(pOBInit->PCROP1AEndAddr), &(pOBInit->PCROP1BStartAddr), &(pOBInit->PCROP1BEndAddr));
408   pOBInit->PCROPConfig |= (OB_PCROP_ZONE_A | OB_PCROP_ZONE_B);
409 
410   /* Get the IPCC start Address */
411   pOBInit->IPCCdataBufAddr = FLASH_OB_GetIPCCBufferAddr();
412 
413   /* Get the Secure Flash start address, Secure Backup RAM2a start address, Secure non-Backup RAM2b start address and the Security Mode, */
414   FLASH_OB_GetSecureMemoryConfig(&(pOBInit->SecureFlashStartAddr), &(pOBInit->SecureRAM2aStartAddr), &(pOBInit->SecureRAM2bStartAddr), &(pOBInit->SecureMode));
415 
416   /* Get the M0+ Secure Boot reset vector and Secure Boot memory selection */
417   FLASH_OB_GetC2BootResetConfig(&(pOBInit->C2SecureBootVectAddr), &(pOBInit->C2BootRegion));
418 }
419 
420 /**
421   * @brief  Flash Empty check
422   * @note   This API checks if first location in Flash is programmed or not.
423   *         This check is done once by Option Byte Loader.
424   * @retval Returned value can be one of the following values:
425   *         @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed
426   *         @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty
427   */
HAL_FLASHEx_FlashEmptyCheck(void)428 uint32_t HAL_FLASHEx_FlashEmptyCheck(void)
429 {
430   return (READ_BIT(FLASH->ACR, FLASH_ACR_EMPTY));
431 }
432 
433 
434 /**
435   * @brief  Force Empty check value.
436   * @note   Allows to modify program empty check value in order to force this
437   *         information in Flash Interface, for all next reset that do not launch
438   *         Option Byte Loader.
439   * @param  FlashEmpty Specifies the empty check value
440   *          This parameter can be one of the following values:
441   *            @arg @ref FLASH_PROG_NOT_EMPTY 1st location in Flash is programmed
442   *            @arg @ref FLASH_PROG_EMPTY 1st location in Flash is empty
443   * @retval None
444   */
HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)445 void HAL_FLASHEx_ForceFlashEmpty(uint32_t FlashEmpty)
446 {
447   assert_param(IS_FLASH_EMPTY_CHECK(FlashEmpty));
448 
449   MODIFY_REG(FLASH->ACR, FLASH_ACR_EMPTY, FlashEmpty);
450 }
451 
452 /**
453   * @brief  Suspend new program or erase operation request.
454   * @note   Any new Flash program and erase operation on both CPU side will be suspended
455   *         until this bit and the same bit in Flash CPU2 access control register (FLASH_C2ACR) are
456   *         cleared. The PESD bit in both the Flash status register (FLASH_SR) and Flash
457   *         CPU2 status register (FLASH_C2SR) register will be set when at least one PES
458   *         bit in FLASH_ACR or FLASH_C2ACR is set.
459   * @retval None
460   */
HAL_FLASHEx_SuspendOperation(void)461 void HAL_FLASHEx_SuspendOperation(void)
462 {
463   SET_BIT(FLASH->ACR, FLASH_ACR_PES);
464 }
465 
466 /**
467   * @brief  Allow new program or erase operation request.
468   * @note   Any new Flash program and erase operation on both CPU side will be allowed
469   *         until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is
470   *         set. The PESD bit in both the Flash status register (FLASH_SR) and Flash
471   *         CPU2 status register (FLASH_C2SR) register will be clear when both PES
472   *         bit in FLASH_ACR or FLASH_C2ACR is cleared.
473   * @retval None
474   */
HAL_FLASHEx_AllowOperation(void)475 void HAL_FLASHEx_AllowOperation(void)
476 {
477   CLEAR_BIT(FLASH->ACR, FLASH_ACR_PES);
478 }
479 
480 /**
481   * @brief  Check if new program or erase operation request from CPU1 or CPU2 is suspended
482   * @note   Any new Flash program and erase operation on both CPU side will be allowed
483   *         until one of this bit or the same bit in Flash CPU2 access control register (FLASH_C2ACR) is
484   *         set. The PESD bit in both the Flash status register (FLASH_SR) and Flash
485   *         CPU2 status register (FLASH_C2SR) register will be cleared when both PES
486   *         bit in FLASH_ACR and FLASH_C2ACR are cleared.
487   * @retval Status
488   *          - 0 : No suspended flash operation
489   *          - 1 : Flash operation is suspended
490   */
HAL_FLASHEx_IsOperationSuspended(void)491 uint32_t HAL_FLASHEx_IsOperationSuspended(void)
492 {
493   uint32_t status = 0U;
494 
495   if (READ_BIT(FLASH->SR, FLASH_SR_PESD) == FLASH_SR_PESD)
496   {
497     status = 1U;
498   }
499 
500   return status;
501 }
502 
503 /**
504   * @}
505   */
506 
507 /**
508   * @}
509   */
510 
511 /* Private functions ---------------------------------------------------------*/
512 /** @addtogroup FLASHEx_Private_Functions
513   * @{
514   */
515 
516 /**
517   * @brief  Mass erase of FLASH memory.
518   * @retval None
519   */
FLASH_MassErase(void)520 static void FLASH_MassErase(void)
521 {
522   /* Set the Mass Erase Bit and start bit */
523   SET_BIT(FLASH->CR, (FLASH_CR_MER | FLASH_CR_STRT));
524 }
525 
526 /**
527   * @brief  Erase the specified FLASH memory page.
528   * @param  Page FLASH page to erase
529   *         This parameter must be a value between 0 and (max number of pages in Flash - 1)
530   * @retval None
531   */
FLASH_PageErase(uint32_t Page)532 void FLASH_PageErase(uint32_t Page)
533 {
534   /* Check the parameters */
535   assert_param(IS_FLASH_PAGE(Page));
536 
537   /* Proceed to erase the page */
538   MODIFY_REG(FLASH->CR, FLASH_CR_PNB, ((Page << FLASH_CR_PNB_Pos) | FLASH_CR_PER | FLASH_CR_STRT));
539 }
540 
541 /**
542   * @brief  Flush the instruction and data caches.
543   * @retval None
544   */
FLASH_FlushCaches(void)545 static void FLASH_FlushCaches(void)
546 {
547   /* Flush instruction cache  */
548   if (READ_BIT(FLASH->ACR, FLASH_ACR_ICEN) == FLASH_ACR_ICEN)
549   {
550     /* Disable instruction cache  */
551     __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
552     /* Reset instruction cache */
553     __HAL_FLASH_INSTRUCTION_CACHE_RESET();
554     /* Enable instruction cache */
555     __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
556   }
557 
558   /* Flush data cache */
559   if (READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) == FLASH_ACR_DCEN)
560   {
561     /* Disable data cache  */
562     __HAL_FLASH_DATA_CACHE_DISABLE();
563     /* Reset data cache */
564     __HAL_FLASH_DATA_CACHE_RESET();
565     /* Enable data cache */
566     __HAL_FLASH_DATA_CACHE_ENABLE();
567   }
568 }
569 
570 /**
571   * @brief  Acknlowldge the page erase operation.
572   * @retval None
573   */
FLASH_AcknowledgePageErase(void)574 static void FLASH_AcknowledgePageErase(void)
575 {
576   CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB));
577 }
578 
579 /**
580   * @brief  Configure the write protection of the desired pages.
581   * @note   When WRP is active in a zone, it cannot be erased or programmed.
582   *         Consequently, a software mass erase cannot be performed if one zone
583   *         is write-protected.
584   * @note   When the memory read protection level is selected (RDP level = 1),
585   *         it is not possible to program or erase Flash memory if the CPU debug
586   *         features are connected (JTAG or single wire) or boot code is being
587   *         executed from RAM or System flash, even if WRP is not activated.
588   * @note   To configure the WRP options, the option lock bit OPTLOCK must be
589   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
590   * @note   To validate the WRP options, the option bytes must be reloaded
591   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
592   * @param  WRPArea Specifies the area to be configured.
593   *          This parameter can be one of the following values:
594   *            @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A
595   *            @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B
596   * @param  WRPStartOffset Specifies the start page of the write protected area
597   *          This parameter can be page number between 0 and (max number of pages in the Flash - 1)
598   * @param  WRDPEndOffset Specifies the end page of the write protected area
599   *          This parameter can be page number between WRPStartOffset and (max number of pages in the Flash - 1)
600   * @retval None
601   */
FLASH_OB_WRPConfig(uint32_t WRPArea,uint32_t WRPStartOffset,uint32_t WRDPEndOffset)602 static void FLASH_OB_WRPConfig(uint32_t WRPArea, uint32_t WRPStartOffset, uint32_t WRDPEndOffset)
603 {
604   /* Check the parameters */
605   assert_param(IS_OB_WRPAREA(WRPArea));
606   assert_param(IS_FLASH_PAGE(WRPStartOffset));
607   assert_param(IS_FLASH_PAGE(WRDPEndOffset));
608 
609   /* Configure the write protected area */
610   if (WRPArea == OB_WRPAREA_BANK1_AREAA)
611   {
612     MODIFY_REG(FLASH->WRP1AR, (FLASH_WRP1AR_WRP1A_STRT | FLASH_WRP1AR_WRP1A_END),
613                (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos)));
614   }
615   else /* OB_WRPAREA_BANK1_AREAB */
616   {
617     MODIFY_REG(FLASH->WRP1BR, (FLASH_WRP1BR_WRP1B_STRT | FLASH_WRP1BR_WRP1B_END),
618                (WRPStartOffset | (WRDPEndOffset << FLASH_WRP1AR_WRP1A_END_Pos)));
619   }
620 }
621 
622 /**
623   * @brief  Set user & RDP configuration
624   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
625   *         to go back to level 1 or 0 !!!
626   * @param  UserType The FLASH User Option Bytes to be modified
627   *         This parameter can be a combination of all the following values:
628   *         @arg @ref OB_USER_BOR_LEV or @ref OB_USER_nRST_STOP or @ref OB_USER_nRST_STDBY or
629   *         @arg @ref OB_USER_nRST_SHDW or @ref OB_USER_IWDG_SW or @ref OB_USER_IWDG_STOP or
630   *         @arg @ref OB_USER_IWDG_STDBY or @ref OB_USER_WWDG_SW or @ref OB_USER_nBOOT1 or
631   *         @arg @ref OB_USER_SRAM2PE or @ref OB_USER_SRAM2RST or @ref OB_USER_nSWBOOT0 or
632   *         @arg @ref OB_USER_nBOOT0 or @ref OB_USER_AGC_TRIM or @ref OB_USER_ALL
633   * @param  UserConfig The FLASH User Option Bytes values.
634   *         This parameter can be a combination of all the following values:
635   *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
636   *         @arg @ref OB_STOP_RST or @ref OB_STOP_NORST
637   *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
638   *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
639   *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
640   *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
641   *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
642   *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
643   *         @arg @ref OB_BOOT1_SRAM or @ref OB_BOOT1_SYSTEM
644   *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
645   *         @arg @ref OB_SRAM2_RST_ERASE or @ref OB_SRAM2_RST_NOT_ERASE
646   *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
647   *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
648   *         @arg @ref OB_AGC_TRIM_0 or @ref OB_AGC_TRIM_1 or ... or @ref OB_AGC_TRIM_7
649   * @param  RDPLevel: specifies the read protection level.
650   *         This parameter can be one of the following values:
651   *            @arg @ref OB_RDP_LEVEL_0 No protection
652   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
653   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
654   * @retval None
655   */
FLASH_OB_OptrConfig(uint32_t UserType,uint32_t UserConfig,uint32_t RDPLevel)656 static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
657 {
658   uint32_t optr;
659 
660   /* Check the parameters */
661   assert_param(IS_OB_USER_TYPE(UserType));
662   assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
663   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
664 
665   /* Configure the RDP level in the option bytes register */
666   optr = FLASH->OPTR;
667   optr &= ~(UserType | FLASH_OPTR_RDP);
668   FLASH->OPTR = (optr | UserConfig | RDPLevel);
669 }
670 
671 /**
672   * @brief  Configure the Zone 1A Proprietary code readout protection of the desired addresses,
673   *         and erase configuration on RDP regression.
674   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
675   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
676   * @note   To validate the PCROP options, the option bytes must be reloaded
677   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
678   * @param  PCROPConfig: specifies the erase configuration (OB_PCROP_RDP_NOT_ERASE or OB_PCROP_RDP_ERASE)
679   *         on RDP level 1 regression.
680   * @param  PCROP1AStartAddr Specifies the Zone 1A Start address of the Proprietary code readout protection
681   *         This parameter can be an address between begin and end of the flash
682   * @param  PCROP1AEndAddr Specifies the Zone 1A end address of the Proprietary code readout protection
683   *         This parameter can be an address between PCROP1AStartAddr and end of the flash
684   * @retval None
685   */
FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig,uint32_t PCROP1AStartAddr,uint32_t PCROP1AEndAddr)686 static void FLASH_OB_PCROP1AConfig(uint32_t PCROPConfig, uint32_t PCROP1AStartAddr, uint32_t PCROP1AEndAddr)
687 {
688   uint32_t startoffset;
689   uint32_t endoffset;
690   uint32_t pcrop1aend;
691 
692   /* Check the parameters */
693   assert_param(IS_OB_PCROP_CONFIG(PCROPConfig));
694   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AStartAddr));
695   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1AEndAddr));
696 
697   /* get pcrop 1A end register */
698   pcrop1aend = FLASH->PCROP1AER;
699 
700   /* Configure the Proprietary code readout protection offset */
701   if ((PCROPConfig & OB_PCROP_ZONE_A) != 0U)
702   {
703     /* Compute offset depending on pcrop granularity */
704     startoffset = ((PCROP1AStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
705     endoffset = ((PCROP1AEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
706 
707     /* Set Zone A start offset */
708     WRITE_REG(FLASH->PCROP1ASR, startoffset);
709 
710     /* Set Zone A end offset */
711     pcrop1aend &= ~FLASH_PCROP1AER_PCROP1A_END;
712     pcrop1aend |= endoffset;
713   }
714 
715   /* Set RDP erase protection if needed. This bit is only set & will be reset by mass erase */
716   if ((PCROPConfig & OB_PCROP_RDP_ERASE) != 0U)
717   {
718     pcrop1aend |= FLASH_PCROP1AER_PCROP_RDP;
719   }
720 
721   /* set 1A End register */
722   WRITE_REG(FLASH->PCROP1AER, pcrop1aend);
723 }
724 
725 /**
726   * @brief  Configure the Zone 1B Proprietary code readout protection of the desired addresses.
727   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
728   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
729   * @note   To validate the PCROP options, the option bytes must be reloaded
730   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
731   * @param  PCROP1BStartAddr Specifies the Zone 1BStart address of the Proprietary code readout protection
732   *         This parameter can be an address between begin and end of the flash
733   * @param  PCROP1BEndAddr Specifies the Zone 1B end address of the Proprietary code readout protection
734   *         This parameter can be an address between PCROP1BStartAddr and end of the flash
735   * @retval None
736   */
FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr,uint32_t PCROP1BEndAddr)737 static void FLASH_OB_PCROP1BConfig(uint32_t PCROP1BStartAddr, uint32_t PCROP1BEndAddr)
738 {
739   uint32_t startoffset;
740   uint32_t endoffset;
741 
742   /* Check the parameters */
743   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BStartAddr));
744   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(PCROP1BEndAddr));
745 
746   /* Compute offset depending on pcrop granularity */
747   startoffset = ((PCROP1BStartAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
748   endoffset = ((PCROP1BEndAddr - FLASH_BASE) >> FLASH_PCROP_GRANULARITY_OFFSET); /* 2K pages */
749 
750   /* Configure the Proprietary code readout protection start address */
751   WRITE_REG(FLASH->PCROP1BSR, startoffset);
752 
753   /* Configure the Proprietary code readout protection end address */
754   WRITE_REG(FLASH->PCROP1BER, endoffset);
755 }
756 
757 /**
758   * @brief  Program the FLASH IPCC data buffer address.
759   * @note   To configure the extra user option bytes, the option lock bit OPTLOCK must
760   *         be cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
761   * @note   To validate the extra user option bytes, the option bytes must be reloaded
762   *         through the call of the @ref HAL_FLASH_OB_Launch() function.
763   * @param  IPCCDataBufAddr IPCC data buffer start address area in SRAM2
764   *         This parameter must be the double-word aligned
765   * @retval None
766   */
FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr)767 static void FLASH_OB_IPCCBufferAddrConfig(uint32_t IPCCDataBufAddr)
768 {
769   assert_param(IS_OB_IPCC_BUF_ADDR(IPCCDataBufAddr));
770 
771   /* Configure the option bytes register */
772   WRITE_REG(FLASH->IPCCBR, (uint32_t)((IPCCDataBufAddr - SRAM2A_BASE) >> 4));
773 }
774 
775 /**
776   * @brief  Configure the secure start address of the different memories (FLASH and SRAM2),
777   *         the secure mode and the CPU2 Secure Boot reset vector
778   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
779   *         cleared with the call of the @ref HAL_FLASH_OB_Unlock() function.
780   * @param  pOBParam Pointer to an @ref FLASH_OBProgramInitTypeDef structure that
781   *         contains the configuration information for the programming
782   * @retval void
783   */
FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef * pOBParam)784 static void FLASH_OB_SecureConfig(FLASH_OBProgramInitTypeDef *pOBParam)
785 {
786   uint32_t sfr_reg_val = READ_REG(FLASH->SFR);
787   uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR);
788 
789   if ((pOBParam->OptionType & OPTIONBYTE_SECURE_MODE) != 0U)
790   {
791     assert_param(IS_OB_SFSA_START_ADDR(pOBParam->SecureFlashStartAddr));
792     assert_param(IS_OB_SBRSA_START_ADDR(pOBParam->SecureRAM2aStartAddr));
793     assert_param(IS_OB_SNBRSA_START_ADDR(pOBParam->SecureRAM2bStartAddr));
794     assert_param(IS_OB_SECURE_MODE(pOBParam->SecureMode));
795 
796     /* Configure SFR register content with start PAGE index to secure */
797     MODIFY_REG(sfr_reg_val, FLASH_SFR_SFSA, (((pOBParam->SecureFlashStartAddr - FLASH_BASE) / FLASH_PAGE_SIZE) << FLASH_SFR_SFSA_Pos));
798 
799     /* Configure SRRVR register */
800     MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRSA | FLASH_SRRVR_SNBRSA), \
801                (((((pOBParam->SecureRAM2aStartAddr - SRAM2A_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SBRSA_Pos)) | \
802                 ((((pOBParam->SecureRAM2bStartAddr - SRAM2B_BASE) >> SRAM_SECURE_PAGE_GRANULARITY_OFFSET) << FLASH_SRRVR_SNBRSA_Pos))));
803 
804     /* If Full System Secure mode is requested, clear all the corresponding bit */
805     /* Else set the corresponding bit */
806     if (pOBParam->SecureMode == SYSTEM_IN_SECURE_MODE)
807     {
808       CLEAR_BIT(sfr_reg_val, FLASH_SFR_FSD);
809       CLEAR_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD));
810     }
811     else
812     {
813       SET_BIT(sfr_reg_val, FLASH_SFR_FSD);
814       SET_BIT(srrvr_reg_val, (FLASH_SRRVR_BRSD | FLASH_SRRVR_NBRSD));
815     }
816 
817     /* Update Flash registers */
818     WRITE_REG(FLASH->SFR, sfr_reg_val);
819   }
820 
821   /* Boot vector */
822   if ((pOBParam->OptionType & OPTIONBYTE_C2_BOOT_VECT) != 0U)
823   {
824     /* Check the parameters */
825     assert_param(IS_OB_BOOT_VECTOR_ADDR(pOBParam->C2SecureBootVectAddr));
826     assert_param(IS_OB_BOOT_REGION(pOBParam->C2BootRegion));
827 
828     /* Set the boot vector */
829     if (pOBParam->C2BootRegion == OB_C2_BOOT_FROM_FLASH)
830     {
831       MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT), (((pOBParam->C2SecureBootVectAddr - FLASH_BASE) >> 2) | pOBParam->C2BootRegion));
832     }
833     else
834     {
835       MODIFY_REG(srrvr_reg_val, (FLASH_SRRVR_SBRV | FLASH_SRRVR_C2OPT), (((pOBParam->C2SecureBootVectAddr - SRAM1_BASE) >> 2) | pOBParam->C2BootRegion));
836     }
837   }
838 
839   /* Update Flash registers */
840   WRITE_REG(FLASH->SRRVR, srrvr_reg_val);
841 }
842 
843 /**
844   * @brief  Return the FLASH Write Protection Option Bytes value.
845   * @param[in]   WRPArea Specifies the area to be returned.
846   *              This parameter can be one of the following values:
847   *              @arg @ref OB_WRPAREA_BANK1_AREAA Flash Bank 1 Area A
848   *              @arg @ref OB_WRPAREA_BANK1_AREAB Flash Bank 1 Area B
849   * @param[out]  WRPStartOffset Specifies the address where to copied the start page
850   *                             of the write protected area
851   * @param[out]  WRDPEndOffset Specifies the address where to copied the end page of
852   *                            the write protected area
853   * @retval None
854   */
FLASH_OB_GetWRP(uint32_t WRPArea,uint32_t * WRPStartOffset,uint32_t * WRDPEndOffset)855 static void FLASH_OB_GetWRP(uint32_t WRPArea, uint32_t *WRPStartOffset, uint32_t *WRDPEndOffset)
856 {
857   /* Check the parameters */
858   assert_param(IS_OB_WRPAREA(WRPArea));
859 
860   /* Get the configuration of the write protected area */
861   if (WRPArea == OB_WRPAREA_BANK1_AREAA)
862   {
863     *WRPStartOffset = READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_STRT);
864     *WRDPEndOffset = (READ_BIT(FLASH->WRP1AR, FLASH_WRP1AR_WRP1A_END) >> FLASH_WRP1AR_WRP1A_END_Pos);
865   }
866   else /* OB_WRPAREA_BANK1_AREAB */
867   {
868     *WRPStartOffset = READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_STRT);
869     *WRDPEndOffset = (READ_BIT(FLASH->WRP1BR, FLASH_WRP1BR_WRP1B_END) >> FLASH_WRP1BR_WRP1B_END_Pos);
870   }
871 }
872 
873 /**
874   * @brief  Return the FLASH Read Protection level.
875   * @retval FLASH ReadOut Protection Status:
876   *         This return value can be one of the following values:
877   *            @arg @ref OB_RDP_LEVEL_0 No protection
878   *            @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
879   *            @arg @ref OB_RDP_LEVEL_2 Full chip protection
880   */
FLASH_OB_GetRDP(void)881 static uint32_t FLASH_OB_GetRDP(void)
882 {
883   uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
884 
885   if ((rdplvl != OB_RDP_LEVEL_0) && (rdplvl != OB_RDP_LEVEL_2))
886   {
887     return (OB_RDP_LEVEL_1);
888   }
889   else
890   {
891     return rdplvl;
892   }
893 }
894 
895 /**
896   * @brief  Return the FLASH User Option Byte value.
897   * @retval This return value can be a combination of all the following values:
898   *         @arg @ref OB_BOR_LEVEL_0 or @ref OB_BOR_LEVEL_1 or ... or @ref OB_BOR_LEVEL_4
899   *         @arg @ref OB_STOP_RST or @ref OB_STOP_RST
900   *         @arg @ref OB_STANDBY_RST or @ref OB_STANDBY_NORST
901   *         @arg @ref OB_SHUTDOWN_RST or @ref OB_SHUTDOWN_NORST
902   *         @arg @ref OB_IWDG_SW or @ref OB_IWDG_HW
903   *         @arg @ref OB_IWDG_STOP_FREEZE or @ref OB_IWDG_STOP_RUN
904   *         @arg @ref OB_IWDG_STDBY_FREEZE or @ref OB_IWDG_STDBY_RUN
905   *         @arg @ref OB_WWDG_SW or @ref OB_WWDG_HW
906   *         @arg @ref OB_BOOT1_SRAM or @ref OB_BOOT1_SYSTEM
907   *         @arg @ref OB_SRAM2_PARITY_ENABLE or @ref OB_SRAM2_PARITY_DISABLE
908   *         @arg @ref OB_SRAM2_RST_ERASE or @ref OB_SRAM2_RST_NOT_ERASE
909   *         @arg @ref OB_BOOT0_FROM_OB or @ref OB_BOOT0_FROM_PIN
910   *         @arg @ref OB_BOOT0_RESET or @ref OB_BOOT0_SET
911   *         @arg @ref OB_AGC_TRIM_0 or @ref OB_AGC_TRIM_1 or ... or @ref OB_AGC_TRIM_7
912   */
FLASH_OB_GetUser(void)913 static uint32_t FLASH_OB_GetUser(void)
914 {
915   uint32_t user_config = (READ_REG(FLASH->OPTR) & OB_USER_ALL);
916   CLEAR_BIT(user_config, (FLASH_OPTR_RDP | FLASH_OPTR_ESE));
917 
918   return user_config;
919 }
920 
921 /**
922   * @brief  Return the FLASH Write Protection Option Bytes value.
923   * @param PCROPConfig [out] Specifies the address where to copied the configuration of PCROP_RDP option
924   * @param PCROP1AStartAddr [out] Specifies the address where to copied the start address
925   *                         of the Zone 1A Proprietary code readout protection
926   * @param PCROP1AEndAddr [out] Specifies the address where to copied the end address of
927   *                       the Zone 1A Proprietary code readout protection
928   * @param PCROP1BStartAddr [out] Specifies the address where to copied the start address
929   *                         of the Zone 1B Proprietary code readout protection
930   * @param PCROP1BEndAddr [out] Specifies the address where to copied the end address of
931   *                       the Zone 1B Proprietary code readout protection
932   * @retval None
933   */
FLASH_OB_GetPCROP(uint32_t * PCROPConfig,uint32_t * PCROP1AStartAddr,uint32_t * PCROP1AEndAddr,uint32_t * PCROP1BStartAddr,uint32_t * PCROP1BEndAddr)934 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROP1AStartAddr, uint32_t *PCROP1AEndAddr, uint32_t *PCROP1BStartAddr, uint32_t *PCROP1BEndAddr)
935 {
936   uint32_t pcrop;
937 
938   pcrop             = (READ_BIT(FLASH->PCROP1BSR, FLASH_PCROP1BSR_PCROP1B_STRT));
939   *PCROP1BStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
940 
941   pcrop             = (READ_BIT(FLASH->PCROP1BER, FLASH_PCROP1BER_PCROP1B_END));
942   *PCROP1BEndAddr   = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
943 
944   pcrop             = (READ_BIT(FLASH->PCROP1ASR, FLASH_PCROP1ASR_PCROP1A_STRT));
945   *PCROP1AStartAddr = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
946 
947   pcrop             = (READ_BIT(FLASH->PCROP1AER, FLASH_PCROP1AER_PCROP1A_END));
948   *PCROP1AEndAddr   = ((pcrop << FLASH_PCROP_GRANULARITY_OFFSET) + FLASH_BASE);
949 
950   *PCROPConfig      = (READ_REG(FLASH->PCROP1AER) & FLASH_PCROP1AER_PCROP_RDP);
951 }
952 
953 /**
954   * @brief  Return the FLASH IPCC data buffer base address Option Byte value.
955   * @retval Returned value is the IPCC data buffer start address area in SRAM2.
956   */
FLASH_OB_GetIPCCBufferAddr(void)957 static uint32_t FLASH_OB_GetIPCCBufferAddr(void)
958 {
959   return (uint32_t)((READ_BIT(FLASH->IPCCBR, FLASH_IPCCBR_IPCCDBA) << 4) + SRAM2A_BASE);
960 }
961 
962 /**
963   * @brief  Return the Secure Flash start address, Secure Backup RAM2a start address, Secure non-Backup RAM2b start address and the SecureMode
964   * @param  SecureFlashStartAddr Specifies the address where to copied the Secure Flash start address
965   * @param  SecureRAM2aStartAddr Specifies the address where to copied the Secure Backup RAM2a start address
966   * @param  SecureRAM2bStartAddr Specifies the address where to copied the Secure non-Backup RAM2b start address
967   * @param  SecureMode           Specifies the address where to copied the Secure Mode.
968   *                              This return value can be one of the following values:
969   *                              @arg @ref SYSTEM_IN_SECURE_MODE : Security enabled
970   *                              @arg @ref SYSTEM_NOT_IN_SECURE_MODE : Security disabled
971   * @retval None
972   */
FLASH_OB_GetSecureMemoryConfig(uint32_t * SecureFlashStartAddr,uint32_t * SecureRAM2aStartAddr,uint32_t * SecureRAM2bStartAddr,uint32_t * SecureMode)973 static void FLASH_OB_GetSecureMemoryConfig(uint32_t *SecureFlashStartAddr, uint32_t *SecureRAM2aStartAddr, uint32_t *SecureRAM2bStartAddr, uint32_t *SecureMode)
974 {
975   uint32_t sfr_reg_val = READ_REG(FLASH->SFR);
976   uint32_t srrvr_reg_val = READ_REG(FLASH->SRRVR);
977 
978   /* Get Secure Flash start address */
979   uint32_t user_config = (READ_BIT(sfr_reg_val, FLASH_SFR_SFSA) >> FLASH_SFR_SFSA_Pos);
980 
981   *SecureFlashStartAddr = ((user_config * FLASH_PAGE_SIZE) + FLASH_BASE);
982 
983   /* Get Secure SRAM2a start address */
984   user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SBRSA) >> FLASH_SRRVR_SBRSA_Pos);
985 
986   *SecureRAM2aStartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2A_BASE);
987 
988   /* Get Secure SRAM2b start address */
989   user_config = (READ_BIT(srrvr_reg_val, FLASH_SRRVR_SNBRSA) >> FLASH_SRRVR_SNBRSA_Pos);
990 
991   *SecureRAM2bStartAddr = ((user_config << SRAM_SECURE_PAGE_GRANULARITY_OFFSET) + SRAM2B_BASE);
992 
993   /* Get Secure Area mode */
994   *SecureMode = (READ_BIT(FLASH->OPTR, FLASH_OPTR_ESE));
995 }
996 
997 /**
998   * @brief  Return the CPU2 Secure Boot reset vector address and the CPU2 Secure Boot Region
999   * @param  C2BootResetVectAddr Specifies the address where to copied the CPU2 Secure Boot reset vector address
1000   * @param  C2BootResetRegion   Specifies the Secure Boot reset memory region
1001   * @retval None
1002   */
FLASH_OB_GetC2BootResetConfig(uint32_t * C2BootResetVectAddr,uint32_t * C2BootResetRegion)1003 static void FLASH_OB_GetC2BootResetConfig(uint32_t *C2BootResetVectAddr, uint32_t *C2BootResetRegion)
1004 {
1005   *C2BootResetRegion = (READ_BIT(FLASH->SRRVR, FLASH_SRRVR_C2OPT));
1006 
1007   if (*C2BootResetRegion == OB_C2_BOOT_FROM_FLASH)
1008   {
1009     *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + FLASH_BASE);
1010   }
1011   else
1012   {
1013     *C2BootResetVectAddr = (uint32_t)((READ_BIT(FLASH->SRRVR, FLASH_SRRVR_SBRV) << 2) + SRAM1_BASE);
1014   }
1015 }
1016 
1017 /**
1018   * @brief  Proceed the OB Write Operation.
1019   * @retval HAL Status
1020   */
FLASH_OB_ProceedWriteOperation(void)1021 static HAL_StatusTypeDef FLASH_OB_ProceedWriteOperation(void)
1022 {
1023   HAL_StatusTypeDef status;
1024 
1025   /* Verify that next operation can be proceed */
1026   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1027 
1028   if (status == HAL_OK)
1029   {
1030     /* Set OPTSTRT Bit */
1031     SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
1032 
1033     /* Wait for last operation to be completed */
1034     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
1035   }
1036 
1037   return status;
1038 }
1039 
1040 /**
1041   * @}
1042   */
1043 
1044 /**
1045   * @}
1046   */
1047 
1048 #endif /* HAL_FLASH_MODULE_ENABLED */
1049 
1050 /**
1051   * @}
1052   */
1053 
1054 /**
1055   * @}
1056   */
1057 
1058 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1059