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