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