1 /**
2 ******************************************************************************
3 * @file stm32wbxx_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 * @attention
13 *
14 * Copyright (c) 2019 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### FLASH peripheral features #####
25 ==============================================================================
26
27 [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
28 to the Flash memory. It implements the erase and program Flash memory operations
29 and the read and write protection mechanisms.
30
31 [..] The Flash memory interface accelerates code execution with a system of instruction
32 prefetch and cache lines.
33
34 [..] The FLASH main features are:
35 (+) Flash memory read operations
36 (+) Flash memory program/erase operations
37 (+) Program and Erase suspension
38 (+) Read / write protections (2 areas per features)
39 (+) CPU2 Security area
40 (+) Option bytes programming
41 (+) Prefetch on CPU1 I-Code and CPU2 S-bus
42 (+) 32 instruction cache lines of 4*64 bits on I-Code for CPU1
43 (+) 8 data cache lines of 4*64 bits on D-Code for CPU1
44 (+) 4 instruction cache lines of 1*64 bits on S-bus for CPU2
45 (+) 4 data cache lines of 1*64 bits on S-Bus for CPU2
46 (+) Error code correction (ECC) : Data in flash are 72-bits word
47 (8 bits added per double word)
48
49 ##### How to use this driver #####
50 ==============================================================================
51 [..]
52 This driver provides functions and macros to configure and program the FLASH
53 memory of all STM32WBxx devices.
54
55 (#) Flash Memory IO Programming functions:
56 (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
57 HAL_FLASH_Lock() functions
58 (++) Program functions: double word and fast program (full row programming)
59 (++) There are two modes of programming:
60 (+++) Polling mode using HAL_FLASH_Program() function
61 (+++) Interrupt mode using HAL_FLASH_Program_IT() function
62
63 (#) Interrupts and flags management functions:
64 (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
65 (++) Callback functions are called when the flash operations are finished :
66 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
67 HAL_FLASH_OperationErrorCallback()
68 (++) Get error flag status by calling HAL_GetError()
69
70 (#) Option bytes management functions :
71 (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
72 HAL_FLASH_OB_Lock() functions
73 (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
74 In this case, a reset is generated
75
76 [..]
77 In addition to these functions, this driver includes a set of macros allowing
78 to handle the following operations:
79 (+) Set the latency
80 (+) Enable/Disable the prefetch buffer
81 (+) Enable/Disable the suspend program or erase request
82 (+) Enable/Disable the Instruction cache and the Data cache
83 (+) Reset the Instruction cache and the Data cache
84 (+) Enable/Disable the Flash interrupts
85 (+) Monitor the Flash flags status
86
87 @endverbatim
88 ******************************************************************************
89 */
90
91 /* Includes ------------------------------------------------------------------*/
92 #include "stm32wbxx_hal.h"
93
94 /** @addtogroup STM32WBxx_HAL_Driver
95 * @{
96 */
97
98 /** @defgroup FLASH FLASH
99 * @brief FLASH HAL module driver
100 * @{
101 */
102
103 #ifdef HAL_FLASH_MODULE_ENABLED
104
105 /* Private typedef -----------------------------------------------------------*/
106 /* Private defines -----------------------------------------------------------*/
107 /** @addtogroup FLASH_Private_Constants
108 * @{
109 */
110 #define FLASH_NB_DOUBLE_WORDS_IN_ROW 64
111 /**
112 * @}
113 */
114
115 /* Private macros ------------------------------------------------------------*/
116 /* Private variables ---------------------------------------------------------*/
117 /** @defgroup FLASH_Private_Variables FLASH Private Variables
118 * @{
119 */
120 /**
121 * @brief Variable used for Program/Erase sectors under interruption
122 */
123 FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
124 .ErrorCode = HAL_FLASH_ERROR_NONE, \
125 .ProcedureOnGoing = 0U, \
126 .Address = 0U, \
127 .Page = 0U, \
128 .NbPagesToErase = 0U
129 };
130 /**
131 * @}
132 */
133
134 /* Private function prototypes -----------------------------------------------*/
135 /** @defgroup FLASH_Private_Functions FLASH Private Functions
136 * @{
137 */
138 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
139 static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress);
140 /**
141 * @}
142 */
143
144 /* Exported functions --------------------------------------------------------*/
145 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
146 * @{
147 */
148
149 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
150 * @brief Programming operation functions
151 *
152 @verbatim
153 ===============================================================================
154 ##### Programming operation functions #####
155 ===============================================================================
156 [..]
157 This subsection provides a set of functions allowing to manage the FLASH
158 program operations.
159
160 @endverbatim
161 * @{
162 */
163
164 /**
165 * @brief Program double word or fast program of a row at a specified address.
166 * @note Before any operation, it is possible to check there is no operation suspended
167 * by call HAL_FLASHEx_IsOperationSuspended()
168 * @param TypeProgram Indicate the way to program at a specified address
169 * This parameter can be a value of @ref FLASH_TYPE_PROGRAM
170 * @param Address Specifies the address to be programmed.
171 * @param Data Specifies the data to be programmed
172 * This parameter is the data for the double word program and the address where
173 * are stored the data for the row fast program.
174 *
175 * @retval HAL_StatusTypeDef HAL Status
176 */
HAL_FLASH_Program(uint32_t TypeProgram,uint32_t Address,uint64_t Data)177 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
178 {
179 HAL_StatusTypeDef status;
180
181 /* Check the parameters */
182 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
183 assert_param(IS_ADDR_ALIGNED_64BITS(Address));
184 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
185
186 /* Process Locked */
187 __HAL_LOCK(&pFlash);
188
189 /* Reset error code */
190 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
191
192 /* Verify that next operation can be proceed */
193 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
194
195 if (status == HAL_OK)
196 {
197 if (TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
198 {
199 /* Check the parameters */
200 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
201
202 /* Program double-word (64-bit) at a specified address */
203 FLASH_Program_DoubleWord(Address, Data);
204 }
205 else
206 {
207 /* Check the parameters */
208 assert_param(IS_FLASH_FAST_PROGRAM_ADDRESS(Address));
209
210 /* Fast program a 64 row double-word (64-bit) at a specified address */
211 FLASH_Program_Fast(Address, (uint32_t)Data);
212 }
213
214 /* Wait for last operation to be completed */
215 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
216
217 /* If the program operation is completed, disable the PG or FSTPG Bit */
218 CLEAR_BIT(FLASH->CR, TypeProgram);
219 }
220
221 /* Process Unlocked */
222 __HAL_UNLOCK(&pFlash);
223
224 /* return status */
225 return status;
226 }
227
228 /**
229 * @brief Program double word or fast program of a row at a specified address with interrupt enabled.
230 * @note Before any operation, it is possible to check there is no operation suspended
231 * by call HAL_FLASHEx_IsOperationSuspended()
232 * @param TypeProgram Indicate the way to program at a specified address.
233 * This parameter can be a value of @ref FLASH_TYPE_PROGRAM
234 * @param Address Specifies the address to be programmed.
235 * @param Data Specifies the data to be programmed
236 * This parameter is the data for the double word program and the address where
237 * are stored the data for the row fast program.
238 *
239 * @retval HAL Status
240 */
HAL_FLASH_Program_IT(uint32_t TypeProgram,uint32_t Address,uint64_t Data)241 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
242 {
243 HAL_StatusTypeDef status;
244
245 /* Check the parameters */
246 assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
247 assert_param(IS_ADDR_ALIGNED_64BITS(Address));
248 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
249
250 /* Process Locked */
251 __HAL_LOCK(&pFlash);
252
253 /* Reset error code */
254 pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
255
256 /* Verify that next operation can be proceed */
257 status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
258
259 if (status != HAL_OK)
260 {
261 /* Process Unlocked */
262 __HAL_UNLOCK(&pFlash);
263 }
264 else
265 {
266 /* Set internal variables used by the IRQ handler */
267 pFlash.ProcedureOnGoing = TypeProgram;
268 pFlash.Address = Address;
269
270 /* Enable End of Operation and Error interrupts */
271 __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
272
273 if (TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
274 {
275 /* Check the parameters */
276 assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
277
278 /* Program double-word (64-bit) at a specified address */
279 FLASH_Program_DoubleWord(Address, Data);
280 }
281 else
282 {
283 /* Check the parameters */
284 assert_param(IS_FLASH_FAST_PROGRAM_ADDRESS(Address));
285
286 /* Fast program a 64 row double-word (64-bit) at a specified address */
287 FLASH_Program_Fast(Address, (uint32_t)Data);
288 }
289 }
290
291 /* return status */
292 return status;
293 }
294
295 /**
296 * @brief Handle FLASH interrupt request.
297 * @retval None
298 */
HAL_FLASH_IRQHandler(void)299 void HAL_FLASH_IRQHandler(void)
300 {
301 uint32_t param = 0xFFFFFFFFU;
302 uint32_t error;
303
304 /* Check FLASH operation error flags */
305 error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
306
307 /* Clear Current operation */
308 CLEAR_BIT(FLASH->CR, pFlash.ProcedureOnGoing);
309
310 /* A] Set parameter for user or error callbacks */
311 /* check operation was a program or erase */
312 if ((pFlash.ProcedureOnGoing & (FLASH_TYPEPROGRAM_DOUBLEWORD | FLASH_TYPEPROGRAM_FAST)) != 0U)
313 {
314 /* return address being programmed */
315 param = pFlash.Address;
316 }
317 else if ((pFlash.ProcedureOnGoing & (FLASH_TYPEERASE_PAGES)) != 0U)
318 {
319 /* return page number being erased */
320 param = pFlash.Page;
321 }
322 else
323 {
324 /* No Procedure on-going */
325 /* Nothing to do, but check error if any */
326 }
327
328 /* B] Check errors */
329 if (error != 0U)
330 {
331 /*Save the error code*/
332 pFlash.ErrorCode |= error;
333
334 /* clear error flags */
335 __HAL_FLASH_CLEAR_FLAG(error);
336
337 /*Stop the procedure ongoing*/
338 pFlash.ProcedureOnGoing = FLASH_TYPENONE;
339
340 /* Error callback */
341 HAL_FLASH_OperationErrorCallback(param);
342 }
343
344 /* C] Check FLASH End of Operation flag */
345 if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
346 {
347 /* Clear FLASH End of Operation pending bit */
348 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
349
350 if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_PAGES)
351 {
352 /* Nb of pages to erased can be decreased */
353 pFlash.NbPagesToErase--;
354
355 /* Check if there are still pages to erase*/
356 if (pFlash.NbPagesToErase != 0U)
357 {
358 /* Increment page number */
359 pFlash.Page++;
360 FLASH_PageErase(pFlash.Page);
361 }
362 else
363 {
364 /* No more pages to erase: stop erase pages procedure */
365 pFlash.ProcedureOnGoing = FLASH_TYPENONE;
366 }
367 }
368 else
369 {
370 /*Stop the ongoing procedure */
371 pFlash.ProcedureOnGoing = FLASH_TYPENONE;
372 }
373
374 /* User callback */
375 HAL_FLASH_EndOfOperationCallback(param);
376 }
377
378 if (pFlash.ProcedureOnGoing == FLASH_TYPENONE)
379 {
380 /* Disable End of Operation and Error interrupts */
381 __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
382
383 /* Process Unlocked */
384 __HAL_UNLOCK(&pFlash);
385 }
386 }
387
388 /**
389 * @brief FLASH end of operation interrupt callback.
390 * @param ReturnValue The value saved in this parameter depends on the ongoing procedure
391 * Page Erase: Page which has 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 * Page Erase: Page number which returned an error
409 * Program: Address which was selected for data program
410 * @retval None
411 */
HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)412 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
413 {
414 /* Prevent unused argument(s) compilation warning */
415 UNUSED(ReturnValue);
416
417 /* NOTE : This function should not be modified, when the callback is needed,
418 the HAL_FLASH_OperationErrorCallback could be implemented in the user file
419 */
420 }
421
422 /**
423 * @}
424 */
425
426 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
427 * @brief Management functions
428 *
429 @verbatim
430 ===============================================================================
431 ##### Peripheral Control functions #####
432 ===============================================================================
433 [..]
434 This subsection provides a set of functions allowing to control the FLASH
435 memory operations.
436
437 @endverbatim
438 * @{
439 */
440
441 /**
442 * @brief Unlock the FLASH control register access.
443 * @retval HAL Status
444 */
HAL_FLASH_Unlock(void)445 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
446 {
447 HAL_StatusTypeDef status = HAL_OK;
448
449 if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
450 {
451 /* Authorize the FLASH Registers access */
452 WRITE_REG(FLASH->KEYR, FLASH_KEY1);
453 WRITE_REG(FLASH->KEYR, FLASH_KEY2);
454
455 /* verify Flash is unlock */
456 if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
457 {
458 status = HAL_ERROR;
459 }
460 }
461
462 return status;
463 }
464
465 /**
466 * @brief Lock the FLASH control register access.
467 * @retval HAL Status
468 */
HAL_FLASH_Lock(void)469 HAL_StatusTypeDef HAL_FLASH_Lock(void)
470 {
471 HAL_StatusTypeDef status = HAL_OK;
472
473 /* Set the LOCK Bit to lock the FLASH Registers access */
474 /* @Note The lock and unlock procedure is done only using CR registers even from CPU2 */
475 SET_BIT(FLASH->CR, FLASH_CR_LOCK);
476
477 /* verify Flash is locked */
478 if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) == 0U)
479 {
480 status = HAL_ERROR;
481 }
482
483 return status;
484 }
485
486 /**
487 * @brief Unlock the FLASH Option Bytes Registers access.
488 * @retval HAL Status
489 */
HAL_FLASH_OB_Unlock(void)490 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
491 {
492 HAL_StatusTypeDef status = HAL_ERROR;
493
494 /* @Note The lock and unlock procedure is done only using CR registers even from CPU2 */
495 if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0U)
496 {
497 /* Authorizes the Option Byte register programming */
498 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
499 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
500
501 /* verify option bytes are unlocked */
502 if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0U)
503 {
504 status = HAL_OK;
505 }
506 }
507
508 return status;
509 }
510
511 /**
512 * @brief Lock the FLASH Option Bytes Registers access.
513 * @retval HAL Status
514 */
HAL_FLASH_OB_Lock(void)515 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
516 {
517 HAL_StatusTypeDef status = HAL_OK;
518
519 /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
520 /* @Note The lock and unlock procedure is done only using CR registers even from CPU2 */
521 SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
522
523 /* verify option bytes are lock */
524 if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0U)
525 {
526 status = HAL_ERROR;
527 }
528
529 return status;
530 }
531
532 /**
533 * @brief Launch the option byte loading.
534 * @retval HAL Status
535 */
HAL_FLASH_OB_Launch(void)536 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
537 {
538 /* Set the bit to force the option byte reloading */
539 /* The OB launch is done from the same register either from CPU1 or CPU2 */
540 SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
541
542 /* We should not reach here : Option byte launch generates Option byte reset
543 so return error */
544 return HAL_ERROR;
545 }
546
547 /**
548 * @}
549 */
550
551 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
552 * @brief Peripheral Errors functions
553 *
554 @verbatim
555 ===============================================================================
556 ##### Peripheral Errors functions #####
557 ===============================================================================
558 [..]
559 This subsection permits to get in run-time Errors of the FLASH peripheral.
560
561 @endverbatim
562 * @{
563 */
564
565 /**
566 * @brief Get the specific FLASH error flag.
567 * @retval FLASH_ErrorCode The returned value can be
568 * @arg @ref HAL_FLASH_ERROR_NONE No error set
569 * @arg @ref HAL_FLASH_ERROR_OP FLASH Operation error
570 * @arg @ref HAL_FLASH_ERROR_PROG FLASH Programming error
571 * @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
572 * @arg @ref HAL_FLASH_ERROR_PGA FLASH Programming alignment error
573 * @arg @ref HAL_FLASH_ERROR_SIZ FLASH Size error
574 * @arg @ref HAL_FLASH_ERROR_PGS FLASH Programming sequence error
575 * @arg @ref HAL_FLASH_ERROR_MIS FLASH Fast programming data miss error
576 * @arg @ref HAL_FLASH_ERROR_FAST FLASH Fast programming error
577 * @arg @ref HAL_FLASH_ERROR_RD FLASH Read Protection error (PCROP)
578 * @arg @ref HAL_FLASH_ERROR_OPTV FLASH Option validity error
579 */
HAL_FLASH_GetError(void)580 uint32_t HAL_FLASH_GetError(void)
581 {
582 return pFlash.ErrorCode;
583 }
584
585 /**
586 * @}
587 */
588
589 /**
590 * @}
591 */
592
593 /* Private functions ---------------------------------------------------------*/
594
595 /** @addtogroup FLASH_Private_Functions
596 * @{
597 */
598
599 /**
600 * @brief Wait for a FLASH operation to complete.
601 * @param Timeout Maximum flash operation timeout
602 * @retval HAL_StatusTypeDef HAL Status
603 */
FLASH_WaitForLastOperation(uint32_t Timeout)604 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
605 {
606 uint32_t error;
607 uint32_t tickstart = HAL_GetTick();
608
609 /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
610 Even if the FLASH operation fails, the BUSY flag will be reset and an error
611 flag will be set */
612 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
613 {
614 if ((HAL_GetTick() - tickstart) >= Timeout)
615 {
616 return HAL_TIMEOUT;
617 }
618 }
619
620 /* Check FLASH operation error flags */
621 error = FLASH->SR;
622
623 /* Check FLASH End of Operation flag */
624 if ((error & FLASH_FLAG_EOP) != 0U)
625 {
626 /* Clear FLASH End of Operation pending bit */
627 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
628 }
629
630 /* Workaround for BZ 70309 :
631 - OPTVERR is always set at power-up due to failure of engi bytes checking
632 - FLASH_WaitForLastOperation() is called at the beginning of erase or program
633 operations, so the bit will be clear when performing first operation */
634 if ((error & FLASH_FLAG_OPTVERR) != 0U)
635 {
636 /* Clear FLASH OPTVERR bit */
637 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
638
639 /* Clear OPTVERR bit in "error" variable to not treat it as error */
640 error &= ~FLASH_FLAG_OPTVERR;
641 }
642
643 /* Now update error variable to only error value */
644 error &= FLASH_FLAG_SR_ERRORS;
645
646 /* clear error flags */
647 __HAL_FLASH_CLEAR_FLAG(error);
648
649 if (error != 0U)
650 {
651 /*Save the error code*/
652 pFlash.ErrorCode = error;
653
654 return HAL_ERROR;
655 }
656
657 /* Wait for control register to be written */
658 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY))
659 {
660 if ((HAL_GetTick() - tickstart) >= Timeout)
661 {
662 return HAL_TIMEOUT;
663 }
664 }
665
666 return HAL_OK;
667 }
668
669 /**
670 * @brief Program double-word (64-bit) at a specified address.
671 * @param Address Specifies the address to be programmed.
672 * @param Data Specifies the data to be programmed.
673 * @retval None
674 */
FLASH_Program_DoubleWord(uint32_t Address,uint64_t Data)675 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
676 {
677 /* Set PG bit */
678 SET_BIT(FLASH->CR, FLASH_CR_PG);
679
680 /* Program first word */
681 *(uint32_t *)Address = (uint32_t)Data;
682
683 /* Barrier to ensure programming is performed in 2 steps, in right order
684 (independently of compiler optimization behavior) */
685 __ISB();
686
687 /* Program second word */
688 *(uint32_t *)(Address + 4U) = (uint32_t)(Data >> 32U);
689 }
690
691 /**
692 * @brief Fast program a 32 row double-word (64-bit) at a specified address.
693 * @param Address Specifies the address to be programmed.
694 * @param DataAddress Specifies the address where the data are stored.
695 * @retval None
696 */
FLASH_Program_Fast(uint32_t Address,uint32_t DataAddress)697 static __RAM_FUNC void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
698 {
699 uint8_t row_index = (2 * FLASH_NB_DOUBLE_WORDS_IN_ROW);
700 __IO uint32_t *dest_addr = (__IO uint32_t *)Address;
701 __IO uint32_t *src_addr = (__IO uint32_t *)DataAddress;
702 uint32_t primask_bit;
703
704 /* Set FSTPG bit */
705 SET_BIT(FLASH->CR, FLASH_CR_FSTPG);
706
707 /* Enter critical section: row programming should not be longer than 7 ms */
708 primask_bit = __get_PRIMASK();
709 __disable_irq();
710
711 /* Program the double word of the row */
712 do
713 {
714 *dest_addr = *src_addr;
715 dest_addr++;
716 src_addr++;
717 row_index--;
718 } while (row_index != 0U);
719
720 /* wait for BSY in order to be sure that flash operation is ended before
721 allowing prefetch in flash. Timeout does not return status, as it will
722 be anyway done later */
723 while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0U)
724 {
725 }
726
727 /* Exit critical section: restore previous priority mask */
728 __set_PRIMASK(primask_bit);
729 }
730
731 /**
732 * @}
733 */
734
735 #endif /* HAL_FLASH_MODULE_ENABLED */
736
737 /**
738 * @}
739 */
740
741 /**
742 * @}
743 */
744