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