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