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