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 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 if (type == FLASH_TYPEPROGRAM_BURST)
332 {
333 param = pFlash.Address;
334 }
335 else
336 {
337 /* Empty statement (to be compliant MISRA 15.7) */
338 }
339
340 /* Clear operation bit on the on-going procedure */
341 CLEAR_BIT((*reg_cr), (type | FLASH_NSCR1_PNB));
342
343 /* Check FLASH operation error flags */
344 if (error != 0U)
345 {
346 /* Save the error code */
347 pFlash.ErrorCode |= error;
348
349 /* Clear error programming flags */
350 (*reg_sr) = error;
351 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
352 if ((error & FLASH_FLAG_OPTWERR) != 0U)
353 {
354 FLASH->NSSR = FLASH_FLAG_OPTWERR;
355 }
356 #endif /* __ARM_FEATURE_CMSE */
357
358 /* Stop the procedure ongoing */
359 pFlash.ProcedureOnGoing = 0U;
360
361 /* FLASH error interrupt user callback */
362 HAL_FLASH_OperationErrorCallback(param);
363 }
364
365 /* Check FLASH End of Operation flag */
366 if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
367 {
368 /* Clear FLASH End of Operation pending bit */
369 (*reg_sr) = FLASH_FLAG_EOP;
370
371 if (type == FLASH_TYPEERASE_PAGES)
372 {
373 /* Nb of pages to erase can be decreased */
374 pFlash.NbPagesToErase--;
375
376 /* Check if there are still pages to erase */
377 if (pFlash.NbPagesToErase != 0U)
378 {
379 /* Increment page number */
380 pFlash.Page++;
381 FLASH_PageErase(pFlash.Page);
382 }
383 else
384 {
385 /* No more pages to Erase */
386 pFlash.ProcedureOnGoing = 0U;
387 param = 0xFFFFFFFFU;
388 }
389 }
390 else
391 {
392 /*Clear the procedure ongoing*/
393 pFlash.ProcedureOnGoing = 0U;
394 }
395
396 /* FLASH EOP interrupt user callback */
397 HAL_FLASH_EndOfOperationCallback(param);
398 }
399
400 if (pFlash.ProcedureOnGoing == 0U)
401 {
402 /* Disable End of Operation and Error interrupts */
403 (*reg_cr) &= ~(FLASH_IT_EOP | FLASH_IT_OPERR);
404
405 /* Process Unlocked */
406 __HAL_UNLOCK(&pFlash);
407 }
408
409 /* Check ECC Correction Error */
410 if ((FLASH->ECCR & (FLASH_ECCR_ECCC | FLASH_ECCR_ECCIE)) == (FLASH_ECCR_ECCC | FLASH_ECCR_ECCIE))
411 {
412 /* Call User callback */
413 HAL_FLASHEx_EccCorrectionCallback();
414
415 /* Clear ECC correction flag in order to allow new ECC error record */
416 SET_BIT(FLASH->ECCR, FLASH_ECCR_ECCC);
417 }
418 }
419
420 /**
421 * @brief FLASH end of operation interrupt callback.
422 * @param ReturnValue The value saved in this parameter depends on the ongoing procedure :
423 * @arg Mass Erase: 0
424 * @arg Page Erase: Page which has been erased
425 * (if 0xFFFFFFFF, it means that all the selected pages have been erased)
426 * @arg Program: Address which was selected for data program
427 * @retval None
428 */
HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)429 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
430 {
431 /* Prevent unused argument(s) compilation warning */
432 UNUSED(ReturnValue);
433
434 /* NOTE : This function should not be modified, when the callback is needed,
435 the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
436 */
437 }
438
439 /**
440 * @brief FLASH operation error interrupt callback.
441 * @param ReturnValue The value saved in this parameter depends on the ongoing procedure :
442 * @arg Mass Erase: 0
443 * @arg Page Erase: Page number which returned an error
444 * @arg Program: Address which was selected for data program
445 * @retval None
446 */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)447 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
448 {
449 /* Prevent unused argument(s) compilation warning */
450 UNUSED(ReturnValue);
451
452 /* NOTE : This function should not be modified, when the callback is needed,
453 the HAL_FLASH_OperationErrorCallback could be implemented in the user file
454 */
455 }
456
457 /**
458 * @}
459 */
460
461 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
462 * @brief Management functions
463 *
464 @verbatim
465 ===============================================================================
466 ##### Peripheral Control functions #####
467 ===============================================================================
468 [..]
469 This subsection provides a set of functions allowing to control the FLASH
470 memory operations.
471
472 @endverbatim
473 * @{
474 */
475
476 /**
477 * @brief Unlock the FLASH control register access.
478 * @retval HAL Status
479 */
HAL_FLASH_Unlock(void)480 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
481 {
482 HAL_StatusTypeDef status = HAL_OK;
483
484 if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
485 {
486 /* Authorize the FLASH Registers access */
487 WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
488 WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
489
490 /* verify Flash is unlocked */
491 if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
492 {
493 status = HAL_ERROR;
494 }
495 }
496
497 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
498 if (status == HAL_OK)
499 {
500 if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
501 {
502 /* Authorize the FLASH Registers access */
503 WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
504 WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
505
506 /* verify Flash is unlocked */
507 if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
508 {
509 status = HAL_ERROR;
510 }
511 }
512 }
513 #endif /* __ARM_FEATURE_CMSE */
514
515 return status;
516 }
517
518 /**
519 * @brief Lock the FLASH control register access.
520 * @retval HAL Status
521 */
HAL_FLASH_Lock(void)522 HAL_StatusTypeDef HAL_FLASH_Lock(void)
523 {
524 HAL_StatusTypeDef status = HAL_ERROR;
525
526 /* Set the LOCK Bit to lock the FLASH Registers access */
527 SET_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK);
528
529 /* verify Flash is locked */
530 if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_LOCK) != 0U)
531 {
532 status = HAL_OK;
533 }
534
535 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
536 if (status == HAL_OK)
537 {
538 SET_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK);
539
540 /* verify Flash is locked */
541 if (READ_BIT(FLASH->SECCR1, FLASH_SECCR1_LOCK) != 0U)
542 {
543 status = HAL_OK;
544 }
545 }
546 #endif /* __ARM_FEATURE_CMSE */
547
548 return status;
549 }
550
551 /**
552 * @brief Unlock the FLASH Option Bytes Registers access.
553 * @retval HAL Status
554 */
HAL_FLASH_OB_Unlock(void)555 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
556 {
557 if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
558 {
559 /* Authorizes the Option Byte register programming */
560 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
561 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
562
563 /* Verify that the Option Bytes are unlocked */
564 if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
565 {
566 return HAL_ERROR;
567 }
568 }
569
570 return HAL_OK;
571 }
572
573 /**
574 * @brief Lock the FLASH Option Bytes Registers access.
575 * @retval HAL Status
576 */
HAL_FLASH_OB_Lock(void)577 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
578 {
579 /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
580 SET_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK);
581
582 /* Verify that the Option Bytes are locked */
583 if (READ_BIT(FLASH->NSCR1, FLASH_NSCR1_OPTLOCK) != 0U)
584 {
585 return HAL_OK;
586 }
587
588 return HAL_ERROR;
589 }
590
591 /**
592 * @brief Launch the option byte loading.
593 * @retval HAL Status
594 */
HAL_FLASH_OB_Launch(void)595 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
596 {
597 /* Set the bit to force the option byte reloading */
598 SET_BIT(FLASH->NSCR1, FLASH_NSCR1_OBL_LAUNCH);
599
600 /* We should not reach here : Option byte launch generates Option byte reset
601 so return error */
602 return HAL_ERROR;
603 }
604
605 /**
606 * @}
607 */
608
609 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
610 * @brief Peripheral Errors functions
611 *
612 @verbatim
613 ===============================================================================
614 ##### Peripheral Errors functions #####
615 ===============================================================================
616 [..]
617 This subsection permits to get in run-time Errors of the FLASH peripheral.
618
619 @endverbatim
620 * @{
621 */
622
623 /**
624 * @brief Get the specific FLASH error flag.
625 * @retval FLASH_ErrorCode The returned value can be
626 * @arg @ref HAL_FLASH_ERROR_NONE No error set
627 * @arg @ref HAL_FLASH_ERROR_OP FLASH Operation error
628 * @arg @ref HAL_FLASH_ERROR_PROG FLASH Programming error
629 * @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
630 * @arg @ref HAL_FLASH_ERROR_PGA FLASH Programming alignment error
631 * @arg @ref HAL_FLASH_ERROR_SIZ FLASH Size error
632 * @arg @ref HAL_FLASH_ERROR_PGS FLASH Programming sequence error
633 * @arg @ref HAL_FLASH_ERROR_OPTW FLASH Option modification error
634 * @arg @ref HAL_FLASH_ERROR_OPTW FLASH Option write error
635 */
HAL_FLASH_GetError(void)636 uint32_t HAL_FLASH_GetError(void)
637 {
638 return pFlash.ErrorCode;
639 }
640
641 /**
642 * @}
643 */
644
645 /**
646 * @}
647 */
648
649 /* Private functions ---------------------------------------------------------*/
650
651 /** @addtogroup FLASH_Private_Functions
652 * @{
653 */
654
655 /**
656 * @brief Wait for a FLASH operation to complete.
657 * @param Timeout Maximum flash operation timeout
658 * @retval HAL_StatusTypeDef HAL Status
659 */
FLASH_WaitForLastOperation(uint32_t Timeout)660 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
661 {
662 /* Wait for the FLASH operation to complete by polling on BUSY and WDW flags to be reset.
663 Even if the FLASH operation fails, the BUSY & WDW flags will be reset, and an error flag will be set */
664
665 uint32_t timeout = HAL_GetTick() + Timeout;
666 uint32_t error;
667 __IO uint32_t *reg_sr;
668
669 /* Access to SECSR or NSSR registers depends on operation type */
670 #if defined(FLASH_SECSR_EOP)
671 reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
672 #else
673 reg_sr = &(FLASH_NS->NSSR);
674 #endif /* FLASH_SECSR_EOP */
675
676 while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WDW)) != 0U)
677 {
678 if (Timeout != HAL_MAX_DELAY)
679 {
680 if (HAL_GetTick() >= timeout)
681 {
682 return HAL_TIMEOUT;
683 }
684 }
685 }
686
687 /* Check FLASH operation error flags */
688 error = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
689 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
690 error |= (FLASH->NSSR & FLASH_FLAG_OPTWERR);
691 #endif /* __ARM_FEATURE_CMSE */
692
693 if (error != 0U)
694 {
695 /*Save the error code*/
696 pFlash.ErrorCode |= error;
697
698 /* Clear error programming flags */
699 (*reg_sr) = error;
700 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
701 if ((error & FLASH_FLAG_OPTWERR) != 0U)
702 {
703 FLASH->NSSR = FLASH_FLAG_OPTWERR;
704 }
705 #endif /* __ARM_FEATURE_CMSE */
706
707 return HAL_ERROR;
708 }
709
710 /* Check FLASH End of Operation flag */
711 if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
712 {
713 /* Clear FLASH End of Operation pending bit */
714 (*reg_sr) = FLASH_FLAG_EOP;
715 }
716
717 return HAL_OK;
718 }
719
720 /**
721 * @brief Program a quad-word (128-bit) at a specified address.
722 * @param Address Specifies the address to be programmed.
723 * @param DataAddress Specifies the address of data to be programmed.
724 * @retval None
725 */
FLASH_Program_QuadWord(uint32_t Address,uint32_t DataAddress)726 static void FLASH_Program_QuadWord(uint32_t Address, uint32_t DataAddress)
727 {
728 uint8_t index = 4;
729 uint32_t *dest_addr = (uint32_t *)Address;
730 uint32_t *src_addr = (uint32_t *)DataAddress;
731 uint32_t primask_bit;
732 __IO uint32_t *reg_cr;
733
734 /* Check the parameters */
735 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
736
737 /* Access to SECCR1 or NSCR1 registers depends on operation type */
738 #if defined(FLASH_SECCR1_LOCK)
739 reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
740 #else
741 reg_cr = &(FLASH_NS->NSCR1);
742 #endif /* FLASH_SECCR1_LOCK */
743
744 /* Set PG bit */
745 SET_BIT((*reg_cr), FLASH_NSCR1_PG);
746
747 /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
748 primask_bit = __get_PRIMASK();
749 __disable_irq();
750
751 /* Program the quad-word */
752 do
753 {
754 *dest_addr = *src_addr;
755 dest_addr++;
756 src_addr++;
757 index--;
758 } while (index != 0U);
759
760 /* Exit critical section: restore previous priority mask */
761 __set_PRIMASK(primask_bit);
762 }
763
764 /**
765 * @brief Program a burst of 8x quad-words at a specified address.
766 * @param Address Specifies the address to be programmed.
767 * @param DataAddress Specifies the address where the data are stored.
768 * @retval None
769 */
FLASH_Program_Burst(uint32_t Address,uint32_t DataAddress)770 static void FLASH_Program_Burst(uint32_t Address, uint32_t DataAddress)
771 {
772 uint8_t burst_index = FLASH_NB_WORDS_IN_BURST;
773 uint32_t *dest_addr = (uint32_t *)Address;
774 uint32_t *src_addr = (uint32_t *)DataAddress;
775 uint32_t primask_bit;
776 __IO uint32_t *reg_cr;
777
778 /* Check the parameters */
779 assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
780
781 /* Access to SECCR1 or NSCR1 registers depends on operation type */
782 #if defined(FLASH_SECCR1_LOCK)
783 reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR1) : &(FLASH_NS->NSCR1);
784 #else
785 reg_cr = &(FLASH_NS->NSCR1);
786 #endif /* FLASH_SECCR1_LOCK */
787
788 /* Set PG and BWR bits */
789 SET_BIT((*reg_cr), (FLASH_NSCR1_PG | FLASH_NSCR1_BWR));
790
791 /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
792 primask_bit = __get_PRIMASK();
793 __disable_irq();
794
795 /* Program the burst */
796 do
797 {
798 *dest_addr = *src_addr;
799 dest_addr++;
800 src_addr++;
801 burst_index--;
802 } while (burst_index != 0U);
803
804 /* Exit critical section: restore previous priority mask */
805 __set_PRIMASK(primask_bit);
806 }
807
808 /**
809 * @}
810 */
811
812 #endif /* HAL_FLASH_MODULE_ENABLED */
813
814 /**
815 * @}
816 */
817
818 /**
819 * @}
820 */
821