Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32f1xx_hal_flash.c Source File

stm32f1xx_hal_flash.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_flash.c
00004   * @author  MCD Application Team
00005   * @version V1.0.4
00006   * @date    29-April-2016
00007   * @brief   FLASH HAL module driver.
00008   *          This file provides firmware functions to manage the following 
00009   *          functionalities of the internal FLASH memory:
00010   *           + Program operations functions
00011   *           + Memory Control functions 
00012   *           + Peripheral State functions
00013   *         
00014   @verbatim
00015   ==============================================================================
00016                         ##### FLASH peripheral features #####
00017   ==============================================================================
00018   [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses 
00019        to the Flash memory. It implements the erase and program Flash memory operations 
00020        and the read and write protection mechanisms.
00021 
00022   [..] The Flash memory interface accelerates code execution with a system of instruction
00023       prefetch. 
00024 
00025   [..] The FLASH main features are:
00026       (+) Flash memory read operations
00027       (+) Flash memory program/erase operations
00028       (+) Read / write protections
00029       (+) Prefetch on I-Code
00030       (+) Option Bytes programming
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 STM32F1xx devices.
00038     
00039       (#) FLASH Memory I/O Programming functions: this group includes all needed
00040           functions to erase and program the main memory:
00041         (++) Lock and Unlock the FLASH interface
00042         (++) Erase function: Erase page, erase all pages
00043         (++) Program functions: half word, word and doubleword
00044     
00045       (#) FLASH Option Bytes Programming functions: this group includes all needed
00046           functions to manage the Option Bytes:
00047         (++) Lock and Unlock the Option Bytes
00048         (++) Set/Reset the write protection
00049         (++) Set the Read protection Level
00050         (++) Program the user Option Bytes
00051         (++) Launch the Option Bytes loader
00052         (++) Erase Option Bytes
00053         (++) Program the data Option Bytes
00054         (++) Get the Write protection.
00055         (++) Get the user option bytes.
00056     
00057       (#) Interrupts and flags management functions : this group 
00058           includes all needed functions to:
00059         (++) Handle FLASH interrupts
00060         (++) Wait for last FLASH operation according to its status
00061         (++) Get error flag status           
00062 
00063   [..] In addition to these function, this driver includes a set of macros allowing
00064        to handle the following operations:
00065       
00066       (+) Set/Get the latency
00067       (+) Enable/Disable the prefetch buffer
00068       (+) Enable/Disable the half cycle access
00069       (+) Enable/Disable the FLASH interrupts
00070       (+) Monitor the FLASH flags status
00071           
00072   @endverbatim
00073   ******************************************************************************
00074   * @attention
00075   *
00076   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00077   *
00078   * Redistribution and use in source and binary forms, with or without modification,
00079   * are permitted provided that the following conditions are met:
00080   *   1. Redistributions of source code must retain the above copyright notice,
00081   *      this list of conditions and the following disclaimer.
00082   *   2. Redistributions in binary form must reproduce the above copyright notice,
00083   *      this list of conditions and the following disclaimer in the documentation
00084   *      and/or other materials provided with the distribution.
00085   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00086   *      may be used to endorse or promote products derived from this software
00087   *      without specific prior written permission.
00088   *
00089   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00090   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00091   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00092   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00093   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00094   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00095   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00096   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00097   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00098   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00099   *
00100   ******************************************************************************  
00101   */
00102 
00103 /* Includes ------------------------------------------------------------------*/
00104 #include "stm32f1xx_hal.h"
00105 
00106 /** @addtogroup STM32F1xx_HAL_Driver
00107   * @{
00108   */
00109 
00110 #ifdef HAL_FLASH_MODULE_ENABLED
00111 
00112 /** @defgroup FLASH FLASH
00113   * @brief FLASH HAL module driver
00114   * @{
00115   */
00116 
00117 /* Private typedef -----------------------------------------------------------*/
00118 /* Private define ------------------------------------------------------------*/
00119 /** @defgroup FLASH_Private_Constants FLASH Private Constants
00120   * @{
00121   */
00122 /**
00123   * @}
00124   */
00125 
00126 /* Private macro ---------------------------- ---------------------------------*/
00127 /** @defgroup FLASH_Private_Macros FLASH Private Macros
00128   * @{
00129   */
00130  
00131 /**
00132   * @}
00133   */
00134 
00135 /* Private variables ---------------------------------------------------------*/
00136 /** @defgroup FLASH_Private_Variables FLASH Private Variables
00137   * @{
00138   */
00139 /* Variables used for Erase pages under interruption*/
00140 FLASH_ProcessTypeDef pFlash;
00141 /**
00142   * @}
00143   */
00144 
00145 /* Private function prototypes -----------------------------------------------*/
00146 /** @defgroup FLASH_Private_Functions FLASH Private Functions
00147   * @{
00148   */
00149 static  void   FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
00150 static  void   FLASH_SetErrorCode(void);
00151 /**
00152   * @}
00153   */
00154 
00155 /* Exported functions ---------------------------------------------------------*/
00156 /** @defgroup FLASH_Exported_Functions FLASH Exported Functions
00157   * @{
00158   */
00159   
00160 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions 
00161   *  @brief   Programming operation functions 
00162   *
00163 @verbatim   
00164 @endverbatim
00165   * @{
00166   */
00167 
00168 /**
00169   * @brief  Program halfword, word or double word at a specified address
00170   * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
00171   *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
00172   *
00173   * @note   If an erase and a program operations are requested simultaneously,    
00174   *         the erase operation is performed before the program one.
00175   *  
00176   * @note   FLASH should be previously erased before new programmation (only exception to this 
00177   *         is when 0x0000 is programmed)
00178   *
00179   * @param  TypeProgram:  Indicate the way to program at a specified address.
00180   *                       This parameter can be a value of @ref FLASH_Type_Program
00181   * @param  Address:      Specifies the address to be programmed.
00182   * @param  Data:         Specifies the data to be programmed
00183   * 
00184   * @retval HAL_StatusTypeDef HAL Status
00185   */
00186 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
00187 {
00188   HAL_StatusTypeDef status = HAL_ERROR;
00189   uint8_t index = 0;
00190   uint8_t nbiterations = 0;
00191   
00192   /* Process Locked */
00193   __HAL_LOCK(&pFlash);
00194 
00195   /* Check the parameters */
00196   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00197   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
00198 
00199 #if defined(FLASH_BANK2_END)
00200   if(Address <= FLASH_BANK1_END)
00201   {
00202 #endif /* FLASH_BANK2_END */
00203     /* Wait for last operation to be completed */
00204     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00205 #if defined(FLASH_BANK2_END)
00206   }
00207   else
00208   {
00209     /* Wait for last operation to be completed */
00210     status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
00211   }
00212 #endif /* FLASH_BANK2_END */
00213   
00214   if(status == HAL_OK)
00215   {
00216     if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
00217     {
00218       /* Program halfword (16-bit) at a specified address. */
00219       nbiterations = 1;
00220     }
00221     else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
00222     {
00223       /* Program word (32-bit = 2*16-bit) at a specified address. */
00224       nbiterations = 2;
00225     }
00226     else
00227     {
00228       /* Program double word (64-bit = 4*16-bit) at a specified address. */
00229       nbiterations = 4;
00230     }
00231 
00232     for (index = 0; index < nbiterations; index++)
00233     {
00234       FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index)));
00235 
00236 #if defined(FLASH_BANK2_END)
00237       if(Address <= FLASH_BANK1_END)
00238       {
00239 #endif /* FLASH_BANK2_END */
00240         /* Wait for last operation to be completed */
00241         status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00242     
00243         /* If the program operation is completed, disable the PG Bit */
00244         CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
00245 #if defined(FLASH_BANK2_END)
00246       }
00247       else
00248       {
00249         /* Wait for last operation to be completed */
00250         status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
00251         
00252         /* If the program operation is completed, disable the PG Bit */
00253         CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
00254       }
00255 #endif /* FLASH_BANK2_END */
00256       /* In case of error, stop programation procedure */
00257       if (status != HAL_OK)
00258       {
00259         break;
00260       }
00261     }
00262   }
00263 
00264   /* Process Unlocked */
00265   __HAL_UNLOCK(&pFlash);
00266 
00267   return status;
00268 }
00269 
00270 /**
00271   * @brief  Program halfword, word or double word at a specified address  with interrupt enabled.
00272   * @note   The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
00273   *         The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
00274   *
00275   * @note   If an erase and a program operations are requested simultaneously,    
00276   *         the erase operation is performed before the program one.
00277   *
00278   * @param  TypeProgram: Indicate the way to program at a specified address.
00279   *                      This parameter can be a value of @ref FLASH_Type_Program
00280   * @param  Address:     Specifies the address to be programmed.
00281   * @param  Data:        Specifies the data to be programmed
00282   * 
00283   * @retval HAL_StatusTypeDef HAL Status
00284   */
00285 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
00286 {
00287   HAL_StatusTypeDef status = HAL_OK;
00288   
00289   /* Process Locked */
00290   __HAL_LOCK(&pFlash);
00291 
00292   /* Check the parameters */
00293   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00294   assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
00295 
00296 #if defined(FLASH_BANK2_END)
00297   /* If procedure already ongoing, reject the next one */
00298   if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
00299   {
00300     return HAL_ERROR;
00301   }
00302   
00303   if(Address <= FLASH_BANK1_END)
00304   {
00305     /* Enable End of FLASH Operation and Error source interrupts */
00306     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
00307 
00308   }else
00309   {
00310     /* Enable End of FLASH Operation and Error source interrupts */
00311     __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
00312   }
00313 #else
00314   /* Enable End of FLASH Operation and Error source interrupts */
00315   __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
00316 #endif /* FLASH_BANK2_END */
00317   
00318   pFlash.Address = Address;
00319   pFlash.Data = Data;
00320 
00321   if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
00322   {
00323     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
00324     /*Program halfword (16-bit) at a specified address.*/
00325     pFlash.DataRemaining = 1;
00326   }
00327   else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
00328   {
00329     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
00330     /*Program word (32-bit : 2*16-bit) at a specified address.*/
00331     pFlash.DataRemaining = 2;
00332   }
00333   else
00334   {
00335     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
00336     /*Program double word (64-bit : 4*16-bit) at a specified address.*/
00337     pFlash.DataRemaining = 4;
00338   }
00339 
00340   /*Program halfword (16-bit) at a specified address.*/
00341   FLASH_Program_HalfWord(Address, (uint16_t)Data);
00342 
00343   return status;
00344 }
00345 
00346 /**
00347   * @brief This function handles FLASH interrupt request.
00348   * @retval None
00349   */
00350 void HAL_FLASH_IRQHandler(void)
00351 {
00352   uint32_t addresstmp = 0;
00353   
00354   /* Check FLASH operation error flags */
00355 #if defined(FLASH_BANK2_END)
00356   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
00357     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
00358 #else
00359   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
00360 #endif /* FLASH_BANK2_END */
00361   {
00362     /*return the faulty address*/
00363     addresstmp = pFlash.Address;
00364     /* Reset address */
00365     pFlash.Address = 0xFFFFFFFF;
00366   
00367     /*Save the Error code*/
00368     FLASH_SetErrorCode();
00369     
00370     /* FLASH error interrupt user callback */
00371     HAL_FLASH_OperationErrorCallback(addresstmp);
00372 
00373     /* Stop the procedure ongoing*/
00374     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00375   }
00376 
00377   /* Check FLASH End of Operation flag  */
00378 #if defined(FLASH_BANK2_END)
00379   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
00380   {
00381     /* Clear FLASH End of Operation pending bit */
00382     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
00383 #else
00384   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
00385   {
00386     /* Clear FLASH End of Operation pending bit */
00387     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
00388 #endif /* FLASH_BANK2_END */
00389     
00390     /* Process can continue only if no error detected */
00391     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
00392     {
00393       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
00394       {
00395         /* Nb of pages to erased can be decreased */
00396         pFlash.DataRemaining--;
00397 
00398         /* Check if there are still pages to erase*/
00399         if(pFlash.DataRemaining != 0)
00400         {
00401           addresstmp = pFlash.Address;
00402           /*Indicate user which sector has been erased*/
00403           HAL_FLASH_EndOfOperationCallback(addresstmp);
00404 
00405           /*Increment sector number*/
00406           addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
00407           pFlash.Address = addresstmp;
00408 
00409           /* If the erase operation is completed, disable the PER Bit */
00410           CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
00411 
00412           FLASH_PageErase(addresstmp);
00413         }
00414         else
00415         {
00416           /*No more pages to Erase, user callback can be called.*/
00417           /*Reset Sector and stop Erase pages procedure*/
00418           pFlash.Address = addresstmp = 0xFFFFFFFF;
00419           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00420           /* FLASH EOP interrupt user callback */
00421           HAL_FLASH_EndOfOperationCallback(addresstmp);
00422         }
00423       }
00424       else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
00425       {
00426         /* Operation is completed, disable the MER Bit */
00427         CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
00428 
00429 #if defined(FLASH_BANK2_END)
00430         /* Stop Mass Erase procedure if no pending mass erase on other bank */
00431         if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
00432         {
00433 #endif /* FLASH_BANK2_END */
00434           /* MassErase ended. Return the selected bank*/
00435           /* FLASH EOP interrupt user callback */
00436           HAL_FLASH_EndOfOperationCallback(0);
00437 
00438           /* Stop Mass Erase procedure*/
00439           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00440         }
00441 #if defined(FLASH_BANK2_END)
00442       }
00443 #endif /* FLASH_BANK2_END */
00444       else
00445       {
00446         /* Nb of 16-bit data to program can be decreased */
00447         pFlash.DataRemaining--;
00448         
00449         /* Check if there are still 16-bit data to program */
00450         if(pFlash.DataRemaining != 0)
00451         {
00452           /* Increment address to 16-bit */
00453           pFlash.Address += 2;
00454           addresstmp = pFlash.Address;
00455           
00456           /* Shift to have next 16-bit data */
00457           pFlash.Data = (pFlash.Data >> 16);
00458           
00459           /* Operation is completed, disable the PG Bit */
00460           CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
00461 
00462           /*Program halfword (16-bit) at a specified address.*/
00463           FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
00464         }
00465         else
00466         {
00467           /*Program ended. Return the selected address*/
00468           /* FLASH EOP interrupt user callback */
00469           if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
00470           {
00471             HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00472           }
00473           else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
00474           {
00475             HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2);
00476           }
00477           else 
00478           {
00479             HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6);
00480           }
00481         
00482           /* Reset Address and stop Program procedure*/
00483           pFlash.Address = 0xFFFFFFFF;
00484           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00485         }
00486       }
00487     }
00488   }
00489   
00490 #if defined(FLASH_BANK2_END)
00491   /* Check FLASH End of Operation flag  */
00492   if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
00493   {
00494     /* Clear FLASH End of Operation pending bit */
00495     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
00496     
00497     /* Process can continue only if no error detected */
00498     if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
00499     {
00500       if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
00501       {
00502         /* Nb of pages to erased can be decreased */
00503         pFlash.DataRemaining--;
00504         
00505         /* Check if there are still pages to erase*/
00506         if(pFlash.DataRemaining != 0)
00507         {
00508           /* Indicate user which page address has been erased*/
00509           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00510         
00511           /* Increment page address to next page */
00512           pFlash.Address += FLASH_PAGE_SIZE;
00513           addresstmp = pFlash.Address;
00514 
00515           /* Operation is completed, disable the PER Bit */
00516           CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
00517 
00518           FLASH_PageErase(addresstmp);
00519         }
00520         else
00521         {
00522           /*No more pages to Erase*/
00523           
00524           /*Reset Address and stop Erase pages procedure*/
00525           pFlash.Address = 0xFFFFFFFF;
00526           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00527 
00528           /* FLASH EOP interrupt user callback */
00529           HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00530         }
00531       }
00532       else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
00533       {
00534         /* Operation is completed, disable the MER Bit */
00535         CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
00536 
00537         if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
00538         {
00539           /* MassErase ended. Return the selected bank*/
00540           /* FLASH EOP interrupt user callback */
00541           HAL_FLASH_EndOfOperationCallback(0);
00542         
00543           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00544         }
00545       }
00546       else
00547       {
00548         /* Nb of 16-bit data to program can be decreased */
00549         pFlash.DataRemaining--;
00550         
00551         /* Check if there are still 16-bit data to program */
00552         if(pFlash.DataRemaining != 0)
00553         {
00554           /* Increment address to 16-bit */
00555           pFlash.Address += 2;
00556           addresstmp = pFlash.Address;
00557           
00558           /* Shift to have next 16-bit data */
00559           pFlash.Data = (pFlash.Data >> 16);
00560           
00561           /* Operation is completed, disable the PG Bit */
00562           CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
00563 
00564           /*Program halfword (16-bit) at a specified address.*/
00565           FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
00566         }
00567         else
00568         {
00569           /*Program ended. Return the selected address*/
00570           /* FLASH EOP interrupt user callback */
00571           if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
00572           {
00573             HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00574           }
00575           else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
00576           {
00577             HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
00578           }
00579           else 
00580           {
00581             HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
00582           }
00583           
00584           /* Reset Address and stop Program procedure*/
00585           pFlash.Address = 0xFFFFFFFF;
00586           pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00587         }
00588       }
00589     }
00590   }
00591 #endif 
00592 
00593   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
00594   {
00595 #if defined(FLASH_BANK2_END)
00596     /* Operation is completed, disable the PG, PER and MER Bits for both bank */
00597     CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
00598     CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));  
00599   
00600     /* Disable End of FLASH Operation and Error source interrupts for both banks */
00601     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
00602 #else
00603     /* Operation is completed, disable the PG, PER and MER Bits */
00604     CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
00605 
00606     /* Disable End of FLASH Operation and Error source interrupts */
00607     __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
00608 #endif /* FLASH_BANK2_END */
00609 
00610     /* Process Unlocked */
00611     __HAL_UNLOCK(&pFlash);
00612   }
00613 }
00614 
00615 
00616 /**
00617   * @brief  FLASH end of operation interrupt callback
00618   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
00619   *                 - Mass Erase: No return value expected
00620   *                 - Pages Erase: Address of the page which has been erased 
00621   *                    (if 0xFFFFFFFF, it means that all the selected pages have been erased)
00622   *                 - Program: Address which was selected for data program
00623   * @retval none
00624   */
00625 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
00626 {
00627   /* Prevent unused argument(s) compilation warning */
00628   UNUSED(ReturnValue);
00629   /* NOTE : This function Should not be modified, when the callback is needed,
00630             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
00631    */ 
00632 }
00633 
00634 /**
00635   * @brief  FLASH operation error interrupt callback
00636   * @param  ReturnValue: The value saved in this parameter depends on the ongoing procedure
00637   *                 - Mass Erase: No return value expected
00638   *                 - Pages Erase: Address of the page which returned an error
00639   *                 - Program: Address which was selected for data program
00640   * @retval none
00641   */
00642 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
00643 {
00644   /* Prevent unused argument(s) compilation warning */
00645   UNUSED(ReturnValue);
00646   /* NOTE : This function Should not be modified, when the callback is needed,
00647             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
00648    */ 
00649 }
00650 
00651 /**
00652   * @}
00653   */
00654 
00655 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions 
00656  *  @brief   management functions 
00657  *
00658 @verbatim   
00659  ===============================================================================
00660                       ##### Peripheral Control functions #####
00661  ===============================================================================  
00662     [..]
00663     This subsection provides a set of functions allowing to control the FLASH 
00664     memory operations.
00665 
00666 @endverbatim
00667   * @{
00668   */
00669 
00670 /**
00671   * @brief  Unlock the FLASH control register access
00672   * @retval HAL Status
00673   */
00674 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
00675 {
00676   if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK))
00677   {
00678     /* Authorize the FLASH Registers access */
00679     WRITE_REG(FLASH->KEYR, FLASH_KEY1);
00680     WRITE_REG(FLASH->KEYR, FLASH_KEY2);
00681   }
00682   else
00683   {
00684     return HAL_ERROR;
00685   }
00686 
00687 #if defined(FLASH_BANK2_END)
00688   if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK))
00689   {
00690     /* Authorize the FLASH BANK2 Registers access */
00691     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
00692     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
00693   }
00694   else
00695   {
00696     return HAL_ERROR;
00697   }
00698   
00699 #endif /* FLASH_BANK2_END */
00700   return HAL_OK; 
00701 }
00702 
00703 /**
00704   * @brief  Locks the FLASH control register access
00705   * @retval HAL Status
00706   */
00707 HAL_StatusTypeDef HAL_FLASH_Lock(void)
00708 {
00709   /* Set the LOCK Bit to lock the FLASH Registers access */
00710   SET_BIT(FLASH->CR, FLASH_CR_LOCK);
00711   
00712 #if defined(FLASH_BANK2_END)
00713   /* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
00714   SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
00715 #endif /* FLASH_BANK2_END */
00716 
00717   return HAL_OK;  
00718 }
00719 
00720 
00721 /**
00722   * @brief  Unlock the FLASH Option Control Registers access.
00723   * @retval HAL Status
00724   */
00725 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
00726 {
00727   if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
00728   {
00729     /* Authorizes the Option Byte register programming */
00730     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
00731     WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
00732   }
00733   else
00734   {
00735     return HAL_ERROR;
00736   }  
00737   
00738   return HAL_OK;  
00739 }
00740 
00741 /**
00742   * @brief  Lock the FLASH Option Control Registers access.
00743   * @retval HAL Status 
00744   */
00745 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
00746 {
00747   /* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
00748   CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
00749   
00750   return HAL_OK;  
00751 }
00752   
00753 /**
00754   * @brief  Launch the option byte loading.
00755   * @note   This function will reset automatically the MCU.
00756   * @retval HAL_StatusTypeDef HAL Status
00757   */
00758 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
00759 {
00760   /* Initiates a system reset request to launch the option byte loading */
00761   HAL_NVIC_SystemReset();
00762   
00763   return HAL_OK;  
00764 }
00765 
00766 /**
00767   * @}
00768   */  
00769 
00770 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State functions 
00771  *  @brief   Peripheral State functions 
00772  *
00773 @verbatim   
00774  ===============================================================================
00775                       ##### Peripheral State functions #####
00776  ===============================================================================  
00777     [..]
00778     This subsection permit to get in run-time the status of the FLASH peripheral.
00779 
00780 @endverbatim
00781   * @{
00782   */
00783 
00784 /**
00785   * @brief  Get the specific FLASH error flag.
00786   * @retval FLASH_ErrorCode: The returned value can be:
00787   *            @ref FLASH_Error_Codes
00788   */
00789 uint32_t HAL_FLASH_GetError(void)
00790 { 
00791    return pFlash.ErrorCode;
00792 }  
00793 /**
00794   * @}
00795   */
00796 
00797 /**
00798   * @}
00799   */
00800 
00801 /** @addtogroup FLASH_Private_Functions
00802  * @{
00803  */
00804 
00805 /**
00806   * @brief  Program a half-word (16-bit) at a specified address.
00807   * @param  Address: specifies the address to be programmed.
00808   * @param  Data: specifies the data to be programmed.
00809   * @retval None
00810   */
00811 static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
00812 {
00813   /* Clean the error context */
00814   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00815   
00816 #if defined(FLASH_BANK2_END)
00817   if(Address <= FLASH_BANK1_END)
00818   {
00819 #endif /* FLASH_BANK2_END */
00820     /* Proceed to program the new data */
00821     SET_BIT(FLASH->CR, FLASH_CR_PG);
00822 #if defined(FLASH_BANK2_END)
00823   }
00824   else
00825   {
00826     /* Proceed to program the new data */
00827     SET_BIT(FLASH->CR2, FLASH_CR2_PG);
00828   }
00829 #endif /* FLASH_BANK2_END */
00830 
00831   /* Write data in the address */
00832   *(__IO uint16_t*)Address = Data;
00833 }
00834 
00835 /**
00836   * @brief  Wait for a FLASH operation to complete.
00837   * @param  Timeout: maximum flash operation timeout
00838   * @retval HAL_StatusTypeDef HAL Status
00839   */
00840 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
00841 {
00842   /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
00843      Even if the FLASH operation fails, the BUSY flag will be reset and an error
00844      flag will be set */
00845      
00846   uint32_t tickstart = HAL_GetTick();
00847      
00848   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) 
00849   { 
00850     if (Timeout != HAL_MAX_DELAY)
00851     {
00852       if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
00853       {
00854         return HAL_TIMEOUT;
00855       }
00856     }
00857   }
00858   
00859   /* Check FLASH End of Operation flag  */
00860   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
00861   {
00862     /* Clear FLASH End of Operation pending bit */
00863     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
00864   }
00865   
00866   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)  || 
00867      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || 
00868      __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
00869   {
00870     /*Save the error code*/
00871     FLASH_SetErrorCode();
00872     return HAL_ERROR;
00873   }
00874 
00875   /* If there is no error flag set */
00876   return HAL_OK;
00877 }
00878 
00879 #if defined(FLASH_BANK2_END)
00880 /**
00881   * @brief  Wait for a FLASH BANK2 operation to complete.
00882   * @param  Timeout: maximum flash operation timeout
00883   * @retval HAL_StatusTypeDef HAL Status
00884   */
00885 HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
00886 { 
00887   /* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
00888      Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
00889      flag will be set */
00890      
00891   uint32_t tickstart = HAL_GetTick();
00892      
00893   while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2)) 
00894   { 
00895     if (Timeout != HAL_MAX_DELAY)
00896     {
00897       if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
00898       {
00899         return HAL_TIMEOUT;
00900       }
00901     }
00902   }
00903   
00904   /* Check FLASH End of Operation flag  */
00905   if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
00906   {
00907     /* Clear FLASH End of Operation pending bit */
00908     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
00909   }
00910 
00911   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
00912   {
00913     /*Save the error code*/
00914     FLASH_SetErrorCode();
00915     return HAL_ERROR;
00916   }
00917 
00918   /* If there is an error flag set */
00919   return HAL_OK;
00920   
00921 }
00922 #endif /* FLASH_BANK2_END */
00923 
00924 /**
00925   * @brief  Set the specific FLASH error flag.
00926   * @retval None
00927   */
00928 static void FLASH_SetErrorCode(void)
00929 { 
00930 #if defined(FLASH_BANK2_END)
00931   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
00932 #else
00933   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
00934 #endif /* FLASH_BANK2_END */
00935   {
00936     pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
00937   }
00938 #if defined(FLASH_BANK2_END)
00939   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
00940 #else
00941   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
00942 #endif /* FLASH_BANK2_END */
00943   {
00944      pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
00945   }
00946 
00947   if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
00948   {
00949      pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
00950      __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
00951   }
00952 
00953   /* Clear FLASH error pending bits */
00954 #if defined(FLASH_BANK2_END)
00955   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2);
00956 #else
00957   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
00958 #endif /* FLASH_BANK2_END */
00959 }  
00960 /**
00961   * @}
00962   */
00963 
00964 /**
00965   * @}
00966   */
00967 
00968 #endif /* HAL_FLASH_MODULE_ENABLED */
00969 
00970 /**
00971   * @}
00972   */
00973 
00974 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/