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