STM32F439xx HAL User Manual
stm32f4xx_hal_flash.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_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       (+) Prefetch on I-Code
00029       (+) 64 cache lines of 128 bits on I-Code
00030       (+) 8 cache lines of 128 bits on D-Code
00031       
00032       
00033                      ##### How to use this driver #####
00034   ==============================================================================
00035     [..]                             
00036       This driver provides functions and macros to configure and program the FLASH 
00037       memory of all STM32F4xx devices.
00038     
00039       (#) FLASH Memory IO Programming functions: 
00040            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and 
00041                 HAL_FLASH_Lock() functions
00042            (++) Program functions: byte, half word, word and double word
00043            (++) There Two modes of programming :
00044             (+++) Polling mode using HAL_FLASH_Program() function
00045             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
00046     
00047       (#) Interrupts and flags management functions : 
00048            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
00049            (++) Wait for last FLASH operation according to its status
00050            (++) Get error flag status by calling HAL_SetErrorCode()          
00051 
00052     [..] 
00053       In addition to these functions, this driver includes a set of macros allowing
00054       to handle the following operations:
00055        (+) Set the latency
00056        (+) Enable/Disable the prefetch buffer
00057        (+) Enable/Disable the Instruction cache and the Data cache
00058        (+) Reset the Instruction cache and the Data cache
00059        (+) Enable/Disable the FLASH interrupts
00060        (+) Monitor the FLASH flags status
00061           
00062   @endverbatim
00063   ******************************************************************************
00064   * @attention
00065   *
00066   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00067   *
00068   * Redistribution and use in source and binary forms, with or without modification,
00069   * are permitted provided that the following conditions are met:
00070   *   1. Redistributions of source code must retain the above copyright notice,
00071   *      this list of conditions and the following disclaimer.
00072   *   2. Redistributions in binary form must reproduce the above copyright notice,
00073   *      this list of conditions and the following disclaimer in the documentation
00074   *      and/or other materials provided with the distribution.
00075   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00076   *      may be used to endorse or promote products derived from this software
00077   *      without specific prior written permission.
00078   *
00079   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00080   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00081   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00082   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00083   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00084   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00085   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00086   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00087   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00088   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00089   *
00090   ******************************************************************************
00091   */ 
00092 
00093 /* Includes ------------------------------------------------------------------*/
00094 #include "stm32f4xx_hal.h"
00095 
00096 /** @addtogroup STM32F4xx_HAL_Driver
00097   * @{
00098   */
00099 
00100 /** @defgroup FLASH FLASH
00101   * @brief FLASH HAL module driver
00102   * @{
00103   */
00104 
00105 #ifdef HAL_FLASH_MODULE_ENABLED
00106 
00107 /* Private typedef -----------------------------------------------------------*/
00108 /* Private define ------------------------------------------------------------*/
00109 /** @addtogroup FLASH_Private_Constants
00110   * @{
00111   */
00112 #define FLASH_TIMEOUT_VALUE       50000U /* 50 s */
00113 /**
00114   * @}
00115   */         
00116 /* Private macro -------------------------------------------------------------*/
00117 /* Private variables ---------------------------------------------------------*/
00118 /** @addtogroup FLASH_Private_Variables
00119   * @{
00120   */
00121 /* Variable used for Erase sectors under interruption */
00122 FLASH_ProcessTypeDef pFlash;
00123 /**
00124   * @}
00125   */
00126 
00127 /* Private function prototypes -----------------------------------------------*/
00128 /** @addtogroup FLASH_Private_Functions
00129   * @{
00130   */
00131 /* Program operations */
00132 static void   FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data);
00133 static void   FLASH_Program_Word(uint32_t Address, uint32_t Data);
00134 static void   FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
00135 static void   FLASH_Program_Byte(uint32_t Address, uint8_t Data);
00136 static void   FLASH_SetErrorCode(void);
00137 
00138 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout);
00139 /**
00140   * @}
00141   */
00142 
00143 /* Exported functions --------------------------------------------------------*/
00144 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
00145   * @{
00146   */
00147   
00148 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions 
00149  *  @brief   Programming operation functions 
00150  *
00151 @verbatim   
00152  ===============================================================================
00153                   ##### Programming operation functions #####
00154  ===============================================================================  
00155     [..]
00156     This subsection provides a set of functions allowing to manage the FLASH 
00157     program operations.
00158 
00159 @endverbatim
00160   * @{
00161   */
00162 
00163 /**
00164   * @brief  Program byte, halfword, word or double word at a specified address
00165   * @param  TypeProgram  Indicate the way to program at a specified address.
00166   *                           This parameter can be a value of @ref FLASH_Type_Program
00167   * @param  Address  specifies the address to be programmed.
00168   * @param  Data specifies the data to be programmed
00169   * 
00170   * @retval HAL_StatusTypeDef HAL Status
00171   */
00172 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
00173 {
00174   HAL_StatusTypeDef status = HAL_ERROR;
00175   
00176   /* Process Locked */
00177   __HAL_LOCK(&pFlash);
00178   
00179   /* Check the parameters */
00180   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00181   
00182   /* Wait for last operation to be completed */
00183   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00184   
00185   if(status == HAL_OK)
00186   {
00187     if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
00188     {
00189       /*Program byte (8-bit) at a specified address.*/
00190       FLASH_Program_Byte(Address, (uint8_t) Data);
00191     }
00192     else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
00193     {
00194       /*Program halfword (16-bit) at a specified address.*/
00195       FLASH_Program_HalfWord(Address, (uint16_t) Data);
00196     }
00197     else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
00198     {
00199       /*Program word (32-bit) at a specified address.*/
00200       FLASH_Program_Word(Address, (uint32_t) Data);
00201     }
00202     else
00203     {
00204       /*Program double word (64-bit) at a specified address.*/
00205       FLASH_Program_DoubleWord(Address, Data);
00206     }
00207     
00208     /* Wait for last operation to be completed */
00209     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00210     
00211     /* If the program operation is completed, disable the PG Bit */
00212     FLASH->CR &= (~FLASH_CR_PG);  
00213   }
00214   
00215   /* Process Unlocked */
00216   __HAL_UNLOCK(&pFlash);
00217   
00218   return status;
00219 }
00220 
00221 /**
00222   * @brief   Program byte, halfword, word or double word at a specified address  with interrupt enabled.
00223   * @param  TypeProgram  Indicate the way to program at a specified address.
00224   *                           This parameter can be a value of @ref FLASH_Type_Program
00225   * @param  Address  specifies the address to be programmed.
00226   * @param  Data specifies the data to be programmed
00227   * 
00228   * @retval HAL Status
00229   */
00230 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
00231 {
00232   HAL_StatusTypeDef status = HAL_OK;
00233   
00234   /* Process Locked */
00235   __HAL_LOCK(&pFlash);
00236 
00237   /* Check the parameters */
00238   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00239 
00240   /* Enable End of FLASH Operation interrupt */
00241   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
00242   
00243   /* Enable Error source interrupt */
00244   __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
00245 
00246   pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
00247   pFlash.Address = Address;
00248 
00249   if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
00250   {
00251     /*Program byte (8-bit) at a specified address.*/
00252       FLASH_Program_Byte(Address, (uint8_t) Data);
00253   }
00254   else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
00255   {
00256     /*Program halfword (16-bit) at a specified address.*/
00257     FLASH_Program_HalfWord(Address, (uint16_t) Data);
00258   }
00259   else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
00260   {
00261     /*Program word (32-bit) at a specified address.*/
00262     FLASH_Program_Word(Address, (uint32_t) Data);
00263   }
00264   else
00265   {
00266     /*Program double word (64-bit) at a specified address.*/
00267     FLASH_Program_DoubleWord(Address, Data);
00268   }
00269 
00270   return status;
00271 }
00272 
00273 /**
00274   * @brief This function handles FLASH interrupt request.
00275   * @retval None
00276   */
00277 void HAL_FLASH_IRQHandler(void)
00278 {
00279   uint32_t addresstmp = 0U;
00280   
00281   /* Check FLASH operation error flags */
00282 #if defined(FLASH_SR_RDERR) 
00283   if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
00284     FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
00285 #else
00286   if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
00287     FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR)) != RESET)
00288 #endif /* FLASH_SR_RDERR */
00289   {
00290     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
00291     {
00292       /*return the faulty sector*/
00293       addresstmp = pFlash.Sector;
00294       pFlash.Sector = 0xFFFFFFFFU;
00295     }
00296     else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
00297     {
00298       /*return the faulty bank*/
00299       addresstmp = pFlash.Bank;
00300     }
00301     else
00302     {
00303       /*return the faulty address*/
00304       addresstmp = pFlash.Address;
00305     }
00306     
00307     /*Save the Error code*/
00308     FLASH_SetErrorCode();
00309     
00310     /* FLASH error interrupt user callback */
00311     HAL_FLASH_OperationErrorCallback(addresstmp);
00312     
00313     /*Stop the procedure ongoing*/
00314     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00315   }
00316   
00317   /* Check FLASH End of Operation flag  */
00318   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
00319   {
00320     /* Clear FLASH End of Operation pending bit */
00321     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
00322     
00323     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
00324     {
00325       /*Nb of sector to erased can be decreased*/
00326       pFlash.NbSectorsToErase--;
00327       
00328       /* Check if there are still sectors to erase*/
00329       if(pFlash.NbSectorsToErase != 0U)
00330       {
00331         addresstmp = pFlash.Sector;
00332         /*Indicate user which sector has been erased*/
00333         HAL_FLASH_EndOfOperationCallback(addresstmp);
00334         
00335         /*Increment sector number*/
00336         pFlash.Sector++;
00337         addresstmp = pFlash.Sector;
00338         FLASH_Erase_Sector(addresstmp, pFlash.VoltageForErase);
00339       }
00340       else
00341       {
00342         /*No more sectors to Erase, user callback can be called.*/
00343         /*Reset Sector and stop Erase sectors procedure*/
00344         pFlash.Sector = addresstmp = 0xFFFFFFFFU;
00345         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00346         
00347         /* Flush the caches to be sure of the data consistency */
00348         FLASH_FlushCaches() ;
00349                 
00350         /* FLASH EOP interrupt user callback */
00351         HAL_FLASH_EndOfOperationCallback(addresstmp);
00352       }
00353     }
00354     else 
00355     {
00356       if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) 
00357       {
00358         /* MassErase ended. Return the selected bank */
00359         /* Flush the caches to be sure of the data consistency */
00360         FLASH_FlushCaches() ;
00361 
00362         /* FLASH EOP interrupt user callback */
00363         HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
00364       }
00365       else
00366       {
00367         /*Program ended. Return the selected address*/
00368         /* FLASH EOP interrupt user callback */
00369         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00370       }
00371       pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00372     }
00373   }
00374   
00375   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
00376   {
00377     /* Operation is completed, disable the PG, SER, SNB and MER Bits */
00378     CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_SER | FLASH_CR_SNB | FLASH_MER_BIT));
00379 
00380     /* Disable End of FLASH Operation interrupt */
00381     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);
00382     
00383     /* Disable Error source interrupt */
00384     __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);
00385     
00386     /* Process Unlocked */
00387     __HAL_UNLOCK(&pFlash);
00388   }
00389 }
00390 
00391 /**
00392   * @brief  FLASH end of operation interrupt callback
00393   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
00394   *                  Mass Erase: Bank number which has been requested to erase
00395   *                  Sectors Erase: Sector which has been erased 
00396   *                    (if 0xFFFFFFFFU, it means that all the selected sectors have been erased)
00397   *                  Program: Address which was selected for data program
00398   * @retval None
00399   */
00400 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
00401 {
00402   /* Prevent unused argument(s) compilation warning */
00403   UNUSED(ReturnValue);
00404   /* NOTE : This function Should not be modified, when the callback is needed,
00405             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
00406    */ 
00407 }
00408 
00409 /**
00410   * @brief  FLASH operation error interrupt callback
00411   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
00412   *                 Mass Erase: Bank number which has been requested to erase
00413   *                 Sectors Erase: Sector number which returned an error
00414   *                 Program: Address which was selected for data program
00415   * @retval None
00416   */
00417 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
00418 {
00419   /* Prevent unused argument(s) compilation warning */
00420   UNUSED(ReturnValue);
00421   /* NOTE : This function Should not be modified, when the callback is needed,
00422             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
00423    */ 
00424 }
00425 
00426 /**
00427   * @}
00428   */
00429 
00430 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions 
00431  *  @brief   management functions 
00432  *
00433 @verbatim   
00434  ===============================================================================
00435                       ##### Peripheral Control functions #####
00436  ===============================================================================  
00437     [..]
00438     This subsection provides a set of functions allowing to control the FLASH 
00439     memory operations.
00440 
00441 @endverbatim
00442   * @{
00443   */
00444 
00445 /**
00446   * @brief  Unlock the FLASH control register access
00447   * @retval HAL Status
00448   */
00449 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
00450 {
00451   HAL_StatusTypeDef status = HAL_OK;
00452 
00453   if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
00454   {
00455     /* Authorize the FLASH Registers access */
00456     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
00457     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
00458 
00459     /* Verify Flash is unlocked */
00460     if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
00461     {
00462       status = HAL_ERROR;
00463     }
00464   }
00465 
00466   return status;
00467 }
00468 
00469 /**
00470   * @brief  Locks the FLASH control register access
00471   * @retval HAL Status
00472   */
00473 HAL_StatusTypeDef HAL_FLASH_Lock(void)
00474 {
00475   /* Set the LOCK Bit to lock the FLASH Registers access */
00476   FLASH->CR |= FLASH_CR_LOCK;
00477   
00478   return HAL_OK;  
00479 }
00480 
00481 /**
00482   * @brief  Unlock the FLASH Option Control Registers access.
00483   * @retval HAL Status
00484   */
00485 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
00486 {
00487   if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET)
00488   {
00489     /* Authorizes the Option Byte register programming */
00490     FLASH->OPTKEYR = FLASH_OPT_KEY1;
00491     FLASH->OPTKEYR = FLASH_OPT_KEY2;
00492   }
00493   else
00494   {
00495     return HAL_ERROR;
00496   }  
00497   
00498   return HAL_OK;  
00499 }
00500 
00501 /**
00502   * @brief  Lock the FLASH Option Control Registers access.
00503   * @retval HAL Status 
00504   */
00505 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
00506 {
00507   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
00508   FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;
00509   
00510   return HAL_OK;  
00511 }
00512 
00513 /**
00514   * @brief  Launch the option byte loading.
00515   * @retval HAL Status
00516   */
00517 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
00518 {
00519   /* Set the OPTSTRT bit in OPTCR register */
00520   *(__IO uint8_t *)OPTCR_BYTE0_ADDRESS |= FLASH_OPTCR_OPTSTRT;
00521 
00522   /* Wait for last operation to be completed */
00523   return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE)); 
00524 }
00525 
00526 /**
00527   * @}
00528   */
00529 
00530 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions 
00531  *  @brief   Peripheral Errors functions 
00532  *
00533 @verbatim   
00534  ===============================================================================
00535                 ##### Peripheral Errors functions #####
00536  ===============================================================================  
00537     [..]
00538     This subsection permits to get in run-time Errors of the FLASH peripheral.
00539 
00540 @endverbatim
00541   * @{
00542   */
00543 
00544 /**
00545   * @brief  Get the specific FLASH error flag.
00546   * @retval FLASH_ErrorCode: The returned value can be a combination of:
00547   *            @arg HAL_FLASH_ERROR_RD: FLASH Read Protection error flag (PCROP)
00548   *            @arg HAL_FLASH_ERROR_PGS: FLASH Programming Sequence error flag 
00549   *            @arg HAL_FLASH_ERROR_PGP: FLASH Programming Parallelism error flag  
00550   *            @arg HAL_FLASH_ERROR_PGA: FLASH Programming Alignment error flag
00551   *            @arg HAL_FLASH_ERROR_WRP: FLASH Write protected error flag
00552   *            @arg HAL_FLASH_ERROR_OPERATION: FLASH operation Error flag 
00553   */
00554 uint32_t HAL_FLASH_GetError(void)
00555 { 
00556    return pFlash.ErrorCode;
00557 }  
00558   
00559 /**
00560   * @}
00561   */    
00562 
00563 /**
00564   * @brief  Wait for a FLASH operation to complete.
00565   * @param  Timeout maximum flash operationtimeout
00566   * @retval HAL Status
00567   */
00568 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
00569 { 
00570   uint32_t tickstart = 0U;
00571   
00572   /* Clear Error Code */
00573   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00574   
00575   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
00576      Even if the FLASH operation fails, the BUSY flag will be reset and an error
00577      flag will be set */
00578   /* Get tick */
00579   tickstart = HAL_GetTick();
00580 
00581   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) 
00582   { 
00583     if(Timeout != HAL_MAX_DELAY)
00584     {
00585       if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
00586       {
00587         return HAL_TIMEOUT;
00588       }
00589     } 
00590   }
00591 
00592   /* Check FLASH End of Operation flag  */
00593   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
00594   {
00595     /* Clear FLASH End of Operation pending bit */
00596     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
00597   }
00598 #if defined(FLASH_SR_RDERR)  
00599   if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
00600                            FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
00601 #else
00602   if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
00603                            FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR)) != RESET)
00604 #endif /* FLASH_SR_RDERR */
00605   {
00606     /*Save the error code*/
00607     FLASH_SetErrorCode();
00608     return HAL_ERROR;
00609   }
00610 
00611   /* If there is no error flag set */
00612   return HAL_OK;
00613   
00614 }  
00615 
00616 /**
00617   * @brief  Program a double word (64-bit) at a specified address.
00618   * @note   This function must be used when the device voltage range is from
00619   *         2.7V to 3.6V and Vpp in the range 7V to 9V.
00620   *
00621   * @note   If an erase and a program operations are requested simultaneously,    
00622   *         the erase operation is performed before the program one.
00623   *  
00624   * @param  Address specifies the address to be programmed.
00625   * @param  Data specifies the data to be programmed.
00626   * @retval None
00627   */
00628 static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data)
00629 {
00630   /* Check the parameters */
00631   assert_param(IS_FLASH_ADDRESS(Address));
00632   
00633   /* If the previous operation is completed, proceed to program the new data */
00634   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00635   FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD;
00636   FLASH->CR |= FLASH_CR_PG;
00637 
00638   /* Program the double-word */
00639   *(__IO uint32_t*)Address = (uint32_t)Data;
00640   *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32);
00641 }
00642 
00643 
00644 /**
00645   * @brief  Program word (32-bit) at a specified address.
00646   * @note   This function must be used when the device voltage range is from
00647   *         2.7V to 3.6V.
00648   *
00649   * @note   If an erase and a program operations are requested simultaneously,    
00650   *         the erase operation is performed before the program one.
00651   *  
00652   * @param  Address specifies the address to be programmed.
00653   * @param  Data specifies the data to be programmed.
00654   * @retval None
00655   */
00656 static void FLASH_Program_Word(uint32_t Address, uint32_t Data)
00657 {
00658   /* Check the parameters */
00659   assert_param(IS_FLASH_ADDRESS(Address));
00660   
00661   /* If the previous operation is completed, proceed to program the new data */
00662   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00663   FLASH->CR |= FLASH_PSIZE_WORD;
00664   FLASH->CR |= FLASH_CR_PG;
00665 
00666   *(__IO uint32_t*)Address = Data;
00667 }
00668 
00669 /**
00670   * @brief  Program a half-word (16-bit) at a specified address.
00671   * @note   This function must be used when the device voltage range is from
00672   *         2.1V to 3.6V.
00673   *
00674   * @note   If an erase and a program operations are requested simultaneously,    
00675   *         the erase operation is performed before the program one.
00676   *  
00677   * @param  Address specifies the address to be programmed.
00678   * @param  Data specifies the data to be programmed.
00679   * @retval None
00680   */
00681 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
00682 {
00683   /* Check the parameters */
00684   assert_param(IS_FLASH_ADDRESS(Address));
00685   
00686   /* If the previous operation is completed, proceed to program the new data */
00687   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00688   FLASH->CR |= FLASH_PSIZE_HALF_WORD;
00689   FLASH->CR |= FLASH_CR_PG;
00690 
00691   *(__IO uint16_t*)Address = Data;
00692 }
00693 
00694 /**
00695   * @brief  Program byte (8-bit) at a specified address.
00696   * @note   This function must be used when the device voltage range is from
00697   *         1.8V to 3.6V.
00698   *
00699   * @note   If an erase and a program operations are requested simultaneously,    
00700   *         the erase operation is performed before the program one.
00701   *  
00702   * @param  Address specifies the address to be programmed.
00703   * @param  Data specifies the data to be programmed.
00704   * @retval None
00705   */
00706 static void FLASH_Program_Byte(uint32_t Address, uint8_t Data)
00707 {
00708   /* Check the parameters */
00709   assert_param(IS_FLASH_ADDRESS(Address));
00710   
00711   /* If the previous operation is completed, proceed to program the new data */
00712   CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
00713   FLASH->CR |= FLASH_PSIZE_BYTE;
00714   FLASH->CR |= FLASH_CR_PG;
00715 
00716   *(__IO uint8_t*)Address = Data;
00717 }
00718 
00719 /**
00720   * @brief  Set the specific FLASH error flag.
00721   * @retval None
00722   */
00723 static void FLASH_SetErrorCode(void)
00724 { 
00725   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)
00726   {
00727    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
00728    
00729    /* Clear FLASH write protection error pending bit */
00730    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);
00731   }
00732   
00733   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET)
00734   {
00735    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
00736    
00737    /* Clear FLASH Programming alignment error pending bit */
00738    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
00739   }
00740   
00741   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET)
00742   {
00743     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP;
00744     
00745     /* Clear FLASH Programming parallelism error pending bit */
00746     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR);
00747   }
00748   
00749   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR) != RESET)
00750   {
00751     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS;
00752     
00753     /* Clear FLASH Programming sequence error pending bit */
00754     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
00755   }
00756 #if defined(FLASH_SR_RDERR) 
00757   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET)
00758   {
00759     pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
00760     
00761     /* Clear FLASH Proprietary readout protection error pending bit */
00762     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_RDERR);
00763   }
00764 #endif /* FLASH_SR_RDERR */  
00765   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET)
00766   {
00767     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION;
00768     
00769     /* Clear FLASH Operation error pending bit */
00770     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR);
00771   }
00772 }
00773 
00774 /**
00775   * @}
00776   */
00777 
00778 #endif /* HAL_FLASH_MODULE_ENABLED */
00779 
00780 /**
00781   * @}
00782   */
00783 
00784 /**
00785   * @}
00786   */
00787 
00788 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/