xref: /btstack/port/stm32-wb55xx-nucleo-freertos/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_flash.c (revision 0561b2d8d5dba972c7daa57d5e677f7a1327edfd)
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>&copy; 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