1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_hal_flash.c
4   * @author  MCD Application Team
5   * @brief   FLASH HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the internal FLASH memory:
8   *           + Program operations functions
9   *           + Memory Control functions
10   *           + Peripheral Errors functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2022 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23  @verbatim
24   ==============================================================================
25                         ##### Flash peripheral features #####
26   ==============================================================================
27 
28   [..] The Flash memory interface manages CPU AHB C-Bus accesses to the Flash memory.
29        It implements the erase and program Flash memory operations and the read
30      and write protection mechanisms.
31 
32   [..] The Flash memory interface implements the TrustZone security features (TZ) supported
33        by ARM Cortex-M33 core (CM33).
34 
35   [..] The FLASH main features are:
36       (+) Flash memory read operations
37       (+) Flash memory program/erase operations
38       (+) Read / write protections
39       (+) Option bytes programming
40           (+) TrustZone aware
41           (+) Watermark-based area protection including the secure hide area
42           (+) Block-based page protection
43       (+) Error code correction (ECC) : Data in flash are 137-bits word
44           (9 bits added per quad-word)
45 
46                         ##### How to use this driver #####
47  ==============================================================================
48     [..]
49       This driver provides functions and macros to configure and program the FLASH
50       memory of all STM32WBAxx devices.
51 
52       (#) Flash Memory IO Programming functions:
53            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
54                 HAL_FLASH_Lock() functions
55            (++) Program functions: quad-words and burst program (8 quad-words)
56            (++) There are two modes of programming:
57             (+++) Polling mode using HAL_FLASH_Program() function
58             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
59 
60       (#) Interrupts and flags management functions:
61            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
62            (++) Callback functions are called when the flash operations are finished :
63                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
64                 HAL_FLASH_OperationErrorCallback()
65            (++) Get error flag status by calling HAL_GetError()
66 
67       (#) Option bytes management functions :
68            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
69                 HAL_FLASH_OB_Lock() functions
70            (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
71                 In this case, a reset is generated
72 
73     [..]
74       In addition to these functions, this driver includes a set of macros allowing
75       to handle the following operations:
76        (+) Set the latency
77        (+) Enable/Disable the Flash power-down during low-power run and sleep modes
78        (+) Enable/Disable the Flash interrupts
79        (+) Monitor the Flash flags status
80 
81  @endverbatim
82   ******************************************************************************
83   */
84 
85 /* Includes ------------------------------------------------------------------*/
86 #include "stm32wbaxx_hal.h"
87 
88 /** @addtogroup STM32WBAxx_HAL_Driver
89   * @{
90   */
91 
92 /** @defgroup FLASH FLASH
93   * @brief FLASH HAL module driver
94   * @{
95   */
96 
97 #ifdef HAL_FLASH_MODULE_ENABLED
98 
99 /* Private typedef -----------------------------------------------------------*/
100 /* Private defines -----------------------------------------------------------*/
101 /** @addtogroup FLASH_Private_Constants
102   * @{
103   */
104 #define FLASH_NB_WORDS_IN_BURST  32
105 /**
106   * @}
107   */
108 
109 /* Private macros ------------------------------------------------------------*/
110 /* Private variables ---------------------------------------------------------*/
111 /** @defgroup FLASH_Private_Variables FLASH Private Variables
112   * @{
113   */
114 /**
115   * @brief  Variable used for Program/Erase sectors under interruption
116   */
117 FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
118                                .ErrorCode = HAL_FLASH_ERROR_NONE, \
119                                .ProcedureOnGoing = 0U, \
120                                .Address = 0U, \
121                                .Page = 0U, \
122                                .NbPagesToErase = 0U
123                               };
124 /**
125   * @}
126   */
127 
128 /* Private function prototypes -----------------------------------------------*/
129 /** @defgroup FLASH_Private_Functions FLASH Private Functions
130   * @{
131   */
132 static void FLASH_Program_QuadWord(uint32_t Address, uint32_t DataAddress);
133 static void FLASH_Program_Burst(uint32_t Address, uint32_t DataAddress);
134 /**
135   * @}
136   */
137 
138 /* Exported functions --------------------------------------------------------*/
139 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
140   * @{
141   */
142 
143 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
144   *  @brief   Programming operation functions
145   *
146 @verbatim
147  ===============================================================================
148                   ##### Programming operation functions #####
149  ===============================================================================
150     [..]
151     This subsection provides a set of functions allowing to manage the FLASH
152     program operations.
153 
154 @endverbatim
155   * @{
156   */
157 
158 /**
159   * @brief  Program a quad-word or a burst of 8 quad-words at a specified address.
160   * @note   Before any operation, it is possible to check there is no operation suspended
161   *         by call HAL_FLASHEx_IsOperationSuspended()
162   * @param  TypeProgram  Indicate the way to program at a specified address
163   *                      This parameter can be a value of @ref FLASH_TYPE_PROGRAM
164   * @param  Address  Specifies the address to be programmed.
165   *         This parameter shall be aligned to the Flash word (128 bits)
166   * @param  DataAddress Specifies the address of data to be programmed.
167   *         This parameter shall be 32-bit aligned
168   *
169   * @retval HAL_StatusTypeDef HAL Status
170   */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint32_t DataAddress)171 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t DataAddress)
172 {
173   HAL_StatusTypeDef status;
174   __IO uint32_t *reg_cr;
175 
176   /* Check the parameters */
177   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
178 
179   /* Process Locked */
180   __HAL_LOCK(&pFlash);
181 
182   /* Reset error code */
183   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
184 
185   /* Verify that next operation can be proceed */
186   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
187 
188   if (status == HAL_OK)
189   {
190     /* Set current operation type */
191     pFlash.ProcedureOnGoing = TypeProgram;
192 
193     /* Access to SECCR1 or NSCR1 depends on operation type */
194 #if defined(FLASH_SECCR1_LOCK)
195     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
196 #else
197     reg_cr = &(FLASH_NS->NSCR1);
198 #endif /* FLASH_SECCR1_LOCK */
199 
200     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
201     {
202       /* Program a quad-word (128-bit) at a specified address */
203       FLASH_Program_QuadWord(Address, DataAddress);
204     }
205     else
206     {
207       /* Program a burst of 8 quad-words at a specified address */
208       FLASH_Program_Burst(Address, DataAddress);
209     }
210 
211     /* Wait for last operation to be completed */
212     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
213 
214     /* If the program operation is completed, disable the PG (and BWR Bit in Burst programming mode) */
215     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK)));
216   }
217 
218   /* Process Unlocked */
219   __HAL_UNLOCK(&pFlash);
220 
221   /* return status */
222   return status;
223 }
224 
225 /**
226   * @brief  Program a quad-word or a burst of 8 quad-words at a specified address with interrupt enabled.
227   * @param  TypeProgram Indicate the way to program at a specified address.
228   *                           This parameter can be a value of @ref FLASH_TYPE_PROGRAM
229   * @param  Address Specifies the address to be programmed.
230   *         This parameter shall be aligned to the Flash word (128 bits)
231   * @param  DataAddress specifies the address of data to be programmed.
232   *         This parameter shall be 32-bit aligned
233   *
234   * @retval HAL Status
235   */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint32_t DataAddress)236 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t DataAddress)
237 {
238   HAL_StatusTypeDef status;
239   __IO uint32_t *reg_cr;
240 
241   /* Check the parameters */
242   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
243   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
244 
245   /* Process Locked */
246   __HAL_LOCK(&pFlash);
247 
248   /* Reset error code */
249   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
250 
251   /* Verify that next operation can be proceed */
252   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
253 
254   if (status != HAL_OK)
255   {
256     /* Process Unlocked */
257     __HAL_UNLOCK(&pFlash);
258   }
259   else
260   {
261     /* Set internal variables used by the IRQ handler */
262     pFlash.ProcedureOnGoing = TypeProgram;
263     pFlash.Address = Address;
264 
265     /* Access to SECCR1 or NSCR1 depends on operation type */
266 #if defined(FLASH_SECCR1_LOCK)
267     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
268 #else
269     reg_cr = &(FLASH_NS->NSCR1);
270 #endif /* FLASH_SECCR1_LOCK */
271 
272     /* Enable End of Operation and Error interrupts */
273     (*reg_cr) |= (FLASH_IT_EOP | FLASH_IT_OPERR);
274 
275     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
276     {
277       /* Program a quad-word (128-bit) at a specified address */
278       FLASH_Program_QuadWord(Address, DataAddress);
279     }
280     else
281     {
282       /* Program a burst of 8 quad-words at a specified address */
283       FLASH_Program_Burst(Address, DataAddress);
284     }
285   }
286 
287   /* return status */
288   return status;
289 }
290 
291 /**
292   * @brief Handle FLASH interrupt request.
293   * @retval None
294   */
HAL_FLASH_IRQHandler(void)295 void HAL_FLASH_IRQHandler(void)
296 {
297   uint32_t param = 0U;
298   uint32_t error;
299   __IO uint32_t *reg_cr;
300   uint32_t type;
301   __IO uint32_t *reg_sr;
302 
303   type = (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK));
304   /* Access to CR and SR registers depends on operation type */
305 #if defined(FLASH_SECCR1_LOCK)
306   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
307 #else
308   reg_cr = &(FLASH_NS->NSCR1);
309 #endif /* FLASH_SECCR1_LOCK */
310 #if defined(FLASH_SECSR_EOP)
311   reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
312 #else
313   reg_sr = &(FLASH_NS->NSSR);
314 #endif /* FLASH_SECSR_EOP */
315 
316   /* Save Flash errors */
317   error = (*reg_sr) & FLASH_FLAG_SR_ERRORS;
318 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
319   error |= (FLASH->NSSR & FLASH_FLAG_OPTWERR);
320 #endif /* __ARM_FEATURE_CMSE */
321 
322   /* Set parameter of the callback */
323   if (type == FLASH_TYPEERASE_PAGES)
324   {
325     param = pFlash.Page;
326   }
327   else if (type == FLASH_TYPEPROGRAM_QUADWORD)
328   {
329     param = pFlash.Address;
330   }
331   else if (type == FLASH_TYPEPROGRAM_BURST)
332   {
333     param = pFlash.Address;
334   }
335   else
336   {
337     /* Empty statement (to be compliant MISRA 15.7) */
338   }
339 
340   /* Clear operation bit on the on-going procedure */
341   CLEAR_BIT((*reg_cr), (type | FLASH_NSCR1_PNB));
342 
343   /* Check FLASH operation error flags */
344   if (error != 0U)
345   {
346     /* Save the error code */
347     pFlash.ErrorCode |= error;
348 
349     /* Clear error programming flags */
350     (*reg_sr) = error;
351 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
352     if ((error & FLASH_FLAG_OPTWERR) != 0U)
353     {
354       FLASH->NSSR = FLASH_FLAG_OPTWERR;
355     }
356 #endif /* __ARM_FEATURE_CMSE */
357 
358     /* Stop the procedure ongoing */
359     pFlash.ProcedureOnGoing = 0U;
360 
361     /* FLASH error interrupt user callback */
362     HAL_FLASH_OperationErrorCallback(param);
363   }
364 
365   /* Check FLASH End of Operation flag  */
366   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
367   {
368     /* Clear FLASH End of Operation pending bit */
369     (*reg_sr) = FLASH_FLAG_EOP;
370 
371     if (type == FLASH_TYPEERASE_PAGES)
372     {
373       /* Nb of pages to erase can be decreased */
374       pFlash.NbPagesToErase--;
375 
376       /* Check if there are still pages to erase */
377       if (pFlash.NbPagesToErase != 0U)
378       {
379         /* Increment page number */
380         pFlash.Page++;
381         FLASH_PageErase(pFlash.Page);
382       }
383       else
384       {
385         /* No more pages to Erase */
386         pFlash.ProcedureOnGoing = 0U;
387         param = 0xFFFFFFFFU;
388       }
389     }
390     else
391     {
392       /*Clear the procedure ongoing*/
393       pFlash.ProcedureOnGoing = 0U;
394     }
395 
396     /* FLASH EOP interrupt user callback */
397     HAL_FLASH_EndOfOperationCallback(param);
398   }
399 
400   if (pFlash.ProcedureOnGoing == 0U)
401   {
402     /* Disable End of Operation and Error interrupts */
403     (*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_OPERR);
404 
405     /* Process Unlocked */
406     __HAL_UNLOCK(&pFlash);
407   }
408 
409   /* Check ECC Correction Error */
410   if ((FLASH->ECCR & (FLASH_ECCR_ECCC | FLASH_ECCR_ECCIE)) == (FLASH_ECCR_ECCC | FLASH_ECCR_ECCIE))
411   {
412     /* Call User callback */
413     HAL_FLASHEx_EccCorrectionCallback();
414 
415     /* Clear ECC correction flag in order to allow new ECC error record */
416     SET_BIT(FLASH->ECCR, FLASH_ECCR_ECCC);
417   }
418 }
419 
420 /**
421   * @brief  FLASH end of operation interrupt callback.
422   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure :
423   *                  @arg Mass Erase: 0
424   *                  @arg Page Erase: Page which has been erased
425   *                       (if 0xFFFFFFFF, it means that all the selected pages have been erased)
426   *                  @arg Program: Address which was selected for data program
427   * @retval None
428   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)429 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
430 {
431   /* Prevent unused argument(s) compilation warning */
432   UNUSED(ReturnValue);
433 
434   /* NOTE : This function should not be modified, when the callback is needed,
435             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
436    */
437 }
438 
439 /**
440   * @brief  FLASH operation error interrupt callback.
441   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure :
442   *                 @arg Mass Erase: 0
443   *                 @arg Page Erase: Page number which returned an error
444   *                 @arg Program: Address which was selected for data program
445   * @retval None
446   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)447 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
448 {
449   /* Prevent unused argument(s) compilation warning */
450   UNUSED(ReturnValue);
451 
452   /* NOTE : This function should not be modified, when the callback is needed,
453             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
454    */
455 }
456 
457 /**
458   * @}
459   */
460 
461 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
462   *  @brief   Management functions
463   *
464 @verbatim
465  ===============================================================================
466                       ##### Peripheral Control functions #####
467  ===============================================================================
468     [..]
469     This subsection provides a set of functions allowing to control the FLASH
470     memory operations.
471 
472 @endverbatim
473   * @{
474   */
475 
476 /**
477   * @brief  Unlock the FLASH control register access.
478   * @retval HAL Status
479   */
HAL_FLASH_Unlock(void)480 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
481 {
482   HAL_StatusTypeDef status = HAL_OK;
483 
484   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
485   {
486     /* Authorize the FLASH Registers access */
487     WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
488     WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
489 
490     /* verify Flash is unlocked */
491     if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
492     {
493       status = HAL_ERROR;
494     }
495   }
496 
497 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
498   if (status == HAL_OK)
499   {
500     if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
501     {
502       /* Authorize the FLASH Registers access */
503       WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
504       WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
505 
506       /* verify Flash is unlocked */
507       if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
508       {
509         status = HAL_ERROR;
510       }
511     }
512   }
513 #endif /* __ARM_FEATURE_CMSE */
514 
515   return status;
516 }
517 
518 /**
519   * @brief  Lock the FLASH control register access.
520   * @retval HAL Status
521   */
HAL_FLASH_Lock(void)522 HAL_StatusTypeDef HAL_FLASH_Lock(void)
523 {
524   HAL_StatusTypeDef status = HAL_ERROR;
525 
526   /* Set the LOCK Bit to lock the FLASH Registers access */
527   SET_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK);
528 
529   /* verify Flash is locked */
530   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
531   {
532     status = HAL_OK;
533   }
534 
535 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
536   if (status == HAL_OK)
537   {
538     SET_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK);
539 
540     /* verify Flash is locked */
541     if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
542     {
543       status = HAL_OK;
544     }
545   }
546 #endif /* __ARM_FEATURE_CMSE */
547 
548   return status;
549 }
550 
551 /**
552   * @brief  Unlock the FLASH Option Bytes Registers access.
553   * @retval HAL Status
554   */
HAL_FLASH_OB_Unlock(void)555 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
556 {
557   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
558   {
559     /* Authorizes the Option Byte register programming */
560     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
561     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
562 
563     /* Verify that the Option Bytes are unlocked */
564     if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
565     {
566       return HAL_ERROR;
567     }
568   }
569 
570   return HAL_OK;
571 }
572 
573 /**
574   * @brief  Lock the FLASH Option Bytes Registers access.
575   * @retval HAL Status
576   */
HAL_FLASH_OB_Lock(void)577 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
578 {
579   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
580   SET_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK);
581 
582   /* Verify that the Option Bytes are locked */
583   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
584   {
585     return HAL_OK;
586   }
587 
588   return HAL_ERROR;
589 }
590 
591 /**
592   * @brief  Launch the option byte loading.
593   * @retval HAL Status
594   */
HAL_FLASH_OB_Launch(void)595 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
596 {
597   /* Set the bit to force the option byte reloading */
598   SET_BIT(FLASH->NSCR1, FLASH_NSCR1_OBL_LAUNCH);
599 
600   /* We should not reach here : Option byte launch generates Option byte reset
601      so return error */
602   return HAL_ERROR;
603 }
604 
605 /**
606   * @}
607   */
608 
609 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
610   *  @brief   Peripheral Errors functions
611   *
612 @verbatim
613  ===============================================================================
614                 ##### Peripheral Errors functions #####
615  ===============================================================================
616     [..]
617     This subsection permits to get in run-time Errors of the FLASH peripheral.
618 
619 @endverbatim
620   * @{
621   */
622 
623 /**
624   * @brief  Get the specific FLASH error flag.
625   * @retval FLASH_ErrorCode The returned value can be
626   *            @arg @ref HAL_FLASH_ERROR_NONE No error set
627   *            @arg @ref HAL_FLASH_ERROR_OP FLASH Operation error
628   *            @arg @ref HAL_FLASH_ERROR_PROG FLASH Programming error
629   *            @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
630   *            @arg @ref HAL_FLASH_ERROR_PGA FLASH Programming alignment error
631   *            @arg @ref HAL_FLASH_ERROR_SIZ FLASH Size error
632   *            @arg @ref HAL_FLASH_ERROR_PGS FLASH Programming sequence error
633   *            @arg @ref HAL_FLASH_ERROR_OPTW FLASH Option modification error
634   *            @arg @ref HAL_FLASH_ERROR_OPTW FLASH Option write error
635   */
HAL_FLASH_GetError(void)636 uint32_t HAL_FLASH_GetError(void)
637 {
638   return pFlash.ErrorCode;
639 }
640 
641 /**
642   * @}
643   */
644 
645 /**
646   * @}
647   */
648 
649 /* Private functions ---------------------------------------------------------*/
650 
651 /** @addtogroup FLASH_Private_Functions
652   * @{
653   */
654 
655 /**
656   * @brief  Wait for a FLASH operation to complete.
657   * @param  Timeout Maximum flash operation timeout
658   * @retval HAL_StatusTypeDef HAL Status
659   */
FLASH_WaitForLastOperation(uint32_t Timeout)660 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
661 {
662   /* Wait for the FLASH operation to complete by polling on BUSY and WDW flags to be reset.
663      Even if the FLASH operation fails, the BUSY & WDW flags will be reset, and an error flag will be set */
664 
665   uint32_t timeout = HAL_GetTick() + Timeout;
666   uint32_t error;
667   __IO uint32_t *reg_sr;
668 
669   /* Access to SECSR or NSSR registers depends on operation type */
670 #if defined(FLASH_SECSR_EOP)
671   reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
672 #else
673   reg_sr = &(FLASH_NS->NSSR);
674 #endif /* FLASH_SECSR_EOP */
675 
676   while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WDW)) != 0U)
677   {
678     if (Timeout != HAL_MAX_DELAY)
679     {
680       if (HAL_GetTick() >= timeout)
681       {
682         return HAL_TIMEOUT;
683       }
684     }
685   }
686 
687   /* Check FLASH operation error flags */
688   error = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
689 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
690   error |= (FLASH->NSSR & FLASH_FLAG_OPTWERR);
691 #endif /* __ARM_FEATURE_CMSE */
692 
693   if (error != 0U)
694   {
695     /*Save the error code*/
696     pFlash.ErrorCode |= error;
697 
698     /* Clear error programming flags */
699     (*reg_sr) = error;
700 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
701     if ((error & FLASH_FLAG_OPTWERR) != 0U)
702     {
703       FLASH->NSSR = FLASH_FLAG_OPTWERR;
704     }
705 #endif /* __ARM_FEATURE_CMSE */
706 
707     return HAL_ERROR;
708   }
709 
710   /* Check FLASH End of Operation flag  */
711   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
712   {
713     /* Clear FLASH End of Operation pending bit */
714     (*reg_sr) = FLASH_FLAG_EOP;
715   }
716 
717   return HAL_OK;
718 }
719 
720 /**
721   * @brief  Program a quad-word (128-bit) at a specified address.
722   * @param  Address Specifies the address to be programmed.
723   * @param  DataAddress Specifies the address of data to be programmed.
724   * @retval None
725   */
FLASH_Program_QuadWord(uint32_t Address,uint32_t DataAddress)726 static void FLASH_Program_QuadWord(uint32_t Address, uint32_t DataAddress)
727 {
728   uint8_t index = 4;
729   uint32_t *dest_addr = (uint32_t *)Address;
730   uint32_t *src_addr  = (uint32_t *)DataAddress;
731   uint32_t primask_bit;
732   __IO uint32_t *reg_cr;
733 
734   /* Check the parameters */
735   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
736 
737   /* Access to SECCR1 or NSCR1 registers depends on operation type */
738 #if defined(FLASH_SECCR1_LOCK)
739   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
740 #else
741   reg_cr = &(FLASH_NS->NSCR1);
742 #endif /* FLASH_SECCR1_LOCK */
743 
744   /* Set PG bit */
745   SET_BIT((*reg_cr), FLASH_NSCR1_PG);
746 
747   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
748   primask_bit = __get_PRIMASK();
749   __disable_irq();
750 
751   /* Program the quad-word */
752   do
753   {
754     *dest_addr = *src_addr;
755     dest_addr++;
756     src_addr++;
757     index--;
758   } while (index != 0U);
759 
760   /* Exit critical section: restore previous priority mask */
761   __set_PRIMASK(primask_bit);
762 }
763 
764 /**
765   * @brief  Program a burst of 8x quad-words at a specified address.
766   * @param  Address Specifies the address to be programmed.
767   * @param  DataAddress Specifies the address where the data are stored.
768   * @retval None
769   */
FLASH_Program_Burst(uint32_t Address,uint32_t DataAddress)770 static void FLASH_Program_Burst(uint32_t Address, uint32_t DataAddress)
771 {
772   uint8_t burst_index = FLASH_NB_WORDS_IN_BURST;
773   uint32_t *dest_addr = (uint32_t *)Address;
774   uint32_t *src_addr = (uint32_t *)DataAddress;
775   uint32_t primask_bit;
776   __IO uint32_t *reg_cr;
777 
778   /* Check the parameters */
779   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
780 
781   /* Access to SECCR1 or NSCR1 registers depends on operation type */
782 #if defined(FLASH_SECCR1_LOCK)
783   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
784 #else
785   reg_cr = &(FLASH_NS->NSCR1);
786 #endif /* FLASH_SECCR1_LOCK */
787 
788   /* Set PG and BWR bits */
789   SET_BIT((*reg_cr), (FLASH_NSCR1_PG | FLASH_NSCR1_BWR));
790 
791   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
792   primask_bit = __get_PRIMASK();
793   __disable_irq();
794 
795   /* Program the burst */
796   do
797   {
798     *dest_addr = *src_addr;
799     dest_addr++;
800     src_addr++;
801     burst_index--;
802   } while (burst_index != 0U);
803 
804   /* Exit critical section: restore previous priority mask */
805   __set_PRIMASK(primask_bit);
806 }
807 
808 /**
809   * @}
810   */
811 
812 #endif /* HAL_FLASH_MODULE_ENABLED */
813 
814 /**
815   * @}
816   */
817 
818 /**
819   * @}
820   */
821