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