1 /**
2   ******************************************************************************
3   * @file    stm32h7xx_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 extension peripheral:
8   *           + Extended programming operations functions
9   *
10  @verbatim
11  ==============================================================================
12                    ##### Flash Extension features #####
13   ==============================================================================
14 
15   [..] Comparing to other previous devices, the FLASH interface for STM32H7xx
16        devices contains the following additional features
17 
18        (+) Capacity up to 2 Mbyte with dual bank architecture supporting read-while-write
19            capability (RWW)
20        (+) Dual bank memory organization
21        (+) PCROP protection for all banks
22        (+) Global readout protection (RDP)
23        (+) Write protection
24        (+) Secure access only protection
25        (+) Bank / register swapping
26        (+) Cyclic Redundancy Check (CRC)
27 
28                         ##### How to use this driver #####
29  ==============================================================================
30   [..] This driver provides functions to configure and program the FLASH memory
31        of all STM32H7xx devices. It includes
32       (#) FLASH Memory Erase functions:
33            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
34                 HAL_FLASH_Lock() functions
35            (++) Erase function: Sector erase, bank erase and dual-bank mass erase
36            (++) There are two modes of erase :
37              (+++) Polling Mode using HAL_FLASHEx_Erase()
38              (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
39 
40       (#) Option Bytes Programming functions: Use HAL_FLASHEx_OBProgram() to:
41         (++) Set/Reset the write protection per bank
42         (++) Set the Read protection Level
43         (++) Set the BOR level
44         (++) Program the user Option Bytes
45         (++) PCROP protection configuration and control per bank
46         (++) Secure area configuration and control per bank
47         (++) Core Boot address configuration
48 
49       (#) FLASH Memory Lock and unlock per Bank: HAL_FLASHEx_Lock_Bank1(), HAL_FLASHEx_Unlock_Bank1(),
50           HAL_FLASHEx_Lock_Bank2() and HAL_FLASHEx_Unlock_Bank2() functions
51 
52       (#) FLASH CRC computation function: Use HAL_FLASHEx_ComputeCRC() to:
53           (++) Enable CRC feature
54           (++) Program the desired burst size
55           (++) Define the user Flash Area on which the CRC has be computed
56           (++) Perform the CRC computation
57           (++) Disable CRC feature
58 
59  @endverbatim
60   ******************************************************************************
61   * @attention
62   *
63   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics.
64   * All rights reserved.</center></h2>
65   *
66   * This software component is licensed by ST under BSD 3-Clause license,
67   * the "License"; You may not use this file except in compliance with the
68   * License. You may obtain a copy of the License at:
69   *                       opensource.org/licenses/BSD-3-Clause
70   *
71   ******************************************************************************
72   */
73 
74 /* Includes ------------------------------------------------------------------*/
75 #include "stm32h7xx_hal.h"
76 
77 /** @addtogroup STM32H7xx_HAL_Driver
78   * @{
79   */
80 
81 /** @defgroup FLASHEx  FLASHEx
82   * @brief FLASH HAL Extension module driver
83   * @{
84   */
85 
86 #ifdef HAL_FLASH_MODULE_ENABLED
87 
88 /* Private typedef -----------------------------------------------------------*/
89 /* Private define ------------------------------------------------------------*/
90 /** @addtogroup FLASHEx_Private_Constants
91   * @{
92   */
93 #define FLASH_TIMEOUT_VALUE       50000U /* 50 s */
94 
95 /**
96   * @}
97   */
98 /* Private macro -------------------------------------------------------------*/
99 /* Private variables ---------------------------------------------------------*/
100 /* Private function prototypes -----------------------------------------------*/
101 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
102   * @{
103   */
104 static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks);
105 static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks);
106 static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Bank);
107 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank);
108 static void FLASH_OB_RDPConfig(uint32_t RDPLevel);
109 static uint32_t FLASH_OB_GetRDP(void);
110 static void FLASH_OB_PCROPConfig(uint32_t PCROConfigRDP, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks);
111 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr,uint32_t *PCROPEndAddr, uint32_t Bank);
112 static void FLASH_OB_BOR_LevelConfig(uint32_t Level);
113 static uint32_t FLASH_OB_GetBOR(void);
114 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig);
115 static uint32_t FLASH_OB_GetUser(void);
116 static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
117 static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
118 static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks);
119 static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank);
120 static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank);
121 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank);
122 
123 #if defined(DUAL_CORE)
124 static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1);
125 static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1);
126 #endif /*DUAL_CORE*/
127 /**
128   * @}
129   */
130 
131 /* Exported functions ---------------------------------------------------------*/
132 /** @defgroup FLASHEx_Exported_Functions FLASHEx Exported Functions
133   * @{
134   */
135 
136 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
137  *  @brief   Extended IO operation functions
138  *
139 @verbatim
140  ===============================================================================
141                 ##### Extended programming operation functions #####
142  ===============================================================================
143     [..]
144     This subsection provides a set of functions allowing to manage the Extension FLASH
145     programming operations Operations.
146 
147 @endverbatim
148   * @{
149   */
150 /**
151   * @brief  Perform a mass erase or erase the specified FLASH memory sectors
152   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
153   *         contains the configuration information for the erasing.
154   *
155   * @param[out]  SectorError pointer to variable  that contains the configuration
156   *          information on faulty sector in case of error (0xFFFFFFFF means that all
157   *          the sectors have been correctly erased)
158   *
159   * @retval HAL Status
160   */
HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef * pEraseInit,uint32_t * SectorError)161 HAL_StatusTypeDef HAL_FLASHEx_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
162 {
163   HAL_StatusTypeDef status = HAL_OK;
164   uint32_t sector_index;
165 
166   /* Check the parameters */
167   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
168   assert_param(IS_FLASH_BANK(pEraseInit->Banks));
169 
170   /* Process Locked */
171   __HAL_LOCK(&pFlash);
172 
173   /* Reset error code */
174   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
175 
176   /* Wait for last operation to be completed on Bank1 */
177   if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
178   {
179     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
180     {
181       status = HAL_ERROR;
182     }
183   }
184 
185   /* Wait for last operation to be completed on Bank2 */
186   if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
187   {
188     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
189     {
190       status = HAL_ERROR;
191     }
192   }
193 
194   if(status == HAL_OK)
195   {
196     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
197     {
198       /* Mass erase to be done */
199       FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
200 
201       /* Wait for last operation to be completed */
202       if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
203       {
204         if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
205         {
206           status = HAL_ERROR;
207         }
208         /* if the erase operation is completed, disable the Bank1 BER Bit */
209         FLASH->CR1 &= (~FLASH_CR_BER);
210       }
211       if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
212       {
213         if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
214         {
215           status = HAL_ERROR;
216         }
217         /* if the erase operation is completed, disable the Bank2 BER Bit */
218         FLASH->CR2 &= (~FLASH_CR_BER);
219       }
220     }
221     else
222     {
223       /*Initialization of SectorError variable*/
224       *SectorError = 0xFFFFFFFFU;
225 
226       /* Erase by sector by sector to be done*/
227       for(sector_index = pEraseInit->Sector; sector_index < (pEraseInit->NbSectors + pEraseInit->Sector); sector_index++)
228       {
229         FLASH_Erase_Sector(sector_index, pEraseInit->Banks, pEraseInit->VoltageRange);
230 
231         if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
232         {
233           /* Wait for last operation to be completed */
234           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
235 
236           /* If the erase operation is completed, disable the SER Bit */
237           FLASH->CR1 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
238         }
239         if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
240         {
241           /* Wait for last operation to be completed */
242           status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
243 
244           /* If the erase operation is completed, disable the SER Bit */
245           FLASH->CR2 &= (~(FLASH_CR_SER | FLASH_CR_SNB));
246         }
247 
248         if(status != HAL_OK)
249         {
250           /* In case of error, stop erase procedure and return the faulty sector */
251           *SectorError = sector_index;
252           break;
253         }
254       }
255     }
256   }
257 
258   /* Process Unlocked */
259   __HAL_UNLOCK(&pFlash);
260 
261   return status;
262 }
263 
264 /**
265   * @brief  Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled
266   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
267   *         contains the configuration information for the erasing.
268   *
269   * @retval HAL Status
270   */
HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef * pEraseInit)271 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
272 {
273   HAL_StatusTypeDef status = HAL_OK;
274 
275   /* Check the parameters */
276   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
277   assert_param(IS_FLASH_BANK(pEraseInit->Banks));
278 
279   /* Process Locked */
280   __HAL_LOCK(&pFlash);
281 
282   /* Reset error code */
283   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
284 
285   /* Wait for last operation to be completed */
286   if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
287   {
288     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
289     {
290       status = HAL_ERROR;
291     }
292   }
293 
294   if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
295   {
296     if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
297     {
298       status = HAL_ERROR;
299     }
300   }
301 
302   if (status != HAL_OK)
303   {
304     /* Process Unlocked */
305     __HAL_UNLOCK(&pFlash);
306   }
307   else
308   {
309     if((pEraseInit->Banks & FLASH_BANK_1) == FLASH_BANK_1)
310     {
311       /* Enable End of Operation and Error interrupts for Bank 1 */
312       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
313                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
314     }
315     if((pEraseInit->Banks & FLASH_BANK_2) == FLASH_BANK_2)
316     {
317       /* Enable End of Operation and Error interrupts for Bank 2 */
318       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
319                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
320     }
321 
322     if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
323     {
324       /*Mass erase to be done*/
325       if(pEraseInit->Banks == FLASH_BANK_1)
326       {
327         pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK1;
328       }
329       else if(pEraseInit->Banks == FLASH_BANK_2)
330       {
331         pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE_BANK2;
332       }
333       else
334       {
335         pFlash.ProcedureOnGoing = FLASH_PROC_ALLBANK_MASSERASE;
336       }
337 
338       FLASH_MassErase(pEraseInit->VoltageRange, pEraseInit->Banks);
339     }
340     else
341     {
342       /* Erase by sector to be done */
343       if(pEraseInit->Banks == FLASH_BANK_1)
344       {
345         pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK1;
346       }
347       else
348       {
349         pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE_BANK2;
350       }
351 
352       pFlash.NbSectorsToErase = pEraseInit->NbSectors;
353       pFlash.Sector = pEraseInit->Sector;
354       pFlash.VoltageForErase = pEraseInit->VoltageRange;
355 
356       /* Erase first sector and wait for IT */
357       FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->Banks, pEraseInit->VoltageRange);
358     }
359   }
360 
361   return status;
362 }
363 
364 /**
365   * @brief  Program option bytes
366   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
367   *         contains the configuration information for the programming.
368   *
369   * @retval HAL Status
370   */
HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef * pOBInit)371 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
372 {
373   HAL_StatusTypeDef status;
374 
375   /* Check the parameters */
376   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
377 
378   /* Process Locked */
379   __HAL_LOCK(&pFlash);
380 
381   /* Reset Error Code */
382   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
383 
384   /* Wait for last operation to be completed */
385   if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
386   {
387     status = HAL_ERROR;
388   }
389   else if(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
390   {
391     status = HAL_ERROR;
392   }
393   else
394   {
395     status = HAL_OK;
396   }
397 
398   if(status == HAL_OK)
399   {
400     /*Write protection configuration*/
401     if((pOBInit->OptionType & OPTIONBYTE_WRP) == OPTIONBYTE_WRP)
402     {
403       assert_param(IS_WRPSTATE(pOBInit->WRPState));
404 
405       if(pOBInit->WRPState == OB_WRPSTATE_ENABLE)
406       {
407         /*Enable of Write protection on the selected Sector*/
408         FLASH_OB_EnableWRP(pOBInit->WRPSector,pOBInit->Banks);
409       }
410       else
411       {
412         /*Disable of Write protection on the selected Sector*/
413         FLASH_OB_DisableWRP(pOBInit->WRPSector, pOBInit->Banks);
414       }
415     }
416 
417     /* Read protection configuration */
418     if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0U)
419     {
420       /* Configure the Read protection level */
421       FLASH_OB_RDPConfig(pOBInit->RDPLevel);
422     }
423 
424     /* User Configuration */
425     if((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
426     {
427       /* Configure the user option bytes */
428       FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig);
429     }
430 
431     /* PCROP Configuration */
432     if((pOBInit->OptionType & OPTIONBYTE_PCROP) != 0U)
433     {
434       assert_param(IS_FLASH_BANK(pOBInit->Banks));
435 
436       /*Configure the Proprietary code readout protection */
437       FLASH_OB_PCROPConfig(pOBInit->PCROPConfig, pOBInit->PCROPStartAddr, pOBInit->PCROPEndAddr, pOBInit->Banks);
438     }
439 
440     /* BOR Level configuration */
441     if((pOBInit->OptionType & OPTIONBYTE_BOR) == OPTIONBYTE_BOR)
442     {
443       FLASH_OB_BOR_LevelConfig(pOBInit->BORLevel);
444     }
445 
446 #if defined(DUAL_CORE)
447     /*CM7 Boot Address  configuration*/
448     if((pOBInit->OptionType & OPTIONBYTE_CM7_BOOTADD) == OPTIONBYTE_CM7_BOOTADD)
449     {
450       FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
451     }
452 
453     /*CM4 Boot Address  configuration*/
454     if((pOBInit->OptionType & OPTIONBYTE_CM4_BOOTADD) == OPTIONBYTE_CM4_BOOTADD)
455     {
456       FLASH_OB_CM4BootAddConfig(pOBInit->CM4BootConfig, pOBInit->CM4BootAddr0, pOBInit->CM4BootAddr1);
457     }
458 #else /* Single Core*/
459     /*Boot Address  configuration*/
460     if((pOBInit->OptionType & OPTIONBYTE_BOOTADD) == OPTIONBYTE_BOOTADD)
461     {
462       FLASH_OB_BootAddConfig(pOBInit->BootConfig, pOBInit->BootAddr0, pOBInit->BootAddr1);
463     }
464 #endif /*DUAL_CORE*/
465 
466     /*Bank1 secure area configuration*/
467     if((pOBInit->OptionType & OPTIONBYTE_SECURE_AREA) == OPTIONBYTE_SECURE_AREA)
468     {
469       FLASH_OB_SecureAreaConfig(pOBInit->SecureAreaConfig, pOBInit->SecureAreaStartAddr, pOBInit->SecureAreaEndAddr,pOBInit->Banks);
470     }
471   }
472 
473   /* Process Unlocked */
474   __HAL_UNLOCK(&pFlash);
475 
476   return status;
477 }
478 
479 /**
480   * @brief Get the Option byte configuration
481   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
482   *         contains the configuration information for the programming.
483   * @note   The parameter Banks of the pOBInit structure must be set exclusively to FLASH_BANK_1 or FLASH_BANK_2,
484   *         as this parameter is use to get the given Bank WRP, PCROP and secured area configuration.
485   *
486   * @retval None
487   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)488 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
489 {
490   pOBInit->OptionType = (OPTIONBYTE_USER | OPTIONBYTE_RDP | OPTIONBYTE_BOR);
491 
492   /* Get Read protection level */
493   pOBInit->RDPLevel = FLASH_OB_GetRDP();
494 
495   /* Get the user option bytes */
496   pOBInit->USERConfig = FLASH_OB_GetUser();
497 
498   /*Get BOR Level*/
499   pOBInit->BORLevel = FLASH_OB_GetBOR();
500 
501   if ((pOBInit->Banks == FLASH_BANK_1) || (pOBInit->Banks == FLASH_BANK_2))
502   {
503     pOBInit->OptionType |= (OPTIONBYTE_WRP | OPTIONBYTE_PCROP | OPTIONBYTE_SECURE_AREA);
504 
505     /* Get write protection on the selected area */
506     FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector), pOBInit->Banks);
507 
508     /* Get the Proprietary code readout protection */
509     FLASH_OB_GetPCROP(&(pOBInit->PCROPConfig), &(pOBInit->PCROPStartAddr), &(pOBInit->PCROPEndAddr), pOBInit->Banks);
510 
511     /*Get Bank Secure area*/
512     FLASH_OB_GetSecureArea(&(pOBInit->SecureAreaConfig), &(pOBInit->SecureAreaStartAddr), &(pOBInit->SecureAreaEndAddr), pOBInit->Banks);
513   }
514 
515   /*Get Boot Address*/
516   FLASH_OB_GetBootAdd(&(pOBInit->BootAddr0), &(pOBInit->BootAddr1));
517 #if defined(DUAL_CORE)
518   pOBInit->OptionType |= OPTIONBYTE_CM7_BOOTADD | OPTIONBYTE_CM4_BOOTADD;
519 
520   /*Get CM4 Boot Address*/
521   FLASH_OB_GetCM4BootAdd(&(pOBInit->CM4BootAddr0), &(pOBInit->CM4BootAddr1));
522 #else
523   pOBInit->OptionType |= OPTIONBYTE_BOOTADD;
524 #endif /*DUAL_CORE*/
525 }
526 
527 /**
528   * @brief  Unlock the FLASH Bank1 control registers access
529   * @retval HAL Status
530   */
HAL_FLASHEx_Unlock_Bank1(void)531 HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank1(void)
532 {
533   if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
534   {
535     /* Authorize the FLASH Bank1 Registers access */
536     WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
537     WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
538 
539     /* Verify Flash Bank1 is unlocked */
540     if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
541     {
542       return HAL_ERROR;
543     }
544   }
545 
546   return HAL_OK;
547 }
548 
549 /**
550   * @brief  Locks the FLASH Bank1 control registers access
551   * @retval HAL Status
552   */
HAL_FLASHEx_Lock_Bank1(void)553 HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank1(void)
554 {
555   /* Set the LOCK Bit to lock the FLASH Bank1 Registers access */
556   SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
557   return HAL_OK;
558 }
559 
560 /**
561   * @brief  Unlock the FLASH Bank2 control registers access
562   * @retval HAL Status
563   */
HAL_FLASHEx_Unlock_Bank2(void)564 HAL_StatusTypeDef HAL_FLASHEx_Unlock_Bank2(void)
565 {
566   if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
567   {
568     /* Authorize the FLASH Bank2 Registers access */
569     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
570     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
571 
572     /* Verify Flash Bank1 is unlocked */
573     if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
574     {
575       return HAL_ERROR;
576     }
577   }
578 
579   return HAL_OK;
580 }
581 
582 /**
583   * @brief  Locks the FLASH Bank2 control registers access
584   * @retval HAL Status
585   */
HAL_FLASHEx_Lock_Bank2(void)586 HAL_StatusTypeDef HAL_FLASHEx_Lock_Bank2(void)
587 {
588   /* Set the LOCK Bit to lock the FLASH Bank2 Registers access */
589   SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
590   return HAL_OK;
591 }
592 
593 /*
594   * @brief  Perform a CRC computation on the specified FLASH memory area
595   * @param  pCRCInit pointer to an FLASH_CRCInitTypeDef structure that
596   *         contains the configuration information for the CRC computation.
597   * @note   CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7
598   * @note   The application should avoid running a CRC on PCROP or secure-only
599   *         user Flash memory area since it may alter the expected CRC value.
600   *         A special error flag (CRC read error: CRCRDERR) can be used to
601   *         detect such a case.
602   * @retval HAL Status
603 */
HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef * pCRCInit,uint32_t * CRC_Result)604 HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result)
605 {
606   HAL_StatusTypeDef status;
607   uint32_t sector_index;
608 
609   /* Check the parameters */
610   assert_param(IS_FLASH_BANK_EXCLUSIVE(pCRCInit->Bank));
611   assert_param(IS_FLASH_TYPECRC(pCRCInit->TypeCRC));
612 
613   /* Wait for OB change operation to be completed */
614   status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
615 
616   if (status == HAL_OK)
617   {
618     if (pCRCInit->Bank == FLASH_BANK_1)
619     {
620       /* Enable CRC feature */
621       FLASH->CR1 |= FLASH_CR_CRC_EN;
622 
623       /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
624       FLASH->CCR1 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
625 
626       /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
627       FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
628 
629       if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
630       {
631         /* Clear sectors list */
632         FLASH->CRCCR1 |= FLASH_CRCCR_CLEAN_SECT;
633 
634         /* Select CRC sectors */
635         for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
636         {
637           FLASH_CRC_AddSector(sector_index, FLASH_BANK_1);
638         }
639       }
640       else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
641       {
642         /* Enable Bank 1 CRC select bit */
643         FLASH->CRCCR1 |= FLASH_CRCCR_ALL_BANK;
644       }
645       else
646       {
647         /* Select CRC start and end addresses */
648         FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_1);
649       }
650 
651       /* Start the CRC calculation */
652       FLASH->CRCCR1 |= FLASH_CRCCR_START_CRC;
653 
654       /* Wait on CRC busy flag */
655       status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1);
656 
657       /* Return CRC result */
658       (*CRC_Result) = FLASH->CRCDATA;
659 
660       /* Disable CRC feature */
661       FLASH->CR1 &= (~FLASH_CR_CRC_EN);
662 
663       /* Clear CRC flags */
664       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCEND_BANK1 | FLASH_FLAG_CRCRDERR_BANK1);
665     }
666     else
667     {
668       /* Enable CRC feature */
669       FLASH->CR2 |= FLASH_CR_CRC_EN;
670 
671       /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
672       FLASH->CCR2 |= (FLASH_CCR_CLR_CRCEND | FLASH_CCR_CLR_CRCRDERR);
673 
674       /* Clear current CRC result, program burst size and define memory area on which CRC has to be computed */
675       FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize | pCRCInit->TypeCRC;
676 
677       if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
678       {
679         /* Clear sectors list */
680         FLASH->CRCCR2 |= FLASH_CRCCR_CLEAN_SECT;
681 
682         /* Add CRC sectors */
683         for(sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
684         {
685           FLASH_CRC_AddSector(sector_index, FLASH_BANK_2);
686         }
687       }
688       else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
689       {
690         /* Enable Bank 2 CRC select bit */
691         FLASH->CRCCR2 |= FLASH_CRCCR_ALL_BANK;
692       }
693       else
694       {
695         /* Select CRC start and end addresses */
696         FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr, FLASH_BANK_2);
697       }
698 
699       /* Start the CRC calculation */
700       FLASH->CRCCR2 |= FLASH_CRCCR_START_CRC;
701 
702       /* Wait on CRC busy flag */
703       status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2);
704 
705       /* Return CRC result */
706       (*CRC_Result) = FLASH->CRCDATA;
707 
708       /* Disable CRC feature */
709       FLASH->CR2 &= (~FLASH_CR_CRC_EN);
710 
711       /* Clear CRC flags */
712       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCEND_BANK2 | FLASH_FLAG_CRCRDERR_BANK2);
713     }
714   }
715 
716   return status;
717 }
718 
719 /**
720   * @}
721   */
722 
723 /**
724   * @}
725   */
726 
727 /* Private functions ---------------------------------------------------------*/
728 
729 /** @addtogroup FLASHEx_Private_Functions
730   * @{
731   */
732 
733 /**
734   * @brief  Mass erase of FLASH memory
735   * @param  VoltageRange The device program/erase parallelism.
736   *          This parameter can be one of the following values:
737   *            @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
738   *            @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
739   *            @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
740   *            @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
741   *
742   * @param  Banks Banks to be erased
743   *          This parameter can be one of the following values:
744   *            @arg FLASH_BANK_1: Bank1 to be erased
745   *            @arg FLASH_BANK_2: Bank2 to be erased
746   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
747   *
748   * @retval HAL Status
749   */
FLASH_MassErase(uint32_t VoltageRange,uint32_t Banks)750 static void FLASH_MassErase(uint32_t VoltageRange, uint32_t Banks)
751 {
752   /* Check the parameters */
753   assert_param(IS_VOLTAGERANGE(VoltageRange));
754   assert_param(IS_FLASH_BANK(Banks));
755 
756   /* Flash Mass Erase */
757   if((Banks & FLASH_BANK_BOTH) == FLASH_BANK_BOTH)
758   {
759     /* Reset Program/erase VoltageRange for Bank1 and Bank2 */
760     FLASH->CR1 &= (~FLASH_CR_PSIZE);
761     FLASH->CR2 &= (~FLASH_CR_PSIZE);
762 
763     /* Set voltage range */
764     FLASH->CR1 |= VoltageRange;
765     FLASH->CR2 |= VoltageRange;
766 
767     /* Set Mass Erase Bit */
768     FLASH->OPTCR |= FLASH_OPTCR_MER;
769   }
770   else
771   {
772     /* Proceed to erase Flash Bank  */
773     if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
774     {
775       /* Reset Program/erase VoltageRange for Bank1 */
776       FLASH->CR1 &= (~FLASH_CR_PSIZE);
777 
778       /* Bank1 will be erased, and set voltage range */
779       FLASH->CR1 |= FLASH_CR_BER | VoltageRange;
780       FLASH->CR1 |= FLASH_CR_START;
781     }
782     if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
783     {
784       /* Reset Program/erase VoltageRange for Bank2 */
785       FLASH->CR2 &= (~FLASH_CR_PSIZE);
786 
787       /* Bank2 will be erased, and set voltage range */
788       FLASH->CR2 |= FLASH_CR_BER | VoltageRange;
789       FLASH->CR2 |= FLASH_CR_START;
790     }
791   }
792 }
793 
794 /**
795   * @brief  Erase the specified FLASH memory sector
796   * @param  Sector FLASH sector to erase
797   *          This parameter can be a value of @ref FLASH_Sectors
798   * @param  Banks Banks to be erased
799   *          This parameter can be one of the following values:
800   *            @arg FLASH_BANK_1: Bank1 to be erased
801   *            @arg FLASH_BANK_2: Bank2 to be erased
802   *            @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased
803   * @param  VoltageRange The device program/erase parallelism.
804   *          This parameter can be one of the following values:
805   *            @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits
806   *            @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits
807   *            @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits
808   *            @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 64 bits
809   *
810   * @retval None
811   */
FLASH_Erase_Sector(uint32_t Sector,uint32_t Banks,uint32_t VoltageRange)812 void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange)
813 {
814   assert_param(IS_FLASH_SECTOR(Sector));
815   assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks));
816   assert_param(IS_VOLTAGERANGE(VoltageRange));
817 
818   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
819   {
820     /* reset Program/erase VoltageRange for Bank1 */
821     FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
822 
823     FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << FLASH_CR_SNB_Pos));
824 
825     FLASH->CR1 |= FLASH_CR_START;
826   }
827 
828   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
829   {
830     /* reset Program/erase VoltageRange for Bank2 */
831     FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB);
832 
833     FLASH->CR2 |= (FLASH_CR_SER | VoltageRange  | (Sector << FLASH_CR_SNB_Pos));
834 
835     FLASH->CR2 |= FLASH_CR_START;
836   }
837 }
838 
839 /**
840   * @brief  Enable the write protection of the desired bank1 or bank 2 sectors
841   * @param  WRPSector specifies the sector(s) to be write protected.
842   *          This parameter can be one of the following values:
843   *            @arg WRPSector:  A combination of OB_WRP_SECTOR_0 to OB_WRP_SECTOR_7 or OB_WRP_SECTOR_All
844   *
845   * @param  Banks the specific bank to apply WRP sectors
846   *          This parameter can be one of the following values:
847   *            @arg FLASH_BANK_1: enable WRP on specified bank1 sectors
848   *            @arg FLASH_BANK_2: enable WRP on specified bank2 sectors
849   *            @arg FLASH_BANK_BOTH: enable WRP on both bank1 and bank2 specified sectors
850   *
851   * @retval HAL FLASH State
852   */
FLASH_OB_EnableWRP(uint32_t WRPSector,uint32_t Banks)853 static void FLASH_OB_EnableWRP(uint32_t WRPSector, uint32_t Banks)
854 {
855   /* Check the parameters */
856   assert_param(IS_OB_WRP_SECTOR(WRPSector));
857   assert_param(IS_FLASH_BANK(Banks));
858 
859   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
860   {
861     /* Enable Write Protection for bank 1 */
862     FLASH->WPSN_PRG1 &= (~(WRPSector & FLASH_WPSN_WRPSN));
863   }
864 
865   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
866   {
867     /* Enable Write Protection for bank 2 */
868     FLASH->WPSN_PRG2 &= (~(WRPSector & FLASH_WPSN_WRPSN));
869   }
870 }
871 
872 /**
873   * @brief  Disable the write protection of the desired bank1 or bank 2 sectors
874   * @param  WRPSector specifies the sector(s) to disable write protection.
875   *          This parameter can be one of the following values:
876   *            @arg WRPSector:  A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All
877   *
878   * @param  Banks the specific bank to apply WRP sectors
879   *          This parameter can be one of the following values:
880   *            @arg FLASH_BANK_1: disable WRP on specified bank1 sectors
881   *            @arg FLASH_BANK_2: disable WRP on specified bank2 sectors
882   *            @arg FLASH_BANK_BOTH: disable WRP on both bank1 and bank2 specified sectors
883   *
884   * @retval HAL FLASH State
885   */
FLASH_OB_DisableWRP(uint32_t WRPSector,uint32_t Banks)886 static void FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
887 {
888   /* Check the parameters */
889   assert_param(IS_OB_WRP_SECTOR(WRPSector));
890   assert_param(IS_FLASH_BANK(Banks));
891 
892   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
893   {
894     /* Disable Write Protection for bank 1 */
895     FLASH->WPSN_PRG1 |= (WRPSector & FLASH_WPSN_WRPSN);
896   }
897 
898   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
899   {
900     /* Disable Write Protection for bank 2 */
901     FLASH->WPSN_PRG2 |= (WRPSector & FLASH_WPSN_WRPSN);
902   }
903 }
904 
905 /**
906   * @brief  Get the write protection of the given bank 1 or bank 2 sectors
907   * @param  WRPState gives the write protection state on the given bank.
908   *          This parameter can be one of the following values:
909   *          @arg WRPState: OB_WRPSTATE_DISABLE or OB_WRPSTATE_ENABLE
910 
911   * @param  WRPSector gives the write protected sector(s) on the given bank .
912   *          This parameter can be one of the following values:
913   *          @arg WRPSector: A combination of FLASH_OB_WRP_SECTOR_0 to FLASH_OB_WRP_SECTOR_7 or FLASH_OB_WRP_SECTOR_All
914   *
915   * @param  Bank the specific bank to apply WRP sectors
916   *          This parameter can be exclusively one of the following values:
917   *            @arg FLASH_BANK_1: Get bank1 WRP sectors
918   *            @arg FLASH_BANK_2: Get bank2 WRP sectors
919   *            @arg FLASH_BANK_BOTH: note allowed in this functions
920   *
921   * @retval HAL FLASH State
922   */
FLASH_OB_GetWRP(uint32_t * WRPState,uint32_t * WRPSector,uint32_t Bank)923 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector, uint32_t Bank)
924 {
925   uint32_t regvalue = 0U;
926 
927   if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1)
928   {
929     regvalue = FLASH->WPSN_CUR1;
930   }
931 
932   if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2)
933   {
934     regvalue = FLASH->WPSN_CUR2;
935   }
936 
937   (*WRPSector) = (~regvalue) & FLASH_WPSN_WRPSN;
938 
939   if(*WRPSector == 0U)
940   {
941     (*WRPState) = OB_WRPSTATE_DISABLE;
942   }
943   else
944   {
945     (*WRPState) = OB_WRPSTATE_ENABLE;
946   }
947 }
948 
949 /**
950   * @brief  Set the read protection level.
951   *
952   * @note   To configure the RDP level, the option lock bit OPTLOCK must be
953   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
954   * @note   To validate the RDP level, the option bytes must be reloaded
955   *         through the call of the HAL_FLASH_OB_Launch() function.
956   * @note   !!! Warning : When enabling OB_RDP level 2 it's no more possible
957   *         to go back to level 1 or 0 !!!
958   *
959   * @param  RDPLevel specifies the read protection level.
960   *         This parameter can be one of the following values:
961   *            @arg OB_RDP_LEVEL_0: No protection
962   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
963   *            @arg OB_RDP_LEVEL_2: Full chip protection
964   *
965   * @retval HAL status
966   */
FLASH_OB_RDPConfig(uint32_t RDPLevel)967 static void FLASH_OB_RDPConfig(uint32_t RDPLevel)
968 {
969   /* Check the parameters */
970   assert_param(IS_OB_RDP_LEVEL(RDPLevel));
971 
972   /* Configure the RDP level in the option bytes register */
973   MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_RDP, RDPLevel);
974 }
975 
976 /**
977   * @brief  Get the read protection level.
978   * @retval RDPLevel specifies the read protection level.
979   *         This return value can be one of the following values:
980   *            @arg OB_RDP_LEVEL_0: No protection
981   *            @arg OB_RDP_LEVEL_1: Read protection of the memory
982   *            @arg OB_RDP_LEVEL_2: Full chip protection
983   */
FLASH_OB_GetRDP(void)984 static uint32_t FLASH_OB_GetRDP(void)
985 {
986   uint32_t rdp_level = READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_RDP);
987 
988   if ((rdp_level != OB_RDP_LEVEL_0) && (rdp_level != OB_RDP_LEVEL_2))
989   {
990     return (OB_RDP_LEVEL_1);
991   }
992   else
993   {
994     return rdp_level;
995   }
996 }
997 
998 #if defined(DUAL_CORE)
999 /**
1000   * @brief  Program the FLASH User Option Byte.
1001   *
1002   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
1003   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
1004   *
1005   * @note   To validate the user option bytes, the option bytes must be reloaded
1006   *         through the call of the HAL_FLASH_OB_Launch() function.
1007   *
1008   * @param  UserType The FLASH User Option Bytes to be modified :
1009   *                   a combination of @ref FLASHEx_OB_USER_Type
1010   *
1011   * @param  UserConfig The FLASH User Option Bytes values:
1012   *         IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1013   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1014   *         SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
1015   *         nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1016   *
1017   * @retval HAL status
1018   */
1019 #else
1020 /**
1021   * @brief  Program the FLASH User Option Byte.
1022   *
1023   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
1024   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
1025   *
1026   * @note   To validate the user option bytes, the option bytes must be reloaded
1027   *         through the call of the HAL_FLASH_OB_Launch() function.
1028   *
1029   * @param  UserType The FLASH User Option Bytes to be modified :
1030   *                   a combination of @arg FLASHEx_OB_USER_Type
1031   *
1032   * @param  UserConfig The FLASH User Option Bytes values:
1033   *         IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1034   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1035   *         SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1036   *
1037   * @retval HAL status
1038   */
1039 #endif /*DUAL_CORE*/
FLASH_OB_UserConfig(uint32_t UserType,uint32_t UserConfig)1040 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig)
1041 {
1042   uint32_t optr_reg_val = 0;
1043   uint32_t optr_reg_mask = 0;
1044 
1045   /* Check the parameters */
1046   assert_param(IS_OB_USER_TYPE(UserType));
1047 
1048   if((UserType & OB_USER_IWDG1_SW) != 0U)
1049   {
1050     /* IWDG_HW option byte should be modified */
1051     assert_param(IS_OB_IWDG1_SOURCE(UserConfig & FLASH_OPTSR_IWDG1_SW));
1052 
1053     /* Set value and mask for IWDG_HW option byte */
1054     optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG1_SW);
1055     optr_reg_mask |= FLASH_OPTSR_IWDG1_SW;
1056   }
1057 #if defined(DUAL_CORE)
1058   if((UserType & OB_USER_IWDG2_SW) != 0U)
1059   {
1060     /* IWDG2_SW option byte should be modified */
1061     assert_param(IS_OB_IWDG2_SOURCE(UserConfig & FLASH_OPTSR_IWDG2_SW));
1062 
1063     /* Set value and mask for IWDG2_SW option byte */
1064     optr_reg_val |= (UserConfig & FLASH_OPTSR_IWDG2_SW);
1065     optr_reg_mask |= FLASH_OPTSR_IWDG2_SW;
1066   }
1067 #endif /*DUAL_CORE*/
1068   if((UserType & OB_USER_NRST_STOP_D1) != 0U)
1069   {
1070     /* NRST_STOP option byte should be modified */
1071     assert_param(IS_OB_STOP_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D1));
1072 
1073     /* Set value and mask for NRST_STOP option byte */
1074     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D1);
1075     optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D1;
1076   }
1077 
1078   if((UserType & OB_USER_NRST_STDBY_D1) != 0U)
1079   {
1080     /* NRST_STDBY option byte should be modified */
1081     assert_param(IS_OB_STDBY_D1_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D1));
1082 
1083     /* Set value and mask for NRST_STDBY option byte */
1084     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D1);
1085     optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D1;
1086   }
1087 
1088   if((UserType & OB_USER_IWDG_STOP) != 0U)
1089   {
1090     /* IWDG_STOP option byte should be modified */
1091     assert_param(IS_OB_USER_IWDG_STOP(UserConfig & FLASH_OPTSR_FZ_IWDG_STOP));
1092 
1093     /* Set value and mask for IWDG_STOP option byte */
1094     optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_STOP);
1095     optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_STOP;
1096   }
1097 
1098   if((UserType & OB_USER_IWDG_STDBY) != 0U)
1099   {
1100     /* IWDG_STDBY option byte should be modified */
1101     assert_param(IS_OB_USER_IWDG_STDBY(UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY));
1102 
1103     /* Set value and mask for IWDG_STDBY option byte */
1104     optr_reg_val |= (UserConfig & FLASH_OPTSR_FZ_IWDG_SDBY);
1105     optr_reg_mask |= FLASH_OPTSR_FZ_IWDG_SDBY;
1106   }
1107 
1108   if((UserType & OB_USER_ST_RAM_SIZE) != 0U)
1109   {
1110     /* ST_RAM_SIZE option byte should be modified */
1111     assert_param(IS_OB_USER_ST_RAM_SIZE(UserConfig & FLASH_OPTSR_ST_RAM_SIZE));
1112 
1113     /* Set value and mask for ST_RAM_SIZE option byte */
1114     optr_reg_val |= (UserConfig & FLASH_OPTSR_ST_RAM_SIZE);
1115     optr_reg_mask |= FLASH_OPTSR_ST_RAM_SIZE;
1116   }
1117 
1118   if((UserType & OB_USER_SECURITY) != 0U)
1119   {
1120     /* SECURITY option byte should be modified */
1121     assert_param(IS_OB_USER_SECURITY(UserConfig & FLASH_OPTSR_SECURITY));
1122 
1123     /* Set value and mask for SECURITY option byte */
1124     optr_reg_val |= (UserConfig & FLASH_OPTSR_SECURITY);
1125     optr_reg_mask |= FLASH_OPTSR_SECURITY;
1126   }
1127 
1128 #if defined(DUAL_CORE)
1129   if((UserType & OB_USER_BCM4) != 0U)
1130   {
1131     /* BCM4 option byte should be modified */
1132     assert_param(IS_OB_USER_BCM4(UserConfig & FLASH_OPTSR_BCM4));
1133 
1134     /* Set value and mask for BCM4 option byte */
1135     optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM4);
1136     optr_reg_mask |= FLASH_OPTSR_BCM4;
1137   }
1138 
1139   if((UserType & OB_USER_BCM7) != 0U)
1140   {
1141     /* BCM7 option byte should be modified */
1142     assert_param(IS_OB_USER_BCM7(UserConfig & FLASH_OPTSR_BCM7));
1143 
1144     /* Set value and mask for BCM7 option byte */
1145     optr_reg_val |= (UserConfig & FLASH_OPTSR_BCM7);
1146     optr_reg_mask |= FLASH_OPTSR_BCM7;
1147   }
1148 
1149   if((UserType & OB_USER_NRST_STOP_D2) != 0U)
1150   {
1151     /* NRST_STOP option byte should be modified */
1152     assert_param(IS_OB_STOP_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STOP_D2));
1153 
1154     /* Set value and mask for NRST_STOP option byte */
1155     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STOP_D2);
1156     optr_reg_mask |= FLASH_OPTSR_NRST_STOP_D2;
1157   }
1158 
1159   if((UserType & OB_USER_NRST_STDBY_D2) != 0U)
1160   {
1161     /* NRST_STDBY option byte should be modified */
1162     assert_param(IS_OB_STDBY_D2_RESET(UserConfig & FLASH_OPTSR_NRST_STBY_D2));
1163 
1164     /* Set value and mask for NRST_STDBY option byte */
1165     optr_reg_val |= (UserConfig & FLASH_OPTSR_NRST_STBY_D2);
1166     optr_reg_mask |= FLASH_OPTSR_NRST_STBY_D2;
1167   }
1168 #endif /*DUAL_CORE*/
1169   if((UserType & OB_USER_SWAP_BANK) != 0U)
1170   {
1171     /* SWAP_BANK_OPT option byte should be modified */
1172     assert_param(IS_OB_USER_SWAP_BANK(UserConfig & FLASH_OPTSR_SWAP_BANK_OPT));
1173 
1174     /* Set value and mask for SWAP_BANK_OPT option byte */
1175     optr_reg_val |= (UserConfig & FLASH_OPTSR_SWAP_BANK_OPT);
1176     optr_reg_mask |= FLASH_OPTSR_SWAP_BANK_OPT;
1177   }
1178 
1179   if((UserType & OB_USER_IOHSLV) != 0U)
1180   {
1181     /* IOHSLV_OPT option byte should be modified */
1182     assert_param(IS_OB_USER_IOHSLV(UserConfig & FLASH_OPTSR_IO_HSLV));
1183 
1184     /* Set value and mask for IOHSLV_OPT option byte */
1185     optr_reg_val |= (UserConfig & FLASH_OPTSR_IO_HSLV);
1186     optr_reg_mask |= FLASH_OPTSR_IO_HSLV;
1187   }
1188 
1189   /* Configure the option bytes register */
1190   MODIFY_REG(FLASH->OPTSR_PRG, optr_reg_mask, optr_reg_val);
1191 }
1192 
1193 #if defined(DUAL_CORE)
1194 /**
1195   * @brief  Return the FLASH User Option Byte value.
1196   * @retval The FLASH User Option Bytes values
1197   *         IWDG1_SW(Bit4), IWDG2_SW(Bit 5), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1198   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1199   *         SECURITY(Bit 21), BCM4(Bit 22), BCM7(Bit 23), nRST_STOP_D2(Bit 24),
1200   *         nRST_STDY_D2(Bit 25), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1201   */
1202 #else
1203 /**
1204   * @brief  Return the FLASH User Option Byte value.
1205   * @retval The FLASH User Option Bytes values
1206   *         IWDG_SW(Bit4), nRST_STOP_D1(Bit 6), nRST_STDY_D1(Bit 7),
1207   *         FZ_IWDG_STOP(Bit 17), FZ_IWDG_SDBY(Bit 18), ST_RAM_SIZE(Bit[19:20]),
1208   *         SECURITY(Bit 21), IO_HSLV (Bit 29) and SWAP_BANK_OPT(Bit 31).
1209   */
1210 #endif /*DUAL_CORE*/
FLASH_OB_GetUser(void)1211 static uint32_t FLASH_OB_GetUser(void)
1212 {
1213   uint32_t userConfig = READ_REG(FLASH->OPTSR_CUR);
1214   userConfig &= (~(FLASH_OPTSR_BOR_LEV | FLASH_OPTSR_RDP));
1215 
1216   return userConfig;
1217 }
1218 
1219 /**
1220   * @brief  Configure the Proprietary code readout protection of the desired addresses
1221   *
1222   * @note   To configure the PCROP options, the option lock bit OPTLOCK must be
1223   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
1224   * @note   To validate the PCROP options, the option bytes must be reloaded
1225   *         through the call of the HAL_FLASH_OB_Launch() function.
1226   *
1227   * @param  PCROPConfig specifies if the PCROP area for the given Bank shall be erased or not
1228   *         when RDP level decreased from Level 1 to Level 0, or after a bank erase with protection removal
1229   *         This parameter must be a value of @arg FLASHEx_OB_PCROP_RDP enumeration
1230   *
1231   * @param  PCROPStartAddr specifies the start address of the Proprietary code readout protection
1232   *          This parameter can be an address between begin and end of the bank
1233   *
1234   * @param  PCROPEndAddr specifies the end address of the Proprietary code readout protection
1235   *          This parameter can be an address between PCROPStartAddr and end of the bank
1236   *
1237   * @param  Banks the specific bank to apply PCROP protection
1238   *          This parameter can be one of the following values:
1239   *            @arg FLASH_BANK_1: PCROP on specified bank1 area
1240   *            @arg FLASH_BANK_2: PCROP on specified bank2 area
1241   *            @arg FLASH_BANK_BOTH: PCROP on specified bank1 and bank2 area (same config will be applied on both banks)
1242   *
1243   * @retval None
1244   */
FLASH_OB_PCROPConfig(uint32_t PCROPConfig,uint32_t PCROPStartAddr,uint32_t PCROPEndAddr,uint32_t Banks)1245 static void FLASH_OB_PCROPConfig(uint32_t PCROPConfig, uint32_t PCROPStartAddr, uint32_t PCROPEndAddr, uint32_t Banks)
1246 {
1247   /* Check the parameters */
1248   assert_param(IS_FLASH_BANK(Banks));
1249   assert_param(IS_OB_PCROP_RDP(PCROPConfig));
1250 
1251   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1252   {
1253     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPStartAddr));
1254     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(PCROPEndAddr));
1255 
1256     /* Configure the Proprietary code readout protection */
1257     FLASH->PRAR_PRG1 = ((PCROPStartAddr - FLASH_BANK1_BASE) >> 8)                                 | \
1258                        (((PCROPEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
1259                        PCROPConfig;
1260   }
1261 
1262   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1263   {
1264     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPStartAddr));
1265     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(PCROPEndAddr));
1266 
1267     /* Configure the Proprietary code readout protection */
1268     FLASH->PRAR_PRG2 = ((PCROPStartAddr - FLASH_BANK2_BASE) >> 8)                                 | \
1269                        (((PCROPEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_PRAR_PROT_AREA_END_Pos) | \
1270                        PCROPConfig;
1271   }
1272 }
1273 
1274 /**
1275   * @brief  Get the Proprietary code readout protection configuration on a given Bank
1276   *
1277   * @param  PCROPConfig indicates if the PCROP area for the given Bank shall be erased or not
1278   *         when RDP level decreased from Level 1 to Level 0 or after a bank erase with protection removal
1279   *
1280   * @param  PCROPStartAddr gives the start address of the Proprietary code readout protection of the bank
1281   *
1282   * @param  PCROPEndAddr gives the end address of the Proprietary code readout protection of the bank
1283   *
1284   * @param  Bank the specific bank to apply PCROP protection
1285   *          This parameter can be exclusively one of the following values:
1286   *            @arg FLASH_BANK_1: PCROP on specified bank1 area
1287   *            @arg FLASH_BANK_2: PCROP on specified bank2 area
1288   *            @arg FLASH_BANK_BOTH: is  not allowed here
1289   *
1290   * @retval None
1291   */
FLASH_OB_GetPCROP(uint32_t * PCROPConfig,uint32_t * PCROPStartAddr,uint32_t * PCROPEndAddr,uint32_t Bank)1292 static void FLASH_OB_GetPCROP(uint32_t *PCROPConfig, uint32_t *PCROPStartAddr, uint32_t *PCROPEndAddr, uint32_t Bank)
1293 {
1294   uint32_t regvalue = 0;
1295   uint32_t bankBase = 0;
1296 
1297   if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1)
1298   {
1299     regvalue = FLASH->PRAR_CUR1;
1300     bankBase = FLASH_BANK1_BASE;
1301   }
1302 
1303   if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2)
1304   {
1305     regvalue = FLASH->PRAR_CUR2;
1306     bankBase = FLASH_BANK2_BASE;
1307   }
1308 
1309   (*PCROPConfig) =  (regvalue & FLASH_PRAR_DMEP);
1310 
1311   (*PCROPStartAddr) = ((regvalue & FLASH_PRAR_PROT_AREA_START) << 8) + bankBase;
1312   (*PCROPEndAddr) = (regvalue & FLASH_PRAR_PROT_AREA_END) >> FLASH_PRAR_PROT_AREA_END_Pos;
1313   (*PCROPEndAddr) = ((*PCROPEndAddr) << 8) + bankBase;
1314 }
1315 
1316 /**
1317   * @brief  Set the BOR Level.
1318   * @param  Level specifies the Option Bytes BOR Reset Level.
1319   *          This parameter can be one of the following values:
1320   *            @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
1321   *            @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
1322   *            @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
1323   *            @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
1324   * @retval None
1325   */
FLASH_OB_BOR_LevelConfig(uint32_t Level)1326 static void FLASH_OB_BOR_LevelConfig(uint32_t Level)
1327 {
1328   assert_param(IS_OB_BOR_LEVEL(Level));
1329 
1330   /* Configure BOR_LEV option byte */
1331   MODIFY_REG(FLASH->OPTSR_PRG, FLASH_OPTSR_BOR_LEV, Level);
1332 }
1333 
1334 /**
1335   * @brief  Get the BOR Level.
1336   * @retval The Option Bytes BOR Reset Level.
1337   *            This parameter can be one of the following values:
1338   *            @arg OB_BOR_LEVEL0: Reset level threshold is set to 1.6V
1339   *            @arg OB_BOR_LEVEL1: Reset level threshold is set to 2.1V
1340   *            @arg OB_BOR_LEVEL2: Reset level threshold is set to 2.4V
1341   *            @arg OB_BOR_LEVEL3: Reset level threshold is set to 2.7V
1342   */
FLASH_OB_GetBOR(void)1343 static uint32_t FLASH_OB_GetBOR(void)
1344 {
1345   return (FLASH->OPTSR_CUR & FLASH_OPTSR_BOR_LEV);
1346 }
1347 
1348 /**
1349   * @brief  Set Boot address
1350   * @param  BootOption Boot address option byte to be programmed,
1351   *                     This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
1352                         (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
1353   *
1354   * @param  BootAddress0 Specifies the Boot Address 0
1355   * @param  BootAddress1 Specifies the Boot Address 1
1356   * @retval HAL Status
1357   */
FLASH_OB_BootAddConfig(uint32_t BootOption,uint32_t BootAddress0,uint32_t BootAddress1)1358 static void FLASH_OB_BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
1359 {
1360   /* Check the parameters */
1361   assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
1362 
1363   if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
1364   {
1365     /* Check the parameters */
1366     assert_param(IS_BOOT_ADDRESS(BootAddress0));
1367 
1368     /* Configure CM7 BOOT ADD0 */
1369 #if defined(DUAL_CORE)
1370     MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD0, (BootAddress0 >> 16));
1371 #else /* Single Core*/
1372     MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD0, (BootAddress0 >> 16));
1373 #endif /* DUAL_CORE */
1374   }
1375 
1376   if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
1377   {
1378     /* Check the parameters */
1379     assert_param(IS_BOOT_ADDRESS(BootAddress1));
1380 
1381     /* Configure CM7 BOOT ADD1 */
1382 #if defined(DUAL_CORE)
1383     MODIFY_REG(FLASH->BOOT7_PRG, FLASH_BOOT7_BCM7_ADD1, BootAddress1);
1384 #else /* Single Core*/
1385     MODIFY_REG(FLASH->BOOT_PRG, FLASH_BOOT_ADD1, BootAddress1);
1386 #endif /* DUAL_CORE */
1387   }
1388 }
1389 
1390 /**
1391   * @brief  Get Boot address
1392   * @param  BootAddress0 Specifies the Boot Address 0.
1393   * @param  BootAddress1 Specifies the Boot Address 1.
1394   * @retval HAL Status
1395   */
FLASH_OB_GetBootAdd(uint32_t * BootAddress0,uint32_t * BootAddress1)1396 static void FLASH_OB_GetBootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
1397 {
1398   uint32_t regvalue;
1399 
1400 #if defined(DUAL_CORE)
1401   regvalue = FLASH->BOOT7_CUR;
1402 
1403   (*BootAddress0) = (regvalue & FLASH_BOOT7_BCM7_ADD0) << 16;
1404   (*BootAddress1) = (regvalue & FLASH_BOOT7_BCM7_ADD1);
1405 #else /* Single Core */
1406   regvalue = FLASH->BOOT_CUR;
1407 
1408   (*BootAddress0) = (regvalue & FLASH_BOOT_ADD0) << 16;
1409   (*BootAddress1) = (regvalue & FLASH_BOOT_ADD1);
1410 #endif /* DUAL_CORE */
1411 }
1412 
1413 #if defined(DUAL_CORE)
1414 /**
1415   * @brief  Set CM4 Boot address
1416   * @param  BootOption Boot address option byte to be programmed,
1417   *                     This parameter must be a value of @ref FLASHEx_OB_BOOT_OPTION
1418                         (OB_BOOT_ADD0, OB_BOOT_ADD1 or OB_BOOT_ADD_BOTH)
1419   *
1420   * @param  BootAddress0 Specifies the CM4 Boot Address 0.
1421   * @param  BootAddress1 Specifies the CM4 Boot Address 1.
1422   * @retval HAL Status
1423   */
FLASH_OB_CM4BootAddConfig(uint32_t BootOption,uint32_t BootAddress0,uint32_t BootAddress1)1424 static void FLASH_OB_CM4BootAddConfig(uint32_t BootOption, uint32_t BootAddress0, uint32_t BootAddress1)
1425 {
1426   /* Check the parameters */
1427   assert_param(IS_OB_BOOT_ADD_OPTION(BootOption));
1428 
1429   if((BootOption & OB_BOOT_ADD0) == OB_BOOT_ADD0)
1430   {
1431     /* Check the parameters */
1432     assert_param(IS_BOOT_ADDRESS(BootAddress0));
1433 
1434     /* Configure CM4 BOOT ADD0 */
1435     MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD0, (BootAddress0 >> 16));
1436 
1437   }
1438 
1439   if((BootOption & OB_BOOT_ADD1) == OB_BOOT_ADD1)
1440   {
1441     /* Check the parameters */
1442     assert_param(IS_BOOT_ADDRESS(BootAddress1));
1443 
1444     /* Configure CM4 BOOT ADD1 */
1445     MODIFY_REG(FLASH->BOOT4_PRG, FLASH_BOOT4_BCM4_ADD1, BootAddress1);
1446   }
1447 }
1448 
1449 /**
1450   * @brief  Get CM4 Boot address
1451   * @param  BootAddress0 Specifies the CM4 Boot Address 0.
1452   * @param  BootAddress1 Specifies the CM4 Boot Address 1.
1453   * @retval HAL Status
1454   */
FLASH_OB_GetCM4BootAdd(uint32_t * BootAddress0,uint32_t * BootAddress1)1455 static void FLASH_OB_GetCM4BootAdd(uint32_t *BootAddress0, uint32_t *BootAddress1)
1456 {
1457   uint32_t regvalue;
1458 
1459   regvalue = FLASH->BOOT4_CUR;
1460 
1461   (*BootAddress0) = (regvalue & FLASH_BOOT4_BCM4_ADD0) << 16;
1462   (*BootAddress1) = (regvalue & FLASH_BOOT4_BCM4_ADD1);
1463 }
1464 #endif /*DUAL_CORE*/
1465 
1466 /**
1467   * @brief  Set secure area configuration
1468   * @param  SecureAreaConfig specify if the secure area will be deleted or not
1469   *         when RDP level decreased from Level 1 to Level 0 or during a mass erase.
1470   *
1471   * @param  SecureAreaStartAddr Specifies the secure area start address
1472   * @param  SecureAreaEndAddr Specifies the secure area end address
1473   * @param  Banks the specific bank to apply Security protection
1474   *          This parameter can be one of the following values:
1475   *            @arg FLASH_BANK_1: Secure area on specified bank1 area
1476   *            @arg FLASH_BANK_2: Secure area on specified bank2 area
1477   *            @arg FLASH_BANK_BOTH: Secure area on specified bank1 and bank2 area (same config will be applied on both banks)
1478   * @retval None
1479   */
FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig,uint32_t SecureAreaStartAddr,uint32_t SecureAreaEndAddr,uint32_t Banks)1480 static void FLASH_OB_SecureAreaConfig(uint32_t SecureAreaConfig, uint32_t SecureAreaStartAddr, uint32_t SecureAreaEndAddr, uint32_t Banks)
1481 {
1482   /* Check the parameters */
1483   assert_param(IS_FLASH_BANK(Banks));
1484   assert_param(IS_OB_SECURE_RDP(SecureAreaConfig));
1485 
1486   if((Banks & FLASH_BANK_1) == FLASH_BANK_1)
1487   {
1488     /* Check the parameters */
1489     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaStartAddr));
1490     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(SecureAreaEndAddr));
1491 
1492     /* Configure the secure area */
1493     FLASH->SCAR_PRG1 = ((SecureAreaStartAddr - FLASH_BANK1_BASE) >> 8)                                | \
1494                        (((SecureAreaEndAddr - FLASH_BANK1_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
1495                        (SecureAreaConfig & FLASH_SCAR_DMES);
1496   }
1497 
1498   if((Banks & FLASH_BANK_2) == FLASH_BANK_2)
1499   {
1500     /* Check the parameters */
1501     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaStartAddr));
1502     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(SecureAreaEndAddr));
1503 
1504     /* Configure the secure area */
1505     FLASH->SCAR_PRG2 = ((SecureAreaStartAddr - FLASH_BANK2_BASE) >> 8)                                | \
1506                        (((SecureAreaEndAddr - FLASH_BANK2_BASE) >> 8) << FLASH_SCAR_SEC_AREA_END_Pos) | \
1507                        (SecureAreaConfig & FLASH_SCAR_DMES);
1508   }
1509 }
1510 
1511 /**
1512   * @brief  Get secure area configuration
1513   * @param  SecureAreaConfig indicates if the secure area will be deleted or not
1514   *         when RDP level decreased from Level 1 to Level 0 or during a mass erase.
1515   * @param  SecureAreaStartAddr gives the secure area start address
1516   * @param  SecureAreaEndAddr gives the secure area end address
1517   * @param  Bank Specifies the Bank
1518   * @retval None
1519   */
FLASH_OB_GetSecureArea(uint32_t * SecureAreaConfig,uint32_t * SecureAreaStartAddr,uint32_t * SecureAreaEndAddr,uint32_t Bank)1520 static void FLASH_OB_GetSecureArea(uint32_t *SecureAreaConfig, uint32_t *SecureAreaStartAddr, uint32_t *SecureAreaEndAddr, uint32_t Bank)
1521 {
1522   uint32_t regvalue = 0;
1523   uint32_t bankBase = 0;
1524 
1525   /* Check Bank parameter value */
1526   if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_1)
1527   {
1528     regvalue = FLASH->SCAR_CUR1;
1529     bankBase = FLASH_BANK1_BASE;
1530   }
1531 
1532   if((Bank & FLASH_BANK_BOTH) == FLASH_BANK_2)
1533   {
1534     regvalue = FLASH->SCAR_CUR2;
1535     bankBase = FLASH_BANK2_BASE;
1536   }
1537 
1538   /* Get the secure area settings */
1539   (*SecureAreaConfig) = (regvalue & FLASH_SCAR_DMES);
1540   (*SecureAreaStartAddr) = ((regvalue & FLASH_SCAR_SEC_AREA_START) << 8) + bankBase;
1541   (*SecureAreaEndAddr) = (regvalue & FLASH_SCAR_SEC_AREA_END) >> FLASH_SCAR_SEC_AREA_END_Pos;
1542   (*SecureAreaEndAddr) = ((*SecureAreaEndAddr) << 8) + bankBase;
1543 }
1544 
1545 /**
1546   * @brief  Add a CRC sector to the list of sectors on which the CRC will be calculated
1547   * @param  Sector Specifies the CRC sector number
1548   * @param  Bank Specifies the Bank
1549   * @retval None
1550   */
FLASH_CRC_AddSector(uint32_t Sector,uint32_t Bank)1551 static void FLASH_CRC_AddSector(uint32_t Sector, uint32_t Bank)
1552 {
1553   /* Check the parameters */
1554   assert_param(IS_FLASH_SECTOR(Sector));
1555 
1556   if (Bank == FLASH_BANK_1)
1557   {
1558     /* Clear CRC sector */
1559     FLASH->CRCCR1 &= (~FLASH_CRCCR_CRC_SECT);
1560 
1561     /* Select CRC Sector and activate ADD_SECT bit */
1562     FLASH->CRCCR1 |= Sector | FLASH_CRCCR_ADD_SECT;
1563   }
1564   else
1565   {
1566     /* Clear CRC sector */
1567     FLASH->CRCCR2 &= (~FLASH_CRCCR_CRC_SECT);
1568 
1569     /* Select CRC Sector and activate ADD_SECT bit */
1570     FLASH->CRCCR2 |= Sector | FLASH_CRCCR_ADD_SECT;
1571   }
1572 }
1573 
1574 /**
1575   * @brief  Select CRC start and end memory addresses on which the CRC will be calculated
1576   * @param  CRCStartAddr Specifies the CRC start address
1577   * @param  CRCEndAddr Specifies the CRC end address
1578   * @param  Bank Specifies the Bank
1579   * @retval None
1580   */
FLASH_CRC_SelectAddress(uint32_t CRCStartAddr,uint32_t CRCEndAddr,uint32_t Bank)1581 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr, uint32_t Bank)
1582 {
1583   if (Bank == FLASH_BANK_1)
1584   {
1585     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCStartAddr));
1586     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK1(CRCEndAddr));
1587 
1588     /* Write CRC Start and End addresses */
1589     FLASH->CRCSADD1 = CRCStartAddr;
1590     FLASH->CRCEADD1 = CRCEndAddr;
1591   }
1592   else
1593   {
1594     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCStartAddr));
1595     assert_param(IS_FLASH_PROGRAM_ADDRESS_BANK2(CRCEndAddr));
1596 
1597     /* Write CRC Start and End addresses */
1598     FLASH->CRCSADD2 = CRCStartAddr;
1599     FLASH->CRCEADD2 = CRCEndAddr;
1600   }
1601 }
1602 /**
1603   * @}
1604   */
1605 
1606 #endif /* HAL_FLASH_MODULE_ENABLED */
1607 
1608 /**
1609   * @}
1610   */
1611 
1612 /**
1613   * @}
1614   */
1615 
1616 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1617