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