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