1 /**
2   ******************************************************************************
3   * @file    stm32h7rsxx_hal_flash_ex.c
4   * @author  MCD Application Team
5   * @brief   Extended FLASH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the FLASH extended peripheral:
8   *           + Extended programming operations functions
9   *
10  @verbatim
11  ==============================================================================
12                    ##### Flash Extended features #####
13  ==============================================================================
14 
15   [..] Comparing to other previous devices, the FLASH interface for STM32H7RSxx
16        devices contains the following additional features
17 
18        (+) Non-volatile state, Root-Of-Trust and Epoch option bytes
19        (+) Option byte keys associated with hide protection level
20        (+) CRC hardware module to check integrity
21        (+) OTP blocks lock mechanism
22 
23                         ##### How to use this driver #####
24  ==============================================================================
25   [..] This driver provides functions to configure and program the FLASH memory
26        of all STM32H7RSxx devices. It includes:
27       (#) Flash Memory Erase functions:
28         (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
29              HAL_FLASH_Lock() functions
30         (++) Erase function: Sector Erase and Mass Erase
31         (++) There are two modes of erase :
32           (+++) Polling Mode using HAL_FLASHEx_Erase()
33           (+++) Interrupt Mode using HAL_FLASHEx_Erase_IT()
34 
35       (#) Option Bytes Programming function: Use HAL_FLASHEx_OBProgram() to:
36         (++) Configure the write protection for each sector
37         (++) Program the user Option Bytes
38         (++) Configure the hide protection area
39         (++) Configure the non-volatile state
40 
41       (#) Get Option Bytes Configuration function: Use HAL_FLASHEx_OBGetConfig() to:
42         (++) Get the value of the sectors write protection
43         (++) Get the value of the user Option Bytes
44         (++) Get the configuration of the hide protection area
45         (++) Get the value of the non-volatile state
46         (++) Get the value of the Root-Of-Trust configuration
47         (++) Get the value of the Epoch
48 
49       (#) OTP lock configuration function: Use HAL_FLASHEx_OTPLockConfig()
50         (++) Activate the lock of an OTP block
51 
52       (#) Get the OTP lock configuration function: Use HAL_FLASHEx_GetOTPLock()
53         (++) Get the value of the OTP blocks lock configuration
54 
55       (#) Option Byte Keys configuration function: Use HAL_FLASHEx_KeyConfig()
56         (++) Program an option key for a specified hide protection level
57 
58       (#) Get an option byte key value: Use HAL_FLASHEx_GetKey()
59         (++) Get the value of an option byte key for a specified hide protection level
60 
61       (#) Perform a CRC computation function: Use HAL_FLASHEx_ComputeCRC()
62         (++) Perform CRC computation on a area defined either by sectors or by start/end
63 		     addresses and return computation result
64 
65       (#) ECC management functions:
66         (++) Handle ECC Detection flash interrupt by calling HAL_FLASHEx_ECCD_IRQHandler()
67         (++) Callback functions are called when the ECC detection or correction occurs :
68              HAL_FLASHEx_EccDetectionCallback() for ECC detection, otherwise
69              HAL_FLASHEx_EccCorrectionCallback()
70         (++) Get information about ECC error by calling HAL_FLASHEx_GetEccInfo()
71         (++) Enable/Disable the ECC correction and detection interrupts:
72           (+++) HAL_FLASHEx_EnableEccCorrectionInterrupt() to enable ECC correction interrupt
73           (+++) HAL_FLASHEx_DisableEccCorrectionInterrupt() to disable ECC correction interrupt
74           (+++) HAL_FLASHEx_EnableEccDetectionInterrupt() to enable ECC detection interrupt
75           (+++) HAL_FLASHEx_DisableEccDetectionInterrupt() to disable ECC detection interrupt
76 
77  @endverbatim
78   ******************************************************************************
79   * @attention
80   *
81   * Copyright (c) 2022 STMicroelectronics.
82   * All rights reserved.
83   *
84   * This software is licensed under terms that can be found in the LICENSE file
85   * in the root directory of this software component.
86   * If no LICENSE file comes with this software, it is provided AS-IS.
87   *
88   ******************************************************************************
89   */
90 
91 /* Includes ------------------------------------------------------------------*/
92 #include "stm32h7rsxx_hal.h"
93 
94 /** @addtogroup STM32H7RSxx_HAL_Driver
95   * @{
96   */
97 
98 /** @defgroup FLASHEx FLASHEx
99   * @brief FLASH Extended HAL module driver
100   * @{
101   */
102 
103 #ifdef HAL_FLASH_MODULE_ENABLED
104 
105 /* Private typedef -----------------------------------------------------------*/
106 /* Private define ------------------------------------------------------------*/
107 #define SYSTEM_FLASH_SIZE  0x00020000UL  /*!< System Flash size : 128 KB */
108 /* Private macro -------------------------------------------------------------*/
109 /* Private variables ---------------------------------------------------------*/
110 /* Private function prototypes -----------------------------------------------*/
111 /** @defgroup FLASHEx_Private_Functions FLASHEx Private Functions
112   * @{
113   */
114 static void              FLASH_MassErase(void);
115 
116 static void              FLASH_OB_WRPConfig(uint32_t WRPState, uint32_t WRPSector);
117 static void              FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2);
118 static void              FLASH_OB_HDPConfig(uint32_t HDPStartPage, uint32_t HDPEndPage);
119 static void              FLASH_OB_NVConfig(uint32_t NVState);
120 
121 static void              FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector);
122 static void              FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2);
123 static void              FLASH_OB_GetHDP(uint32_t *HDPStartPage, uint32_t *HDPEndPage);
124 static uint32_t          FLASH_OB_GetNV(void);
125 static uint32_t          FLASH_OB_GetRoT(void);
126 static uint32_t          FLASH_OB_GetEpoch(void);
127 
128 static void              FLASH_CRC_AddSector(uint32_t Sector);
129 static void              FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr);
130 static HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout);
131 /**
132   * @}
133   */
134 
135 /* Exported functions -------------------------------------------------------*/
136 /** @defgroup FLASHEx_Exported_Functions FLASH Extended Exported Functions
137   * @{
138   */
139 
140 /** @defgroup FLASHEx_Exported_Functions_Group1 Extended IO operation functions
141   *  @brief   Extended IO operation functions
142   *
143 @verbatim
144  ===============================================================================
145                 ##### Extended programming operation functions #####
146  ===============================================================================
147     [..]
148     This subsection provides a set of functions allowing to manage the Extended FLASH
149     programming operations Operations.
150 
151 @endverbatim
152   * @{
153   */
154 /**
155   * @brief  Perform a mass erase or erase the specified FLASH memory sectors.
156   * @param[in]  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
157   *         contains the configuration information for the erasing.
158   *
159   * @param[out]  SectorError pointer to variable that contains the configuration
160   *         information on faulty sector in case of error (0xFFFFFFFF means that all
161   *         the sectors have been correctly erased).
162   *
163   * @retval HAL Status
164   */
HAL_FLASHEx_Erase(const FLASH_EraseInitTypeDef * pEraseInit,uint32_t * SectorError)165 HAL_StatusTypeDef HAL_FLASHEx_Erase(const FLASH_EraseInitTypeDef *pEraseInit, uint32_t *SectorError)
166 {
167   HAL_StatusTypeDef status;
168   uint32_t sector_index;
169 
170   /* Check the parameters */
171   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
172 
173   /* Process Locked */
174   __HAL_LOCK(&pFlash);
175 
176   /* Reset error code */
177   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
178 
179   /* Wait for last operation to be completed */
180   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
181 
182   if (status == HAL_OK)
183   {
184     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
185     {
186       /* Mass erase to be done */
187       FLASH_MassErase();
188 
189       /* Wait for last operation to be completed */
190       status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
191     }
192     else
193     {
194       /*Initialization of SectorError variable*/
195       *SectorError = 0xFFFFFFFFU;
196 
197       for (sector_index = pEraseInit->Sector; sector_index < (pEraseInit->Sector + pEraseInit->NbSectors);
198            sector_index++)
199       {
200         FLASH_SectorErase(sector_index);
201 
202         /* Wait for last operation to be completed */
203         status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
204 
205         if (status != HAL_OK)
206         {
207           /* In case of error, stop erase procedure and return the faulty sector */
208           *SectorError = sector_index;
209           break;
210         }
211       }
212     }
213 
214     /* If the erase operation is completed, disable the associated bits */
215     CLEAR_BIT(FLASH->CR, (pEraseInit->TypeErase | FLASH_CR_SSN));
216   }
217 
218   /* Process Unlocked */
219   __HAL_UNLOCK(&pFlash);
220 
221   return status;
222 }
223 
224 /**
225   * @brief  Perform a mass erase or erase the specified FLASH memory sectors with interrupt enabled.
226   * @param  pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
227   *         contains the configuration information for the erasing.
228   *
229   * @retval HAL Status
230   */
HAL_FLASHEx_Erase_IT(const FLASH_EraseInitTypeDef * pEraseInit)231 HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(const FLASH_EraseInitTypeDef *pEraseInit)
232 {
233   HAL_StatusTypeDef status;
234 
235   /* Check the parameters */
236   assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
237 
238   /* Process Locked */
239   __HAL_LOCK(&pFlash);
240 
241   /* Reset error code */
242   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
243 
244   /* Wait for last operation to be completed */
245   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
246 
247   if (status != HAL_OK)
248   {
249     /* Process Unlocked */
250     __HAL_UNLOCK(&pFlash);
251   }
252   else
253   {
254     /* Set internal variables used by the IRQ handler */
255     pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
256 
257     /* Enable End of Operation and Error interrupts */
258     SET_BIT(FLASH->IER, (FLASH_IT_EOP | FLASH_IT_WRPERR | FLASH_IT_PGSERR | FLASH_IT_STRBERR | FLASH_IT_INCERR));
259 
260     if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
261     {
262       /* Mass erase to be done */
263       FLASH_MassErase();
264     }
265     else
266     {
267       /* Erase by sector to be done */
268       pFlash.NbSectorsToErase = pEraseInit->NbSectors;
269       pFlash.Sector = pEraseInit->Sector;
270 
271       /* Erase first sector and wait for IT */
272       FLASH_SectorErase(pEraseInit->Sector);
273     }
274   }
275 
276   return status;
277 }
278 
279 /**
280   * @brief  Program Option bytes.
281   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that
282   *         contains the configuration information for the programming.
283   *
284   * @note   To configure any option bytes, the option lock bit OPTLOCK must be
285   *         cleared with the call of HAL_FLASH_OB_Unlock() function.
286   * @note   New option bytes configuration will be taken into account in two cases:
287   *         - after an option bytes launch through the call of HAL_FLASH_OB_Launch()
288   *         - after a power reset (BOR reset or exit from Standby/Shutdown modes)
289   *
290   * @retval HAL Status
291   */
HAL_FLASHEx_OBProgram(const FLASH_OBProgramInitTypeDef * pOBInit)292 HAL_StatusTypeDef HAL_FLASHEx_OBProgram(const FLASH_OBProgramInitTypeDef *pOBInit)
293 {
294   HAL_StatusTypeDef status;
295 
296   /* Check the parameters */
297   assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
298 
299   /* Process Locked */
300   __HAL_LOCK(&pFlash);
301 
302   /* Reset error code */
303   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
304 
305   /* Wait for last operation to be completed */
306   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
307 
308   if ((status == HAL_OK) && (pOBInit->OptionType != 0U))
309   {
310     /* Set PG_OPT Bit */
311     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
312 
313     /* Write protection configuration */
314     if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0U)
315     {
316       /* Configure of Write protection on the selected area */
317       FLASH_OB_WRPConfig(pOBInit->WRPState, pOBInit->WRPSector);
318     }
319 
320     /* User Configuration */
321     if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0U)
322     {
323       /* Configure the user option bytes */
324       FLASH_OB_UserConfig(pOBInit->USERType, pOBInit->USERConfig1, pOBInit->USERConfig2);
325     }
326 
327     /* HDP configuration */
328     if ((pOBInit->OptionType & OPTIONBYTE_HDP) != 0U)
329     {
330       /* Configure the HDP Protection */
331       FLASH_OB_HDPConfig(pOBInit->HDPStartPage, pOBInit->HDPEndPage);
332     }
333 
334     /* Non-volatile state configuration */
335     if ((pOBInit->OptionType & OPTIONBYTE_NV) != 0U)
336     {
337       /* Configure the non-volatile state */
338       FLASH_OB_NVConfig(pOBInit->NVState);
339     }
340 
341     /* Wait for last operation to be completed */
342     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
343 
344     /* Clear PG_OPT Bit */
345     CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
346   }
347 
348   /* Process Unlocked */
349   __HAL_UNLOCK(&pFlash);
350 
351   return status;
352 }
353 
354 /**
355   * @brief  Get the Option bytes configuration.
356   * @param  pOBInit pointer to an FLASH_OBInitStruct structure that contains the
357   *                  configuration information.
358   * @note   The fields pOBInit->WRPArea, pOBInit->WMSecConfig and pOBInit->BootAddrConfig
359   *         should indicate which area/address is requested for the WRP, WM Security or
360   *         Boot Address, else no information will be returned
361   *
362   * @retval None
363   */
HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef * pOBInit)364 void HAL_FLASHEx_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
365 {
366   /* Get write protection on the selected area */
367   FLASH_OB_GetWRP(&(pOBInit->WRPState), &(pOBInit->WRPSector));
368 
369   /* Get the user option bytes */
370   FLASH_OB_GetUser(&(pOBInit->USERConfig1), &(pOBInit->USERConfig2));
371 
372   /* Get the HDP Protection */
373   FLASH_OB_GetHDP(&(pOBInit->HDPStartPage), &(pOBInit->HDPEndPage));
374 
375   /* Get the non-volatile state */
376   pOBInit->NVState = FLASH_OB_GetNV();
377 
378   /* Get the Root-Of-Trust configuration */
379   pOBInit->ROTConfig = FLASH_OB_GetRoT();
380 
381   /* Get the epoch */
382   pOBInit->EPOCH = FLASH_OB_GetEpoch();
383 }
384 
385 /**
386   * @}
387   */
388 
389 /** @defgroup FLASHEx_Exported_Functions_Group2 Extended protection operation functions
390   *  @brief   Extended protection operation functions
391   *
392 @verbatim
393  ===============================================================================
394                ##### Extended protection operation functions #####
395  ===============================================================================
396     [..]
397     This subsection provides a set of functions allowing to manage the Extended FLASH
398     CRC operations, OTP lock mechanism and option byte keys management.
399 
400 @endverbatim
401   * @{
402   */
403 /**
404   * @brief  Configure the OTP Lock.
405   *
406   * @note   To configure the OTP Lock options, the option lock bit OPTLOCK must be
407   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
408   *
409   * @param  OTPLBlock Specifies the block(s) to be OTP locked (used for OPTIONBYTE_OTPL).
410   *                   The value of this parameter depend on device used within the same series
411   *
412   * @retval HAL Status
413   */
HAL_FLASHEx_OTPLockConfig(uint32_t OTPLBlock)414 HAL_StatusTypeDef HAL_FLASHEx_OTPLockConfig(uint32_t OTPLBlock)
415 {
416   HAL_StatusTypeDef status;
417 
418   /* Check the parameters */
419   assert_param(IS_OB_OTP_BLOCK(OTPLBlock));
420 
421   /* Process Locked */
422   __HAL_LOCK(&pFlash);
423 
424   /* Reset error code */
425   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
426 
427   /* Wait for last operation to be completed */
428   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
429 
430   if (status == HAL_OK)
431   {
432     /* Set the bit for the OTP programmation */
433     SET_BIT(FLASH->CR, FLASH_CR_PG_OTP);
434 
435     /* Set PG_OPT Bit */
436     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
437 
438     /* Configure the write protected area */
439     MODIFY_REG(FLASH->OTPLSRP, FLASH_OTPLSRP_OTPL, (OTPLBlock & FLASH_OTPLSRP_OTPL));
440 
441     /* Wait for last operation to be completed */
442     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
443 
444     /* Clear PG_OPT Bit */
445     CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
446 
447     /* Clear the bit for the OTP programmation */
448     CLEAR_BIT(FLASH->CR, FLASH_CR_PG_OTP);
449   }
450 
451   /* Process Unlocked */
452   __HAL_UNLOCK(&pFlash);
453 
454   return status;
455 }
456 
457 /**
458   * @brief  Return the FLASH OTP Lock Option Bytes value.
459   *
460   * @retval Status of the OTP Lock
461   */
HAL_FLASHEx_GetOTPLock(void)462 uint32_t HAL_FLASHEx_GetOTPLock(void)
463 {
464   return (FLASH->OTPLSR & FLASH_OTPLSR_OTPL);
465 }
466 
467 /**
468   * @brief  Configure the Keys.
469   *
470   * @note   To configure the Keys options, the option lock bit OPTLOCK must be
471   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
472   *
473   * @param  pKeyConfig Key(s) to be configured.
474   *
475   * @param  pKey Address of the key
476   *
477   * @retval HAL Status
478   */
HAL_FLASHEx_KeyConfig(const FLASH_KeyConfigTypeDef * pKeyConfig,const uint32_t * pKey)479 HAL_StatusTypeDef HAL_FLASHEx_KeyConfig(const FLASH_KeyConfigTypeDef *pKeyConfig, const uint32_t *pKey)
480 {
481   uint32_t index;
482   uint32_t index_max;
483   const uint32_t *pdata;
484   HAL_StatusTypeDef status;
485 
486   /* Check the parameters */
487   assert_param(IS_KEY_INDEX(pKeyConfig->Index));
488   assert_param(IS_KEY_SIZE(pKeyConfig->Size));
489   assert_param(IS_KEY_HDPL_LEVEL(pKeyConfig->HDPLLevel));
490 
491   /* Process Locked */
492   __HAL_LOCK(&pFlash);
493 
494   /* Reset error code */
495   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
496 
497   /* Wait for last operation to be completed */
498   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
499 
500   if (status == HAL_OK)
501   {
502     /* Set PG_OPT Bit */
503     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
504 
505     switch (pKeyConfig->Size)
506     {
507       case FLASH_KEY_32_BITS :
508         index_max = 1U;
509         break;
510 
511       case FLASH_KEY_64_BITS :
512         index_max = 2U;
513         break;
514 
515       case FLASH_KEY_128_BITS :
516         index_max = 4U;
517         break;
518 
519       case FLASH_KEY_256_BITS :
520         index_max = 8U;
521         break;
522 
523       default:
524         /* This case should not occur */
525         index_max = 0U;
526         break;
527     }
528 
529     pdata = pKey;
530     for (index = 0U; index < index_max; index++)
531     {
532       FLASH->OBKDR[index] = pdata[index];
533     }
534 
535     MODIFY_REG(FLASH->OBKCR, (FLASH_OBKCR_OBKINDEX | FLASH_OBKCR_NEXTKL | FLASH_OBKCR_OBKSIZE),
536                (pKeyConfig->Index | pKeyConfig->HDPLLevel | pKeyConfig->Size));
537 
538     SET_BIT(FLASH->OBKCR, (FLASH_OBKCR_KEYSTART | FLASH_OBKCR_KEYPROG));
539 
540     /* Wait for last operation to be completed */
541     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
542 
543     CLEAR_BIT(FLASH->OBKCR, FLASH_OBKCR_KEYPROG);
544 
545     /* Clear PG_OPT Bit */
546     CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
547   }
548 
549   /* Process Unlocked */
550   __HAL_UNLOCK(&pFlash);
551 
552   return status;
553 }
554 
555 /**
556   * @brief  Load and optionally return the FLASH Option Bytes Key value.
557   *
558   * @param pKeyConfig Configuration of the key to be loaded and optionally returned
559   *
560   * @param pKey Address to return the FLASH Option Bytes Key value if not NULL.
561   *
562   * @retval HAL Status
563   */
HAL_FLASHEx_GetKey(const FLASH_KeyConfigTypeDef * pKeyConfig,uint32_t * pKey)564 HAL_StatusTypeDef HAL_FLASHEx_GetKey(const FLASH_KeyConfigTypeDef *pKeyConfig, uint32_t *pKey)
565 {
566   uint32_t index;
567   uint32_t index_max;
568   uint32_t *pdata;
569   HAL_StatusTypeDef status;
570 
571   /* Check the parameters */
572   assert_param(IS_KEY_INDEX(pKeyConfig->Index));
573   assert_param(IS_KEY_SIZE(pKeyConfig->Size));
574   assert_param(IS_KEY_HDPL_LEVEL(pKeyConfig->HDPLLevel));
575 
576   /* Process Locked */
577   __HAL_LOCK(&pFlash);
578 
579   /* Reset error code */
580   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
581 
582   /* Wait for last operation to be completed */
583   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
584 
585   if (status == HAL_OK)
586   {
587     /* Set PG_OPT Bit */
588     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
589 
590     /* Configure index and HDPL level */
591     MODIFY_REG(FLASH->OBKCR, (FLASH_OBKCR_OBKINDEX | FLASH_OBKCR_NEXTKL | FLASH_OBKCR_OBKSIZE | FLASH_OBKCR_KEYPROG),
592                (pKeyConfig->Index | pKeyConfig->HDPLLevel | pKeyConfig->Size));
593 
594     /* Set the start bit to get the key value */
595     SET_BIT(FLASH->OBKCR, FLASH_OBKCR_KEYSTART);
596 
597     /* Wait for last operation to be completed */
598     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
599 
600     if ((status == HAL_OK) && (pKey != NULL))
601     {
602       switch (pKeyConfig->Size)
603       {
604         case FLASH_KEY_32_BITS :
605           index_max = 1U;
606           break;
607 
608         case FLASH_KEY_64_BITS :
609           index_max = 2U;
610           break;
611 
612         case FLASH_KEY_128_BITS :
613           index_max = 4U;
614           break;
615 
616         case FLASH_KEY_256_BITS :
617           index_max = 8U;
618           break;
619 
620         default:
621           /* This case should not occur */
622           index_max = 0U;
623           break;
624       }
625 
626       pdata = pKey;
627       for (index = 0U; index < index_max; index++)
628       {
629         *pdata = FLASH->OBKDR[index];
630         pdata++;
631       }
632     }
633 
634     /* Clear PG_OPT Bit */
635     CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OPT);
636   }
637 
638   /* Process Unlocked */
639   __HAL_UNLOCK(&pFlash);
640 
641   return status;
642 }
643 
644 /**
645   * @brief  Perform a CRC computation on the specified FLASH memory area
646   * @param  pCRCInit pointer to an FLASH_CRCInitTypeDef structure that
647   *         contains the configuration information for the CRC computation.
648   * @param  CRC_Result pointer to CRC result
649   * @note   CRC computation uses CRC-32 (Ethernet) polynomial 0x4C11DB7
650   * @retval HAL Status
651   */
HAL_FLASHEx_ComputeCRC(const FLASH_CRCInitTypeDef * pCRCInit,uint32_t * CRC_Result)652 HAL_StatusTypeDef HAL_FLASHEx_ComputeCRC(const FLASH_CRCInitTypeDef *pCRCInit, uint32_t *CRC_Result)
653 {
654   HAL_StatusTypeDef status;
655   uint32_t sector_index;
656 
657   /* Check the parameters */
658   assert_param(IS_FLASH_TYPE_CRC(pCRCInit->TypeCRC));
659   assert_param(IS_FLASH_BURST_SIZE_CRC(pCRCInit->BurstSize));
660 
661   /* Wait for last operation to be completed */
662   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
663 
664   if (status == HAL_OK)
665   {
666     /* Process Locked */
667     __HAL_LOCK(&pFlash);
668 
669     /* Reset error code */
670     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
671 
672     /* Enable CRC feature */
673     SET_BIT(FLASH->CR, FLASH_CR_CRC_EN);
674 
675     /* Clear CRC flags in Status Register: CRC end of calculation and CRC read error */
676     FLASH->ICR = (FLASH_ICR_CRCRDERRF | FLASH_ICR_CRCENDF);
677 
678     /* Clear current CRC result and program burst size */
679     MODIFY_REG(FLASH->CRCCR, (FLASH_CRCCR_CLEAN_CRC | FLASH_CRCCR_CRC_BURST),
680                (FLASH_CRCCR_CLEAN_CRC | pCRCInit->BurstSize));
681 
682     if (pCRCInit->TypeCRC == FLASH_CRC_SECTORS)
683     {
684       /* Select CRC by sector and clear sectors list */
685       SET_BIT(FLASH->CRCCR, (FLASH_CRCCR_CRC_BY_SECT | FLASH_CRCCR_CLEAN_SECT));
686 
687       /* Select CRC sectors */
688       for (sector_index = pCRCInit->Sector; sector_index < (pCRCInit->NbSectors + pCRCInit->Sector); sector_index++)
689       {
690         FLASH_CRC_AddSector(sector_index);
691       }
692     }
693     else if (pCRCInit->TypeCRC == FLASH_CRC_BANK)
694     {
695       /* Select CRC by sector and all sectors */
696       SET_BIT(FLASH->CRCCR, (FLASH_CRCCR_CRC_BY_SECT | FLASH_CRCCR_ALL_SECT));
697     }
698     else
699     {
700       /* Select CRC by address */
701       CLEAR_BIT(FLASH->CRCCR, FLASH_CRCCR_CRC_BY_SECT);
702 
703       /* Select CRC start and end addresses */
704       FLASH_CRC_SelectAddress(pCRCInit->CRCStartAddr, pCRCInit->CRCEndAddr);
705     }
706 
707     /* Start the CRC calculation */
708     SET_BIT(FLASH->CRCCR, FLASH_CRCCR_START_CRC);
709 
710     /* Wait on CRC busy flag */
711     status = FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
712 
713     /* Return CRC result */
714     (*CRC_Result) = FLASH->CRCDATAR;
715 
716     /* Disable CRC feature */
717     CLEAR_BIT(FLASH->CR, FLASH_CR_CRC_EN);
718 
719     /* Clear CRC flags */
720     FLASH->ICR = (FLASH_ICR_CRCRDERRF | FLASH_ICR_CRCENDF);
721 
722     /* Process Unlocked */
723     __HAL_UNLOCK(&pFlash);
724   }
725 
726   return status;
727 }
728 
729 /**
730   * @}
731   */
732 
733 /** @defgroup FLASHEx_Exported_Functions_Group3 Extended ECC operation functions
734   *  @brief   Extended ECC operation functions
735   *
736 @verbatim
737  ===============================================================================
738                   ##### Extended ECC operation functions #####
739  ===============================================================================
740     [..]
741     This subsection provides a set of functions allowing to manage the Extended FLASH
742     ECC Operations.
743 
744 @endverbatim
745   * @{
746   */
747 /**
748   * @brief  Enable ECC correction interrupt
749   * @retval None
750   */
HAL_FLASHEx_EnableEccCorrectionInterrupt(void)751 void HAL_FLASHEx_EnableEccCorrectionInterrupt(void)
752 {
753   __HAL_FLASH_ENABLE_IT(FLASH_IT_SNECCERR);
754 }
755 
756 /**
757   * @brief  Disable ECC correction interrupt
758   * @retval None
759   */
HAL_FLASHEx_DisableEccCorrectionInterrupt(void)760 void HAL_FLASHEx_DisableEccCorrectionInterrupt(void)
761 {
762   __HAL_FLASH_DISABLE_IT(FLASH_IT_SNECCERR);
763 }
764 
765 /**
766   * @brief  Enable ECC detection interrupt
767   * @retval None
768   */
HAL_FLASHEx_EnableEccDetectionInterrupt(void)769 void HAL_FLASHEx_EnableEccDetectionInterrupt(void)
770 {
771   __HAL_FLASH_ENABLE_IT(FLASH_IT_DBECCERR);
772 }
773 
774 /**
775   * @brief  Disable ECC detection interrupt
776   * @retval None
777   */
HAL_FLASHEx_DisableEccDetectionInterrupt(void)778 void HAL_FLASHEx_DisableEccDetectionInterrupt(void)
779 {
780   __HAL_FLASH_DISABLE_IT(FLASH_IT_DBECCERR);
781 }
782 
783 /**
784   * @brief  Get the ECC error information.
785   * @param  pData Pointer to an FLASH_EccInfoTypeDef structure that contains the
786   *         ECC error information.
787   * @note   This function should be called before ECC bit is cleared
788   *         (in callback function)
789   * @retval None
790   */
HAL_FLASHEx_GetEccInfo(FLASH_EccInfoTypeDef * pData)791 void HAL_FLASHEx_GetEccInfo(FLASH_EccInfoTypeDef *pData)
792 {
793   /* Check Null pointer */
794   assert_param(pData != NULL);
795 
796   /* Set address which generate ECC error */
797   if ((FLASH->ISR & FLASH_FLAG_SNECCERR) != 0U)
798   {
799     pData->Address = FLASH->ECCSFADDR;
800   }
801   else
802   {
803     pData->Address = FLASH->ECCDFADDR;
804   }
805 
806   /* Set area according address */
807   if (IS_FLASH_MAIN_MEM_ADDRESS(pData->Address))
808   {
809     pData->Area = FLASH_ECC_AREA_USER_BANK1;
810   }
811   else if (IS_FLASH_OTP_ADDRESS(pData->Address))
812   {
813     pData->Area = FLASH_ECC_AREA_OTP;
814   }
815   else if ((pData->Address >= SYSTEM_FLASH_BASE) &&
816            (pData->Address < (SYSTEM_FLASH_BASE + SYSTEM_FLASH_SIZE)))
817   {
818     pData->Area = FLASH_ECC_AREA_SYSTEM;
819   }
820   else
821   {
822     pData->Area = FLASH_ECC_AREA_READ_ONLY;
823   }
824 
825   /* Set Master which initiates transaction. On H7RS, it's necessary CPU1 */
826   pData->MasterID = FLASH_ECC_MASTER_CPU1;
827 }
828 
829 /**
830   * @brief  Handle Flash ECC Detection interrupt request.
831   * @note   On STM32H7RS, this Irq Handler should be called in Bus Fault
832   *         interrupt subroutine.
833   * @retval None
834   */
HAL_FLASHEx_ECCD_IRQHandler(void)835 void HAL_FLASHEx_ECCD_IRQHandler(void)
836 {
837   /* Check ECC Detection Error */
838   if ((FLASH->ISR & FLASH_FLAG_DBECCERR) != 0U)
839   {
840     /* Call User callback */
841     HAL_FLASHEx_EccDetectionCallback();
842 
843     /* Clear ECC detection flag in order to allow new ECC error record */
844     FLASH->ICR = FLASH_FLAG_DBECCERR;
845   }
846 }
847 
848 /**
849   * @brief  FLASH ECC Correction interrupt callback.
850   * @retval None
851   */
HAL_FLASHEx_EccCorrectionCallback(void)852 __weak void HAL_FLASHEx_EccCorrectionCallback(void)
853 {
854   /* NOTE : This function should not be modified, when the callback is needed,
855             the HAL_FLASHEx_EccCorrectionCallback could be implemented in the user file
856    */
857 }
858 
859 /**
860   * @brief  FLASH ECC Detection interrupt callback.
861   * @retval None
862   */
HAL_FLASHEx_EccDetectionCallback(void)863 __weak void HAL_FLASHEx_EccDetectionCallback(void)
864 {
865   /* NOTE : This function should not be modified, when the callback is needed,
866             the HAL_FLASHEx_EccDetectionCallback could be implemented in the user file
867    */
868 }
869 
870 /**
871   * @}
872   */
873 
874 /**
875   * @}
876   */
877 
878 /* Private functions ---------------------------------------------------------*/
879 
880 /** @addtogroup FLASHEx_Private_Functions
881   * @{
882   */
883 /**
884   * @brief  Mass erase of FLASH memory.
885   * @retval None
886   */
FLASH_MassErase(void)887 static void FLASH_MassErase(void)
888 {
889   /* Set the Mass Erase Bit and proceed to erase */
890   SET_BIT(FLASH->CR, (FLASH_CR_BER | FLASH_CR_START));
891 }
892 
893 /**
894   * @brief  Erase the specified FLASH memory sector.
895   * @param  Sector FLASH sector to erase
896   *         This parameter must be a value between 0 and (max number of sectors in the bank - 1)
897   * @retval None
898   */
FLASH_SectorErase(uint32_t Sector)899 void FLASH_SectorErase(uint32_t Sector)
900 {
901   /* Check the parameters */
902   assert_param(IS_FLASH_SECTOR(Sector));
903 
904   /* Proceed to erase the page */
905   MODIFY_REG(FLASH->CR, (FLASH_CR_SSN | FLASH_CR_SER | FLASH_CR_START), \
906              ((Sector << FLASH_CR_SSN_Pos) | FLASH_CR_SER | FLASH_CR_START));
907 }
908 
909 /**
910   * @brief  Configure the write protection of the desired sectors.
911   *
912   * @note   To configure the WRP options, the option lock bit OPTLOCK must be
913   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
914   *
915   * @param  WRPState
916   *
917   * @param  WRPSector
918   *
919   * @retval None
920   */
FLASH_OB_WRPConfig(uint32_t WRPState,uint32_t WRPSector)921 static void FLASH_OB_WRPConfig(uint32_t WRPState, uint32_t WRPSector)
922 {
923   /* Check the parameters */
924   assert_param(IS_OB_WRPSTATE(WRPState));
925 
926   /* Configure the write protected area */
927   if (WRPState == OB_WRPSTATE_DISABLE)
928   {
929     FLASH->WRPSRP |= (WRPSector & FLASH_WRPSRP_WRPS);
930   }
931   else if (WRPState == OB_WRPSTATE_ENABLE)
932   {
933     FLASH->WRPSRP &= (~(WRPSector & FLASH_WRPSRP_WRPS));
934   }
935   else
936   {
937     /* Empty statement (to be compliant MISRA 15.7) */
938   }
939 }
940 
941 /**
942   * @brief  Program the FLASH User Option Byte.
943   *
944   * @note   To configure the user option bytes, the option lock bit OPTLOCK must
945   *         be cleared with the call of the HAL_FLASH_OB_Unlock() function.
946   * @param  UserType: The FLASH User Option Bytes to be modified.
947   *         This parameter can be a combination of @ref FLASH_OB_USER_TYPE
948   * @param  UserConfig1 The selected User Option Bytes values
949   * @param  UserConfig2 The selected User Option Bytes values
950   * @retval None
951   */
FLASH_OB_UserConfig(uint32_t UserType,uint32_t UserConfig1,uint32_t UserConfig2)952 static void FLASH_OB_UserConfig(uint32_t UserType, uint32_t UserConfig1, uint32_t UserConfig2)
953 {
954   uint32_t optr_reg_val = 0;
955   uint32_t optr_reg_mask = 0;
956 
957   /* Check the parameters */
958   assert_param(IS_OB_USER_TYPE(UserType));
959 
960   if ((UserType & OB_USER_BOR_LEV) != 0U)
961   {
962     /* BOR level option byte should be modified */
963     assert_param(IS_OB_USER_BOR_LEVEL(UserConfig1 & FLASH_OBW1SR_BOR_LEVEL));
964 
965     /* Set value and mask for BOR level option byte */
966     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_BOR_LEVEL);
967     optr_reg_mask |= FLASH_OBW1SR_BOR_LEVEL;
968   }
969 
970   if ((UserType & OB_USER_IWDG_SW) != 0U)
971   {
972     /* IWDG1_HW option byte should be modified */
973     assert_param(IS_OB_USER_IWDG(UserConfig1 & FLASH_OBW1SR_IWDG_HW));
974 
975     /* Set value and mask for IWDG1_HW option byte */
976     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_HW);
977     optr_reg_mask |= FLASH_OBW1SR_IWDG_HW;
978   }
979 
980   if ((UserType & OB_USER_NRST_STOP) != 0U)
981   {
982     /* NRST_STOP_D1 option byte should be modified */
983     assert_param(IS_OB_USER_STOP(UserConfig1 & FLASH_OBW1SR_NRST_STOP));
984 
985     /* Set value and mask for NRST_STOP_D1 option byte */
986     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_NRST_STOP);
987     optr_reg_mask |= FLASH_OBW1SR_NRST_STOP;
988   }
989 
990   if ((UserType & OB_USER_NRST_STDBY) != 0U)
991   {
992     /* NRST_STBY_D1 option byte should be modified */
993     assert_param(IS_OB_USER_STANDBY(UserConfig1 & FLASH_OBW1SR_NRST_STBY));
994 
995     /* Set value and mask for NRST_STBY_D1 option byte */
996     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_NRST_STBY);
997     optr_reg_mask |= FLASH_OBW1SR_NRST_STBY;
998   }
999 
1000   if ((UserType & OB_USER_XSPI1_HSLV) != 0U)
1001   {
1002     /* XSPI1_HSLV option byte should be modified */
1003     assert_param(IS_OB_USER_XSPI1_HSLV(UserConfig1 & FLASH_OBW1SR_XSPI1_HSLV));
1004 
1005     /* Set value and mask for XSPI1_HSLV option byte */
1006     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_XSPI1_HSLV);
1007     optr_reg_mask |= FLASH_OBW1SR_XSPI1_HSLV;
1008   }
1009 
1010   if ((UserType & OB_USER_XSPI2_HSLV) != 0U)
1011   {
1012     /* XSPI2_HSLV option byte should be modified */
1013     assert_param(IS_OB_USER_XSPI2_HSLV(UserConfig1 & FLASH_OBW1SR_XSPI2_HSLV));
1014 
1015     /* Set value and mask for XSPI2_HSLV option byte */
1016     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_XSPI2_HSLV);
1017     optr_reg_mask |= FLASH_OBW1SR_XSPI2_HSLV;
1018   }
1019 
1020   if ((UserType & OB_USER_IWDG_STOP) != 0U)
1021   {
1022     /* IWDG_FZ_STOP option byte should be modified */
1023     assert_param(IS_OB_USER_IWDG_STOP(UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STOP));
1024 
1025     /* Set value and mask for IWDG_FZ_STOP option byte */
1026     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STOP);
1027     optr_reg_mask |= FLASH_OBW1SR_IWDG_FZ_STOP;
1028   }
1029 
1030   if ((UserType & OB_USER_IWDG_STDBY) != 0U)
1031   {
1032     /* IWDG_FZ_SDBY option byte should be modified */
1033     assert_param(IS_OB_USER_IWDG_STDBY(UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STBY));
1034 
1035     /* Set value and mask for IWDG_FZ_SDBY option byte */
1036     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_IWDG_FZ_STBY);
1037     optr_reg_mask |= FLASH_OBW1SR_IWDG_FZ_STBY;
1038   }
1039 
1040   if ((UserType & OB_USER_VDDIO_HSLV) != 0U)
1041   {
1042     /* VDDIO_HSLV option byte should be modified */
1043     assert_param(IS_OB_USER_VDDIO_HSLV(UserConfig1 & FLASH_OBW1SR_VDDIO_HSLV));
1044 
1045     /* Set value and mask for VDDIO_HSLV option byte */
1046     optr_reg_val |= (UserConfig1 & FLASH_OBW1SR_VDDIO_HSLV);
1047     optr_reg_mask |= FLASH_OBW1SR_VDDIO_HSLV;
1048   }
1049 
1050   /* Configure the option bytes register 1 if necessary */
1051   if (optr_reg_mask != 0U)
1052   {
1053     MODIFY_REG(FLASH->OBW1SRP, optr_reg_mask, optr_reg_val);
1054   }
1055 
1056   optr_reg_val = 0;
1057   optr_reg_mask = 0;
1058 
1059   if ((UserType & OB_USER_ITCM_AXI_SHARE) != 0U)
1060   {
1061     /* ITCM_AXI_SHARE option byte should be modified */
1062     assert_param(IS_OB_USER_ITCM_AXI_SHARE(UserConfig2 & FLASH_OBW2SR_ITCM_AXI_SHARE));
1063 
1064     /* Set value and mask for ITCM_AXI_SHARE option byte */
1065     optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_ITCM_AXI_SHARE);
1066     optr_reg_mask |= FLASH_OBW2SR_ITCM_AXI_SHARE;
1067   }
1068 
1069   if ((UserType & OB_USER_DTCM_AXI_SHARE) != 0U)
1070   {
1071     /* DTCM_AXI_SHARE option byte should be modified */
1072     assert_param(IS_OB_USER_DTCM_AXI_SHARE(UserConfig2 & FLASH_OBW2SR_DTCM_AXI_SHARE));
1073 
1074     /* Set value and mask for DTCM_AXI_SHARE option byte */
1075     optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_DTCM_AXI_SHARE);
1076     optr_reg_mask |= FLASH_OBW2SR_DTCM_AXI_SHARE;
1077   }
1078 
1079   if ((UserType & OB_USER_SRAM_ECC) != 0U)
1080   {
1081     /* SRAM_ECC option byte should be modified */
1082     assert_param(IS_OB_USER_AXISRAM_ECC(UserConfig2 & FLASH_OBW2SR_ECC_ON_SRAM));
1083 
1084     /* Set value and mask for SRAM_ECC option byte */
1085     optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_ECC_ON_SRAM);
1086     optr_reg_mask |= FLASH_OBW2SR_ECC_ON_SRAM;
1087   }
1088 
1089   if ((UserType & OB_USER_I2C_NI3C) != 0U)
1090   {
1091     /* I2C_NI3C option byte should be modified */
1092     assert_param(IS_OB_USER_I2C_NI3C(UserConfig2 & FLASH_OBW2SR_I2C_NI3C));
1093 
1094     /* Set value and mask for I2C_NI3C option byte */
1095     optr_reg_val |= (UserConfig2 & FLASH_OBW2SR_I2C_NI3C);
1096     optr_reg_mask |= FLASH_OBW2SR_I2C_NI3C;
1097   }
1098 
1099   /* Configure the option bytes register 2 if necessary */
1100   if (optr_reg_mask != 0U)
1101   {
1102     MODIFY_REG(FLASH->OBW2SRP, optr_reg_mask, optr_reg_val);
1103   }
1104 }
1105 
1106 /**
1107   * @brief  Configure the Hide Protection.
1108   *
1109   * @note   To configure the HDP options, the option lock bit OPTLOCK must be
1110   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
1111   *
1112   * @param  HDPStartPage
1113   *
1114   * @param  HDPEndPage
1115   *
1116   * @retval None
1117   */
FLASH_OB_HDPConfig(uint32_t HDPStartPage,uint32_t HDPEndPage)1118 static void FLASH_OB_HDPConfig(uint32_t HDPStartPage, uint32_t HDPEndPage)
1119 {
1120   /* Check the parameters */
1121   assert_param(IS_OB_HDP_PAGE(HDPStartPage));
1122   assert_param(IS_OB_HDP_PAGE(HDPEndPage));
1123 
1124   MODIFY_REG(FLASH->HDPSRP, (FLASH_HDPSRP_HDP_AREA_START | FLASH_HDPSRP_HDP_AREA_END), \
1125              (HDPStartPage | (HDPEndPage << FLASH_HDPSRP_HDP_AREA_END_Pos)));
1126 }
1127 
1128 /**
1129   * @brief  Configure the Non-Volatile state.
1130   *
1131   * @note   To configure the Non-volatile options, the option lock bit OPTLOCK must be
1132   *         cleared with the call of the HAL_FLASH_OB_Unlock() function.
1133   *
1134   * @param  NVState
1135   *
1136   * @retval None
1137   */
FLASH_OB_NVConfig(uint32_t NVState)1138 static void FLASH_OB_NVConfig(uint32_t NVState)
1139 {
1140   /* Check the parameter */
1141   assert_param(IS_OB_NVSTATE(NVState));
1142 
1143   MODIFY_REG(FLASH->NVSRP, FLASH_NVSRP_NVSTATE, NVState);
1144 }
1145 
1146 /**
1147   * @brief  Return the FLASH Write Protection Option Bytes value.
1148   *
1149   * @param  WRPState
1150   *
1151   * @param  WRPSector
1152   *
1153   * @retval None
1154   */
FLASH_OB_GetWRP(uint32_t * WRPState,uint32_t * WRPSector)1155 static void FLASH_OB_GetWRP(uint32_t *WRPState, uint32_t *WRPSector)
1156 {
1157   if ((FLASH->WRPSR & FLASH_WRPSR_WRPS) == FLASH_WRPSR_WRPS)
1158   {
1159     /* All sectors aren't write protected */
1160     *WRPState = OB_WRPSTATE_DISABLE;
1161   }
1162   else
1163   {
1164     /* Some sectors are write protected */
1165     *WRPState = OB_WRPSTATE_ENABLE;
1166     *WRPSector = ((~(FLASH->WRPSR)) & FLASH_WRPSR_WRPS);
1167   }
1168 }
1169 
1170 /**
1171   * @brief  Return the FLASH User Option Byte value.
1172   *
1173   * @param UserConfig1 Address to return the FLASH User Option Bytes values configuration 1.
1174   *         The return value can be a combination of
1175   * @param UserConfig2 Address to return the FLASH User Option Bytes values configuration 2.
1176   *         The return value can be a combination of
1177   *
1178   * @retval None
1179   */
FLASH_OB_GetUser(uint32_t * UserConfig1,uint32_t * UserConfig2)1180 static void FLASH_OB_GetUser(uint32_t *UserConfig1, uint32_t *UserConfig2)
1181 {
1182   *UserConfig1 = FLASH->OBW1SR;
1183   *UserConfig2 = FLASH->OBW2SR;
1184 }
1185 
1186 /**
1187   * @brief  Return the FLASH Hide Protection Option Bytes value.
1188   *
1189   * @param HDPStartPage Address to return the FLASH HDP Option Bytes Start Sector.
1190   *         The return value can be a combination of
1191   * @param HDPEndPage Address to return the FLASH HDP Option Bytes End Sector.
1192   *         The return value can be a combination of
1193   *
1194   * @retval None
1195   */
FLASH_OB_GetHDP(uint32_t * HDPStartPage,uint32_t * HDPEndPage)1196 static void FLASH_OB_GetHDP(uint32_t *HDPStartPage, uint32_t *HDPEndPage)
1197 {
1198   *HDPStartPage = (FLASH->HDPSR & FLASH_HDPSR_HDP_AREA_START);
1199   *HDPEndPage = ((FLASH->HDPSR & FLASH_HDPSR_HDP_AREA_END) >> FLASH_HDPSR_HDP_AREA_END_Pos);
1200 }
1201 
1202 /**
1203   * @brief  Return the FLASH Non-volatile state Option Bytes value.
1204   *
1205   * @retval Value of Non-volatile state
1206   */
FLASH_OB_GetNV(void)1207 static uint32_t FLASH_OB_GetNV(void)
1208 {
1209   return (FLASH->NVSR & FLASH_NVSR_NVSTATE);
1210 }
1211 
1212 /**
1213   * @brief  Return the FLASH RoT Option Bytes value.
1214   *
1215   * @retval Value of the RoT
1216   */
FLASH_OB_GetRoT(void)1217 static uint32_t FLASH_OB_GetRoT(void)
1218 {
1219   return (FLASH->ROTSR & (FLASH_ROTSR_OEM_PROVD | FLASH_ROTSR_DBG_AUTH | FLASH_ROTSR_IROT_SELECT));
1220 }
1221 
1222 /**
1223   * @brief  Return the FLASH Epoch Option Bytes value.
1224   *
1225   * @retval Value of the Epoch
1226   */
FLASH_OB_GetEpoch(void)1227 static uint32_t FLASH_OB_GetEpoch(void)
1228 {
1229   return (FLASH->EPOCHSR & FLASH_EPOCHSR_EPOCH);
1230 }
1231 
1232 /**
1233   * @brief  Add a CRC sector to the list of sectors on which the CRC will be calculated
1234   * @param  Sector Specifies the CRC sector number
1235   * @retval None
1236   */
FLASH_CRC_AddSector(uint32_t Sector)1237 static void FLASH_CRC_AddSector(uint32_t Sector)
1238 {
1239   /* Check the parameters */
1240   assert_param(IS_FLASH_SECTOR(Sector));
1241 
1242   /* Clear CRC sector */
1243   MODIFY_REG(FLASH->CRCCR, FLASH_CRCCR_CRC_SECT, Sector);
1244 
1245   /* Activate ADD_SECT bit */
1246   SET_BIT(FLASH->CRCCR, FLASH_CRCCR_ADD_SECT);
1247 }
1248 
1249 /**
1250   * @brief  Select CRC start and end memory addresses on which the CRC will be calculated
1251   * @param  CRCStartAddr Specifies the CRC start address
1252   * @param  CRCEndAddr Specifies the CRC end address
1253   * @retval None
1254   */
FLASH_CRC_SelectAddress(uint32_t CRCStartAddr,uint32_t CRCEndAddr)1255 static void FLASH_CRC_SelectAddress(uint32_t CRCStartAddr, uint32_t CRCEndAddr)
1256 {
1257   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(CRCStartAddr));
1258   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(CRCEndAddr));
1259 
1260   /* Write CRC Start and End addresses */
1261   FLASH->CRCSADDR = (CRCStartAddr - FLASH_BASE);
1262   FLASH->CRCEADDR = (CRCEndAddr - FLASH_BASE);
1263 }
1264 
1265 /**
1266   * @brief  Wait for a FLASH CRC computation to complete.
1267   * @param  Timeout maximum flash operation timeout
1268   * @retval HAL_StatusTypeDef HAL Status
1269   */
FLASH_CRC_WaitForLastOperation(uint32_t Timeout)1270 static HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout)
1271 {
1272   uint32_t timeout = HAL_GetTick() + Timeout;
1273 
1274   /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
1275   while ((FLASH->SR & FLASH_SR_CRC_BUSY) != 0U)
1276   {
1277     if (HAL_GetTick() >= timeout)
1278     {
1279       return HAL_TIMEOUT;
1280     }
1281   }
1282 
1283   /* Check FLASH CRC calculation error flag  */
1284   if ((FLASH->ISR & FLASH_FLAG_CRCERR) != 0U)
1285   {
1286     /*Save the error code*/
1287     pFlash.ErrorCode |= HAL_FLASH_ERROR_CRC;
1288 
1289     /* Clear CRC error flag */
1290     FLASH->ICR = FLASH_FLAG_CRCERR;
1291 
1292     return HAL_ERROR;
1293   }
1294 
1295   /* Check FLASH CRC End of Calculation flag  */
1296   if ((FLASH->ISR & FLASH_FLAG_CRCEND) != 0U)
1297   {
1298     /* Clear FLASH End of Calculation pending bit */
1299     FLASH->ICR = FLASH_FLAG_CRCEND;
1300   }
1301 
1302   /* If there is no error flag set */
1303   return HAL_OK;
1304 }
1305 
1306 /**
1307   * @}
1308   */
1309 
1310 /**
1311   * @}
1312   */
1313 
1314 #endif /* HAL_FLASH_MODULE_ENABLED */
1315 
1316 /**
1317   * @}
1318   */
1319 
1320 /**
1321   * @}
1322   */
1323