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