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