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   __IO 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
332   {
333     /* Empty statement (to be compliant MISRA 15.7) */
334   }
335 
336   /* Clear operation bit on the on-going procedure */
337   CLEAR_BIT((*reg_cr), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK)));
338 
339   /* Check FLASH operation error flags */
340   if (error != 0U)
341   {
342     /* Save the error code */
343     pFlash.ErrorCode |= error;
344 
345     /* Clear error programming flags */
346     (*reg_sr) = error;
347 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
348     if ((error & FLASH_FLAG_OPTWERR) != 0U)
349     {
350       FLASH->NSSR = FLASH_FLAG_OPTWERR;
351     }
352 #endif /* __ARM_FEATURE_CMSE */
353 
354     /* Stop the procedure ongoing */
355     pFlash.ProcedureOnGoing = 0U;
356 
357     /* FLASH error interrupt user callback */
358     HAL_FLASH_OperationErrorCallback(param);
359   }
360 
361   /* Check FLASH End of Operation flag  */
362   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
363   {
364     /* Clear FLASH End of Operation pending bit */
365     (*reg_sr) = FLASH_FLAG_EOP;
366 
367     if (type == FLASH_TYPEERASE_PAGES)
368     {
369       /* Nb of pages to erase can be decreased */
370       pFlash.NbPagesToErase--;
371 
372       /* Check if there are still pages to erase */
373       if (pFlash.NbPagesToErase != 0U)
374       {
375         /* Increment page number */
376         pFlash.Page++;
377         FLASH_PageErase(pFlash.Page);
378       }
379       else
380       {
381         /* No more pages to Erase */
382         pFlash.ProcedureOnGoing = 0U;
383         param = 0xFFFFFFFFU;
384       }
385     }
386     else
387     {
388       /*Clear the procedure ongoing*/
389       pFlash.ProcedureOnGoing = 0U;
390     }
391 
392     /* FLASH EOP interrupt user callback */
393     HAL_FLASH_EndOfOperationCallback(param);
394   }
395 
396   if (pFlash.ProcedureOnGoing == 0U)
397   {
398     /* Disable End of Operation and Error interrupts */
399     (*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_OPERR);
400 
401     /* Process Unlocked */
402     __HAL_UNLOCK(&pFlash);
403   }
404 }
405 
406 /**
407   * @brief  FLASH end of operation interrupt callback.
408   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure :
409   *                  @arg Mass Erase: 0
410   *                  @arg Page Erase: Page which has been erased
411   *                       (if 0xFFFFFFFF, it means that all the selected pages have been erased)
412   *                  @arg Program: Address which was selected for data program
413   * @retval None
414   */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)415 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
416 {
417   /* Prevent unused argument(s) compilation warning */
418   UNUSED(ReturnValue);
419 
420   /* NOTE : This function should not be modified, when the callback is needed,
421             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
422    */
423 }
424 
425 /**
426   * @brief  FLASH operation error interrupt callback.
427   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure :
428   *                 @arg Mass Erase: 0
429   *                 @arg Page Erase: Page number which returned an error
430   *                 @arg Program: Address which was selected for data program
431   * @retval None
432   */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)433 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
434 {
435   /* Prevent unused argument(s) compilation warning */
436   UNUSED(ReturnValue);
437 
438   /* NOTE : This function should not be modified, when the callback is needed,
439             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
440    */
441 }
442 
443 /**
444   * @}
445   */
446 
447 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
448   *  @brief   Management functions
449   *
450 @verbatim
451  ===============================================================================
452                       ##### Peripheral Control functions #####
453  ===============================================================================
454     [..]
455     This subsection provides a set of functions allowing to control the FLASH
456     memory operations.
457 
458 @endverbatim
459   * @{
460   */
461 
462 /**
463   * @brief  Unlock the FLASH control register access.
464   * @retval HAL Status
465   */
HAL_FLASH_Unlock(void)466 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
467 {
468   HAL_StatusTypeDef status = HAL_OK;
469 
470   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
471   {
472     /* Authorize the FLASH Registers access */
473     WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
474     WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
475 
476     /* verify Flash is unlocked */
477     if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
478     {
479       status = HAL_ERROR;
480     }
481   }
482 
483 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
484   if (status == HAL_OK)
485   {
486     if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
487     {
488       /* Authorize the FLASH Registers access */
489       WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
490       WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
491 
492       /* verify Flash is unlocked */
493       if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
494       {
495         status = HAL_ERROR;
496       }
497     }
498   }
499 #endif /* __ARM_FEATURE_CMSE */
500 
501   return status;
502 }
503 
504 /**
505   * @brief  Lock the FLASH control register access.
506   * @retval HAL Status
507   */
HAL_FLASH_Lock(void)508 HAL_StatusTypeDef HAL_FLASH_Lock(void)
509 {
510   HAL_StatusTypeDef status = HAL_ERROR;
511 
512   /* Set the LOCK Bit to lock the FLASH Registers access */
513   SET_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK);
514 
515   /* verify Flash is locked */
516   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
517   {
518     status = HAL_OK;
519   }
520 
521 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
522   if (status == HAL_OK)
523   {
524     SET_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK);
525 
526     /* verify Flash is locked */
527     if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
528     {
529       status = HAL_OK;
530     }
531   }
532 #endif /* __ARM_FEATURE_CMSE */
533 
534   return status;
535 }
536 
537 /**
538   * @brief  Unlock the FLASH Option Bytes Registers access.
539   * @retval HAL Status
540   */
HAL_FLASH_OB_Unlock(void)541 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
542 {
543   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
544   {
545     /* Authorizes the Option Byte register programming */
546     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
547     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
548 
549     /* Verify that the Option Bytes are unlocked */
550     if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
551     {
552       return HAL_ERROR;
553     }
554   }
555 
556   return HAL_OK;
557 }
558 
559 /**
560   * @brief  Lock the FLASH Option Bytes Registers access.
561   * @retval HAL Status
562   */
HAL_FLASH_OB_Lock(void)563 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
564 {
565   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
566   SET_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK);
567 
568   /* Verify that the Option Bytes are locked */
569   if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
570   {
571     return HAL_OK;
572   }
573 
574   return HAL_ERROR;
575 }
576 
577 /**
578   * @brief  Launch the option byte loading.
579   * @retval HAL Status
580   */
HAL_FLASH_OB_Launch(void)581 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
582 {
583   /* Set the bit to force the option byte reloading */
584   SET_BIT(FLASH->NSCR1, FLASH_NSCR1_OBL_LAUNCH);
585 
586   /* We should not reach here : Option byte launch generates Option byte reset
587      so return error */
588   return HAL_ERROR;
589 }
590 
591 /**
592   * @}
593   */
594 
595 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
596   *  @brief   Peripheral Errors functions
597   *
598 @verbatim
599  ===============================================================================
600                 ##### Peripheral Errors functions #####
601  ===============================================================================
602     [..]
603     This subsection permits to get in run-time Errors of the FLASH peripheral.
604 
605 @endverbatim
606   * @{
607   */
608 
609 /**
610   * @brief  Get the specific FLASH error flag.
611   * @retval FLASH_ErrorCode The returned value can be
612   *            @arg @ref HAL_FLASH_ERROR_NONE No error set
613   *            @arg @ref HAL_FLASH_ERROR_OP FLASH Operation error
614   *            @arg @ref HAL_FLASH_ERROR_PROG FLASH Programming error
615   *            @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
616   *            @arg @ref HAL_FLASH_ERROR_PGA FLASH Programming alignment error
617   *            @arg @ref HAL_FLASH_ERROR_SIZ FLASH Size error
618   *            @arg @ref HAL_FLASH_ERROR_PGS FLASH Programming sequence error
619   *            @arg @ref HAL_FLASH_ERROR_OPTW FLASH Option modification error
620   *            @arg @ref HAL_FLASH_ERROR_OPTW FLASH Option write error
621   */
HAL_FLASH_GetError(void)622 uint32_t HAL_FLASH_GetError(void)
623 {
624   return pFlash.ErrorCode;
625 }
626 
627 /**
628   * @}
629   */
630 
631 /**
632   * @}
633   */
634 
635 /* Private functions ---------------------------------------------------------*/
636 
637 /** @addtogroup FLASH_Private_Functions
638   * @{
639   */
640 
641 /**
642   * @brief  Wait for a FLASH operation to complete.
643   * @param  Timeout Maximum flash operation timeout
644   * @retval HAL_StatusTypeDef HAL Status
645   */
FLASH_WaitForLastOperation(uint32_t Timeout)646 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
647 {
648   /* Wait for the FLASH operation to complete by polling on BUSY and WDW flags to be reset.
649      Even if the FLASH operation fails, the BUSY & WDW flags will be reset, and an error flag will be set */
650 
651   uint32_t timeout = HAL_GetTick() + Timeout;
652   uint32_t error;
653   __IO uint32_t *reg_sr;
654 
655   /* Access to SECSR or NSSR registers depends on operation type */
656 #if defined(FLASH_SECSR_EOP)
657   reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
658 #else
659   reg_sr = &(FLASH_NS->NSSR);
660 #endif /* FLASH_SECSR_EOP */
661 
662   while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WDW)) != 0U)
663   {
664     if (Timeout != HAL_MAX_DELAY)
665     {
666       if (HAL_GetTick() >= timeout)
667       {
668         return HAL_TIMEOUT;
669       }
670     }
671   }
672 
673   /* Check FLASH operation error flags */
674   error = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
675 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
676   error |= (FLASH->NSSR & FLASH_FLAG_OPTWERR);
677 #endif /* __ARM_FEATURE_CMSE */
678 
679   if (error != 0U)
680   {
681     /*Save the error code*/
682     pFlash.ErrorCode |= error;
683 
684     /* Clear error programming flags */
685     (*reg_sr) = error;
686 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
687     if ((error & FLASH_FLAG_OPTWERR) != 0U)
688     {
689       FLASH->NSSR = FLASH_FLAG_OPTWERR;
690     }
691 #endif /* __ARM_FEATURE_CMSE */
692 
693     return HAL_ERROR;
694   }
695 
696   /* Check FLASH End of Operation flag  */
697   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
698   {
699     /* Clear FLASH End of Operation pending bit */
700     (*reg_sr) = FLASH_FLAG_EOP;
701   }
702 
703   return HAL_OK;
704 }
705 
706 /**
707   * @brief  Program a quad-word (128-bit) at a specified address.
708   * @param  Address Specifies the address to be programmed.
709   * @param  DataAddress Specifies the address of data to be programmed.
710   * @retval None
711   */
FLASH_Program_QuadWord(uint32_t Address,uint32_t DataAddress)712 static void FLASH_Program_QuadWord(uint32_t Address, uint32_t DataAddress)
713 {
714   uint8_t index = 4;
715   uint32_t *dest_addr = (uint32_t *)Address;
716   uint32_t *src_addr  = (uint32_t *)DataAddress;
717   uint32_t primask_bit;
718   __IO uint32_t *reg_cr;
719 
720   /* Check the parameters */
721   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
722 
723   /* Access to SECCR1 or NSCR1 registers depends on operation type */
724 #if defined(FLASH_SECCR1_LOCK)
725   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
726 #else
727   reg_cr = &(FLASH_NS->NSCR1);
728 #endif /* FLASH_SECCR1_LOCK */
729 
730   /* Set PG bit */
731   SET_BIT((*reg_cr), FLASH_NSCR1_PG);
732 
733   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
734   primask_bit = __get_PRIMASK();
735   __disable_irq();
736 
737   /* Program the quad-word */
738   do
739   {
740     *dest_addr = *src_addr;
741     dest_addr++;
742     src_addr++;
743     index--;
744   } while (index != 0U);
745 
746   /* Exit critical section: restore previous priority mask */
747   __set_PRIMASK(primask_bit);
748 }
749 
750 /**
751   * @brief  Program a burst of 8x quad-words at a specified address.
752   * @param  Address Specifies the address to be programmed.
753   * @param  DataAddress Specifies the address where the data are stored.
754   * @retval None
755   */
FLASH_Program_Burst(uint32_t Address,uint32_t DataAddress)756 static void FLASH_Program_Burst(uint32_t Address, uint32_t DataAddress)
757 {
758   uint8_t burst_index = FLASH_NB_WORDS_IN_BURST;
759   uint32_t *dest_addr = (uint32_t *)Address;
760   uint32_t *src_addr = (uint32_t *)DataAddress;
761   uint32_t primask_bit;
762   __IO uint32_t *reg_cr;
763 
764   /* Check the parameters */
765   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
766 
767   /* Access to SECCR1 or NSCR1 registers depends on operation type */
768 #if defined(FLASH_SECCR1_LOCK)
769   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
770 #else
771   reg_cr = &(FLASH_NS->NSCR1);
772 #endif /* FLASH_SECCR1_LOCK */
773 
774   /* Set PG and BWR bits */
775   SET_BIT((*reg_cr), (FLASH_NSCR1_PG | FLASH_NSCR1_BWR));
776 
777   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
778   primask_bit = __get_PRIMASK();
779   __disable_irq();
780 
781   /* Program the burst */
782   do
783   {
784     *dest_addr = *src_addr;
785     dest_addr++;
786     src_addr++;
787     burst_index--;
788   } while (burst_index != 0U);
789 
790   /* Exit critical section: restore previous priority mask */
791   __set_PRIMASK(primask_bit);
792 }
793 
794 /**
795   * @}
796   */
797 
798 #endif /* HAL_FLASH_MODULE_ENABLED */
799 
800 /**
801   * @}
802   */
803 
804 /**
805   * @}
806   */
807