STM32L443xx HAL User Manual
stm32l4xx_hal_flash.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_flash.c
00004   * @author  MCD Application Team
00005   * @brief   FLASH HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the internal FLASH memory:
00008   *           + Program operations functions
00009   *           + Memory Control functions
00010   *           + Peripheral Errors functions
00011   *
00012  @verbatim
00013   ==============================================================================
00014                         ##### FLASH peripheral features #####
00015   ==============================================================================
00016 
00017   [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
00018        to the Flash memory. It implements the erase and program Flash memory operations
00019        and the read and write protection mechanisms.
00020 
00021   [..] The Flash memory interface accelerates code execution with a system of instruction
00022        prefetch and cache lines.
00023 
00024   [..] The FLASH main features are:
00025       (+) Flash memory read operations
00026       (+) Flash memory program/erase operations
00027       (+) Read / write protections
00028       (+) Option bytes programming
00029       (+) Prefetch on I-Code
00030       (+) 32 cache lines of 4*64 bits on I-Code
00031       (+) 8 cache lines of 4*64 bits on D-Code
00032       (+) Error code correction (ECC) : Data in flash are 72-bits word
00033           (8 bits added per double word)
00034 
00035 
00036                         ##### How to use this driver #####
00037  ==============================================================================
00038     [..]
00039       This driver provides functions and macros to configure and program the FLASH
00040       memory of all STM32L4xx devices.
00041 
00042       (#) Flash Memory IO Programming functions:
00043            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
00044                 HAL_FLASH_Lock() functions
00045            (++) Program functions: double word and fast program (full row programming)
00046            (++) There Two modes of programming :
00047             (+++) Polling mode using HAL_FLASH_Program() function
00048             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
00049 
00050       (#) Interrupts and flags management functions :
00051            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
00052            (++) Callback functions are called when the flash operations are finished :
00053                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
00054                 HAL_FLASH_OperationErrorCallback()
00055            (++) Get error flag status by calling HAL_GetError()
00056 
00057       (#) Option bytes management functions :
00058            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
00059                 HAL_FLASH_OB_Lock() functions
00060            (++) Launch the reload of the option bytes using HAL_FLASH_Launch() function.
00061                 In this case, a reset is generated
00062 
00063     [..]
00064       In addition to these functions, this driver includes a set of macros allowing
00065       to handle the following operations:
00066        (+) Set the latency
00067        (+) Enable/Disable the prefetch buffer
00068        (+) Enable/Disable the Instruction cache and the Data cache
00069        (+) Reset the Instruction cache and the Data cache
00070        (+) Enable/Disable the Flash power-down during low-power run and sleep modes
00071        (+) Enable/Disable the Flash interrupts
00072        (+) Monitor the Flash flags status
00073 
00074  @endverbatim
00075   ******************************************************************************
00076   * @attention
00077   *
00078   * Copyright (c) 2017 STMicroelectronics.
00079   * All rights reserved.
00080   *
00081   * This software is licensed under terms that can be found in the LICENSE file in
00082   * the root directory of this software component.
00083   * If no LICENSE file comes with this software, it is provided AS-IS.
00084   ******************************************************************************
00085   */
00086 
00087 /* Includes ------------------------------------------------------------------*/
00088 #include "stm32l4xx_hal.h"
00089 
00090 /** @addtogroup STM32L4xx_HAL_Driver
00091   * @{
00092   */
00093 
00094 /** @defgroup FLASH FLASH
00095   * @brief FLASH HAL module driver
00096   * @{
00097   */
00098 
00099 #ifdef HAL_FLASH_MODULE_ENABLED
00100 
00101 /* Private typedef -----------------------------------------------------------*/
00102 /* Private defines -----------------------------------------------------------*/
00103 #if defined (STM32L4P5xx) || defined (STM32L4Q5xx) || defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00104 #define FLASH_NB_DOUBLE_WORDS_IN_ROW  64
00105 #else
00106 #define FLASH_NB_DOUBLE_WORDS_IN_ROW  32
00107 #endif
00108 /* Private macros ------------------------------------------------------------*/
00109 /* Private variables ---------------------------------------------------------*/
00110 /** @defgroup FLASH_Private_Variables FLASH Private Variables
00111  * @{
00112  */
00113 /**
00114   * @brief  Variable used for Program/Erase sectors under interruption
00115   */
00116 FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
00117                                .ErrorCode = HAL_FLASH_ERROR_NONE, \
00118                                .ProcedureOnGoing = FLASH_PROC_NONE, \
00119                                .Address = 0U, \
00120                                .Bank = FLASH_BANK_1, \
00121                                .Page = 0U, \
00122                                .NbPagesToErase = 0U, \
00123                                .CacheToReactivate = FLASH_CACHE_DISABLED};
00124 /**
00125   * @}
00126   */
00127 
00128 /* Private function prototypes -----------------------------------------------*/
00129 /** @defgroup FLASH_Private_Functions FLASH Private Functions
00130  * @{
00131  */
00132 static void          FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
00133 static void          FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress);
00134 /**
00135   * @}
00136   */
00137 
00138 /* Exported functions --------------------------------------------------------*/
00139 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
00140   * @{
00141   */
00142 
00143 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
00144  *  @brief   Programming operation functions
00145  *
00146 @verbatim
00147  ===============================================================================
00148                   ##### Programming operation functions #####
00149  ===============================================================================
00150     [..]
00151     This subsection provides a set of functions allowing to manage the FLASH
00152     program operations.
00153 
00154 @endverbatim
00155   * @{
00156   */
00157 
00158 /**
00159   * @brief  Program double word or fast program of a row at a specified address.
00160   * @param  TypeProgram  Indicate the way to program at a specified address.
00161   *                           This parameter can be a value of @ref FLASH_Type_Program
00162   * @param  Address  specifies the address to be programmed.
00163   * @param  Data specifies the data to be programmed
00164   *                This parameter is the data for the double word program and the address where
00165   *                are stored the data for the row fast program
00166   *
00167   * @retval HAL_StatusTypeDef HAL Status
00168   */
00169 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
00170 {
00171   HAL_StatusTypeDef status;
00172   uint32_t prog_bit = 0;
00173 
00174   /* Process Locked */
00175   __HAL_LOCK(&pFlash);
00176 
00177   /* Check the parameters */
00178   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00179 
00180   /* Wait for last operation to be completed */
00181   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00182 
00183   if(status == HAL_OK)
00184   {
00185     pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00186 
00187     /* Deactivate the data cache if they are activated to avoid data misbehavior */
00188     if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
00189     {
00190       /* Disable data cache  */
00191       __HAL_FLASH_DATA_CACHE_DISABLE();
00192       pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
00193     }
00194     else
00195     {
00196       pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
00197     }
00198 
00199     if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
00200     {
00201       /* Program double-word (64-bit) at a specified address */
00202       FLASH_Program_DoubleWord(Address, Data);
00203       prog_bit = FLASH_CR_PG;
00204     }
00205     else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
00206     {
00207       /* Fast program a 32 row double-word (64-bit) at a specified address */
00208       FLASH_Program_Fast(Address, (uint32_t)Data);
00209 
00210       /* If it is the last row, the bit will be cleared at the end of the operation */
00211       if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
00212       {
00213         prog_bit = FLASH_CR_FSTPG;
00214       }
00215     }
00216     else
00217     {
00218       /* Nothing to do */
00219     }
00220 
00221     /* Wait for last operation to be completed */
00222     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00223 
00224     /* If the program operation is completed, disable the PG or FSTPG Bit */
00225     if (prog_bit != 0U)
00226     {
00227       CLEAR_BIT(FLASH->CR, prog_bit);
00228     }
00229 
00230     /* Flush the caches to be sure of the data consistency */
00231     FLASH_FlushCaches();
00232   }
00233 
00234   /* Process Unlocked */
00235   __HAL_UNLOCK(&pFlash);
00236 
00237   return status;
00238 }
00239 
00240 /**
00241   * @brief  Program double word or fast program of a row at a specified address with interrupt enabled.
00242   * @param  TypeProgram  Indicate the way to program at a specified address.
00243   *                           This parameter can be a value of @ref FLASH_Type_Program
00244   * @param  Address  specifies the address to be programmed.
00245   * @param  Data specifies the data to be programmed
00246   *                This parameter is the data for the double word program and the address where
00247   *                are stored the data for the row fast program
00248   *
00249   * @retval HAL Status
00250   */
00251 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
00252 {
00253   HAL_StatusTypeDef status = HAL_OK;
00254 
00255   /* Check the parameters */
00256   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00257 
00258   /* Process Locked */
00259   __HAL_LOCK(&pFlash);
00260 
00261   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00262 
00263   /* Deactivate the data cache if they are activated to avoid data misbehavior */
00264   if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != 0U)
00265   {
00266     /* Disable data cache  */
00267     __HAL_FLASH_DATA_CACHE_DISABLE();
00268     pFlash.CacheToReactivate = FLASH_CACHE_DCACHE_ENABLED;
00269   }
00270   else
00271   {
00272     pFlash.CacheToReactivate = FLASH_CACHE_DISABLED;
00273   }
00274 
00275   /* Set internal variables used by the IRQ handler */
00276   if(TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST)
00277   {
00278     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_LAST;
00279   }
00280   else
00281   {
00282     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
00283   }
00284   pFlash.Address = Address;
00285 
00286   /* Enable End of Operation and Error interrupts */
00287   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
00288 
00289   if(TypeProgram == FLASH_TYPEPROGRAM_DOUBLEWORD)
00290   {
00291     /* Program double-word (64-bit) at a specified address */
00292     FLASH_Program_DoubleWord(Address, Data);
00293   }
00294   else if((TypeProgram == FLASH_TYPEPROGRAM_FAST) || (TypeProgram == FLASH_TYPEPROGRAM_FAST_AND_LAST))
00295   {
00296     /* Fast program a 32 row double-word (64-bit) at a specified address */
00297     FLASH_Program_Fast(Address, (uint32_t)Data);
00298   }
00299   else
00300   {
00301     /* Nothing to do */
00302   }
00303 
00304   return status;
00305 }
00306 
00307 /**
00308   * @brief Handle FLASH interrupt request.
00309   * @retval None
00310   */
00311 void HAL_FLASH_IRQHandler(void)
00312 {
00313   uint32_t tmp_page;
00314   uint32_t error;
00315   FLASH_ProcedureTypeDef procedure;
00316 
00317   /* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */
00318   CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_PER | FLASH_CR_PNB));
00319 #if defined (STM32L471xx) || defined (STM32L475xx) || defined (STM32L476xx) || defined (STM32L485xx) || defined (STM32L486xx) || \
00320     defined (STM32L496xx) || defined (STM32L4A6xx) || \
00321     defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \
00322     defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
00323   CLEAR_BIT(FLASH->CR, FLASH_CR_MER2);
00324 #endif
00325 
00326   /* Disable the FSTPG Bit only if it is the last row programmed */
00327   if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)
00328   {
00329     CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG);
00330   }
00331 
00332   /* Check FLASH operation error flags */
00333   error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
00334 
00335   if (error !=0U)
00336   {
00337     /*Save the error code*/
00338     pFlash.ErrorCode |= error;
00339 
00340     /* Clear error programming flags */
00341     __HAL_FLASH_CLEAR_FLAG(error);
00342 
00343     /* Flush the caches to be sure of the data consistency */
00344     FLASH_FlushCaches() ;
00345 
00346     /* FLASH error interrupt user callback */
00347     procedure = pFlash.ProcedureOnGoing;
00348     if(procedure == FLASH_PROC_PAGE_ERASE)
00349     {
00350        HAL_FLASH_OperationErrorCallback(pFlash.Page);
00351     }
00352     else if(procedure == FLASH_PROC_MASS_ERASE)
00353     {
00354         HAL_FLASH_OperationErrorCallback(pFlash.Bank);
00355     }
00356     else if((procedure == FLASH_PROC_PROGRAM) ||
00357             (procedure == FLASH_PROC_PROGRAM_LAST))
00358     {
00359        HAL_FLASH_OperationErrorCallback(pFlash.Address);
00360     }
00361     else
00362     {
00363        HAL_FLASH_OperationErrorCallback(0U);
00364     }
00365 
00366     /*Stop the procedure ongoing*/
00367     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00368   }
00369 
00370   /* Check FLASH End of Operation flag  */
00371   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0U)
00372   {
00373     /* Clear FLASH End of Operation pending bit */
00374     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
00375 
00376     if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE)
00377     {
00378       /* Nb of pages to erased can be decreased */
00379       pFlash.NbPagesToErase--;
00380 
00381       /* Check if there are still pages to erase*/
00382       if(pFlash.NbPagesToErase != 0U)
00383       {
00384         /* Indicate user which page has been erased*/
00385         HAL_FLASH_EndOfOperationCallback(pFlash.Page);
00386 
00387         /* Increment page number */
00388         pFlash.Page++;
00389         tmp_page = pFlash.Page;
00390         FLASH_PageErase(tmp_page, pFlash.Bank);
00391       }
00392       else
00393       {
00394         /* No more pages to Erase */
00395         /* Reset Address and stop Erase pages procedure */
00396         pFlash.Page = 0xFFFFFFFFU;
00397         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00398 
00399         /* Flush the caches to be sure of the data consistency */
00400         FLASH_FlushCaches() ;
00401 
00402         /* FLASH EOP interrupt user callback */
00403         HAL_FLASH_EndOfOperationCallback(pFlash.Page);
00404       }
00405     }
00406     else
00407     {
00408       /* Flush the caches to be sure of the data consistency */
00409       FLASH_FlushCaches() ;
00410 
00411       procedure = pFlash.ProcedureOnGoing;
00412       if(procedure == FLASH_PROC_MASS_ERASE)
00413       {
00414         /* MassErase ended. Return the selected bank */
00415         /* FLASH EOP interrupt user callback */
00416         HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
00417       }
00418       else if((procedure == FLASH_PROC_PROGRAM) ||
00419               (procedure == FLASH_PROC_PROGRAM_LAST))
00420       {
00421         /* Program ended. Return the selected address */
00422         /* FLASH EOP interrupt user callback */
00423         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00424       }
00425       else
00426       {
00427         /* Nothing to do */
00428       }
00429 
00430       /*Clear the procedure ongoing*/
00431       pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00432     }
00433   }
00434 
00435   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
00436   {
00437     /* Disable End of Operation and Error interrupts */
00438     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
00439 
00440     /* Process Unlocked */
00441     __HAL_UNLOCK(&pFlash);
00442   }
00443 }
00444 
00445 /**
00446   * @brief  FLASH end of operation interrupt callback.
00447   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
00448   *                  Mass Erase: Bank number which has been requested to erase
00449   *                  Page Erase: Page which has been erased
00450   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
00451   *                  Program: Address which was selected for data program
00452   * @retval None
00453   */
00454 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
00455 {
00456   /* Prevent unused argument(s) compilation warning */
00457   UNUSED(ReturnValue);
00458 
00459   /* NOTE : This function should not be modified, when the callback is needed,
00460             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
00461    */
00462 }
00463 
00464 /**
00465   * @brief  FLASH operation error interrupt callback.
00466   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
00467   *                 Mass Erase: Bank number which has been requested to erase
00468   *                 Page Erase: Page number which returned an error
00469   *                 Program: Address which was selected for data program
00470   * @retval None
00471   */
00472 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
00473 {
00474   /* Prevent unused argument(s) compilation warning */
00475   UNUSED(ReturnValue);
00476 
00477   /* NOTE : This function should not be modified, when the callback is needed,
00478             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
00479    */
00480 }
00481 
00482 /**
00483   * @}
00484   */
00485 
00486 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
00487  *  @brief   Management functions
00488  *
00489 @verbatim
00490  ===============================================================================
00491                       ##### Peripheral Control functions #####
00492  ===============================================================================
00493     [..]
00494     This subsection provides a set of functions allowing to control the FLASH
00495     memory operations.
00496 
00497 @endverbatim
00498   * @{
00499   */
00500 
00501 /**
00502   * @brief  Unlock the FLASH control register access.
00503   * @retval HAL Status
00504   */
00505 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
00506 {
00507   HAL_StatusTypeDef status = HAL_OK;
00508 
00509   if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
00510   {
00511     /* Authorize the FLASH Registers access */
00512     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
00513     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
00514 
00515     /* Verify Flash is unlocked */
00516     if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U)
00517     {
00518       status = HAL_ERROR;
00519     }
00520   }
00521 
00522   return status;
00523 }
00524 
00525 /**
00526   * @brief  Lock the FLASH control register access.
00527   * @retval HAL Status
00528   */
00529 HAL_StatusTypeDef HAL_FLASH_Lock(void)
00530 {
00531   /* Set the LOCK Bit to lock the FLASH Registers access */
00532   SET_BIT(FLASH->CR, FLASH_CR_LOCK);
00533 
00534   return HAL_OK;
00535 }
00536 
00537 /**
00538   * @brief  Unlock the FLASH Option Bytes Registers access.
00539   * @retval HAL Status
00540   */
00541 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
00542 {
00543   if(READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0U)
00544   {
00545     /* Authorizes the Option Byte register programming */
00546     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
00547     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
00548   }
00549   else
00550   {
00551     return HAL_ERROR;
00552   }
00553 
00554   return HAL_OK;
00555 }
00556 
00557 /**
00558   * @brief  Lock the FLASH Option Bytes Registers access.
00559   * @retval HAL Status
00560   */
00561 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
00562 {
00563   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
00564   SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
00565 
00566   return HAL_OK;
00567 }
00568 
00569 /**
00570   * @brief  Launch the option byte loading.
00571   * @retval HAL Status
00572   */
00573 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
00574 {
00575   /* Set the bit to force the option byte reloading */
00576   SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
00577 
00578   /* Wait for last operation to be completed */
00579   return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE));
00580 }
00581 
00582 /**
00583   * @}
00584   */
00585 
00586 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
00587  *  @brief   Peripheral Errors functions
00588  *
00589 @verbatim
00590  ===============================================================================
00591                 ##### Peripheral Errors functions #####
00592  ===============================================================================
00593     [..]
00594     This subsection permits to get in run-time Errors of the FLASH peripheral.
00595 
00596 @endverbatim
00597   * @{
00598   */
00599 
00600 /**
00601   * @brief  Get the specific FLASH error flag.
00602   * @retval FLASH_ErrorCode: The returned value can be:
00603   *            @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP)
00604   *            @arg HAL_FLASH_ERROR_PGS: FLASH Programming Sequence error flag
00605   *            @arg HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag
00606   *            @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag
00607   *            @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag
00608   *            @arg HAL_FLASH_ERROR_OPERATION: FLASH operation Error flag
00609   *            @arg HAL_FLASH_ERROR_NONE: No error set
00610   *            @arg HAL_FLASH_ERROR_OP: FLASH Operation error
00611   *            @arg HAL_FLASH_ERROR_PROG: FLASH Programming error
00612   *            @arg HAL_FLASH_ERROR_WRP: FLASH Write protection error
00613   *            @arg HAL_FLASH_ERROR_PGA: FLASH Programming alignment error
00614   *            @arg HAL_FLASH_ERROR_SIZ: FLASH Size error
00615   *            @arg HAL_FLASH_ERROR_PGS: FLASH Programming sequence error
00616   *            @arg HAL_FLASH_ERROR_MIS: FLASH Fast programming data miss error
00617   *            @arg HAL_FLASH_ERROR_FAST: FLASH Fast programming error
00618   *            @arg HAL_FLASH_ERROR_RD: FLASH PCROP read error
00619   *            @arg HAL_FLASH_ERROR_OPTV: FLASH Option validity error
00620   *            @arg FLASH_FLAG_PEMPTY : FLASH Boot from not programmed flash (apply only for STM32L43x/STM32L44x devices)
00621   */
00622 uint32_t HAL_FLASH_GetError(void)
00623 {
00624    return pFlash.ErrorCode;
00625 }
00626 
00627 /**
00628   * @}
00629   */
00630 
00631 /**
00632   * @}
00633   */
00634 
00635 /* Private functions ---------------------------------------------------------*/
00636 
00637 /** @addtogroup FLASH_Private_Functions
00638   * @{
00639   */
00640 
00641 /**
00642   * @brief  Wait for a FLASH operation to complete.
00643   * @param  Timeout maximum flash operation timeout
00644   * @retval HAL_StatusTypeDef HAL Status
00645   */
00646 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
00647 {
00648   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
00649      Even if the FLASH operation fails, the BUSY flag will be reset and an error
00650      flag will be set */
00651 
00652   uint32_t tickstart = HAL_GetTick();
00653   uint32_t error;
00654 
00655   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
00656   {
00657     if(Timeout != HAL_MAX_DELAY)
00658     {
00659       if((HAL_GetTick() - tickstart) >= Timeout)
00660       {
00661         return HAL_TIMEOUT;
00662       }
00663     }
00664   }
00665 
00666   error = (FLASH->SR & FLASH_FLAG_SR_ERRORS);
00667 
00668   if(error != 0u)
00669   {
00670     /*Save the error code*/
00671     pFlash.ErrorCode |= error;
00672 
00673     /* Clear error programming flags */
00674     __HAL_FLASH_CLEAR_FLAG(error);
00675 
00676     return HAL_ERROR;
00677   }
00678 
00679   /* Check FLASH End of Operation flag  */
00680   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
00681   {
00682     /* Clear FLASH End of Operation pending bit */
00683     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
00684   }
00685 
00686   /* If there is an error flag set */
00687   return HAL_OK;
00688 }
00689 
00690 /**
00691   * @brief  Program double-word (64-bit) at a specified address.
00692   * @param  Address specifies the address to be programmed.
00693   * @param  Data specifies the data to be programmed.
00694   * @retval None
00695   */
00696 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
00697 {
00698   /* Check the parameters */
00699   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
00700 
00701   /* Set PG bit */
00702   SET_BIT(FLASH->CR, FLASH_CR_PG);
00703 
00704   /* Program first word */
00705   *(__IO uint32_t*)Address = (uint32_t)Data;
00706 
00707   /* Barrier to ensure programming is performed in 2 steps, in right order
00708     (independently of compiler optimization behavior) */
00709   __ISB();
00710 
00711   /* Program second word */
00712   *(__IO uint32_t*)(Address+4U) = (uint32_t)(Data >> 32);
00713 }
00714 
00715 /**
00716   * @brief  Fast program a row double-word (64-bit) at a specified address.
00717   * @param  Address specifies the address to be programmed.
00718   * @param  DataAddress specifies the address where the data are stored.
00719   * @retval None
00720   */
00721 static void FLASH_Program_Fast(uint32_t Address, uint32_t DataAddress)
00722 {
00723   uint32_t primask_bit;
00724   uint8_t row_index = (2*FLASH_NB_DOUBLE_WORDS_IN_ROW);
00725   __IO uint32_t *dest_addr = (__IO uint32_t*)Address;
00726   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
00727 
00728   /* Check the parameters */
00729   assert_param(IS_FLASH_MAIN_MEM_ADDRESS(Address));
00730 
00731   /* Set FSTPG bit */
00732   SET_BIT(FLASH->CR, FLASH_CR_FSTPG);
00733 
00734   /* Disable interrupts to avoid any interruption during the loop */
00735   primask_bit = __get_PRIMASK();
00736   __disable_irq();
00737 
00738   /* Program the double word of the row */
00739   do
00740   {
00741     *dest_addr = *src_addr;
00742     dest_addr++;
00743     src_addr++;
00744     row_index--;
00745   } while (row_index != 0U);
00746 
00747   /* Re-enable the interrupts */
00748   __set_PRIMASK(primask_bit);
00749 }
00750 
00751 /**
00752   * @}
00753   */
00754 
00755 #endif /* HAL_FLASH_MODULE_ENABLED */
00756 
00757 /**
00758   * @}
00759   */
00760 
00761 /**
00762   * @}
00763   */
00764