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