STM32H735xx HAL User Manual
stm32h7xx_hal_flash.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_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 AXI 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 main features are:
00022       (+) Flash memory read operations
00023       (+) Flash memory program/erase operations
00024       (+) Read / write protections
00025       (+) Option bytes programming
00026       (+) Error code correction (ECC) : Data in flash are 266-bits word
00027           (10 bits added per flash word)
00028 
00029                         ##### How to use this driver #####
00030  ==============================================================================
00031     [..]
00032       This driver provides functions and macros to configure and program the FLASH
00033       memory of all STM32H7xx devices.
00034 
00035       (#) FLASH Memory IO Programming functions:
00036            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
00037                 HAL_FLASH_Lock() functions
00038            (++) Program functions: 256-bit word only
00039            (++) There Two modes of programming :
00040             (+++) Polling mode using HAL_FLASH_Program() function
00041             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
00042 
00043       (#) Interrupts and flags management functions :
00044            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
00045            (++) Callback functions are called when the flash operations are finished :
00046                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
00047                 HAL_FLASH_OperationErrorCallback()
00048            (++) Get error flag status by calling HAL_FLASH_GetError()
00049 
00050       (#) Option bytes management functions :
00051            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
00052                 HAL_FLASH_OB_Lock() functions
00053            (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
00054                 In this case, a reset is generated
00055     [..]
00056       In addition to these functions, this driver includes a set of macros allowing
00057       to handle the following operations:
00058        (+) Set the latency
00059        (+) Enable/Disable the FLASH interrupts
00060        (+) Monitor the FLASH flags status
00061      [..]
00062     (@) For any Flash memory program operation (erase or program), the CPU clock frequency
00063         (HCLK) must be at least 1MHz.
00064     (@) The contents of the Flash memory are not guaranteed if a device reset occurs during
00065         a Flash memory operation.
00066     (@) The application can simultaneously request a read and a write operation through each AXI
00067         interface.
00068         As the Flash memory is divided into two independent banks, the embedded Flash
00069         memory interface can drive different operations at the same time on each bank. For
00070         example a read, write or erase operation can be executed on bank 1 while another read,
00071         write or erase operation is executed on bank 2.
00072 
00073  @endverbatim
00074   ******************************************************************************
00075   * @attention
00076   *
00077   * Copyright (c) 2017 STMicroelectronics.
00078   * All rights reserved.
00079   *
00080   * This software is licensed under terms that can be found in the LICENSE file in
00081   * the root directory of this software component.
00082   * If no LICENSE file comes with this software, it is provided AS-IS.
00083   ******************************************************************************
00084   */
00085 
00086 /* Includes ------------------------------------------------------------------*/
00087 #include "stm32h7xx_hal.h"
00088 
00089 /** @addtogroup STM32H7xx_HAL_Driver
00090   * @{
00091   */
00092 
00093 /** @defgroup FLASH FLASH
00094   * @brief FLASH HAL module driver
00095   * @{
00096   */
00097 
00098 #ifdef HAL_FLASH_MODULE_ENABLED
00099 
00100 /* Private typedef -----------------------------------------------------------*/
00101 /* Private define ------------------------------------------------------------*/
00102 /** @addtogroup FLASH_Private_Constants
00103   * @{
00104   */
00105 #define FLASH_TIMEOUT_VALUE              50000U /* 50 s */
00106 /**
00107   * @}
00108   */
00109 /* Private macro -------------------------------------------------------------*/
00110 /* Private variables ---------------------------------------------------------*/
00111 FLASH_ProcessTypeDef pFlash;
00112 /* Private function prototypes -----------------------------------------------*/
00113 /* Exported functions ---------------------------------------------------------*/
00114 
00115 /** @defgroup FLASH_Exported_Functions FLASH Exported functions
00116   * @{
00117   */
00118 
00119 /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
00120  *  @brief   Programming operation functions
00121  *
00122 @verbatim
00123  ===============================================================================
00124                   ##### Programming operation functions #####
00125  ===============================================================================
00126     [..]
00127     This subsection provides a set of functions allowing to manage the FLASH
00128     program operations.
00129 
00130 @endverbatim
00131   * @{
00132   */
00133 
00134 /**
00135   * @brief  Program a flash word at a specified address
00136   * @param  TypeProgram Indicate the way to program at a specified address.
00137   *         This parameter can be a value of @ref FLASH_Type_Program
00138   * @param  FlashAddress specifies the address to be programmed.
00139   *         This parameter shall be aligned to the Flash word:
00140   *          - 256 bits for STM32H74x/5X devices (8x 32bits words)
00141   *          - 128 bits for STM32H7Ax/BX devices (4x 32bits words)
00142   *          - 256 bits for STM32H72x/3X devices (8x 32bits words)
00143   * @param  DataAddress specifies the address of data to be programmed.
00144   *         This parameter shall be 32-bit aligned
00145   *
00146   * @retval HAL_StatusTypeDef HAL Status
00147   */
00148 HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
00149 {
00150   HAL_StatusTypeDef status;
00151   __IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
00152   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
00153   uint32_t bank;
00154   uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
00155 
00156   /* Check the parameters */
00157   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00158   assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
00159 
00160   /* Process Locked */
00161   __HAL_LOCK(&pFlash);
00162 
00163 #if defined (FLASH_OPTCR_PG_OTP)
00164   if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
00165 #else
00166   if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
00167 #endif /* FLASH_OPTCR_PG_OTP */
00168   {
00169     bank = FLASH_BANK_1;
00170   }
00171 #if defined (DUAL_BANK)
00172   else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
00173   {
00174     bank = FLASH_BANK_2;
00175   }
00176 #endif /* DUAL_BANK */
00177   else
00178   {
00179     return HAL_ERROR;
00180   }
00181 
00182   /* Reset error code */
00183   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00184 
00185   /* Wait for last operation to be completed */
00186   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
00187 
00188   if(status == HAL_OK)
00189   {
00190 #if defined (DUAL_BANK)
00191     if(bank == FLASH_BANK_1)
00192     {
00193 #if defined (FLASH_OPTCR_PG_OTP)
00194       if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00195       {
00196         /* Set OTP_PG bit */
00197         SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
00198       }
00199       else
00200 #endif /* FLASH_OPTCR_PG_OTP */
00201       {
00202         /* Set PG bit */
00203         SET_BIT(FLASH->CR1, FLASH_CR_PG);
00204       }
00205     }
00206     else
00207     {
00208       /* Set PG bit */
00209       SET_BIT(FLASH->CR2, FLASH_CR_PG);
00210     }
00211 #else /* Single Bank */
00212 #if defined (FLASH_OPTCR_PG_OTP)
00213       if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00214       {
00215         /* Set OTP_PG bit */
00216         SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
00217       }
00218       else
00219 #endif /* FLASH_OPTCR_PG_OTP */
00220       {
00221         /* Set PG bit */
00222         SET_BIT(FLASH->CR1, FLASH_CR_PG);
00223       }
00224 #endif /* DUAL_BANK */
00225 
00226     __ISB();
00227     __DSB();
00228 
00229 #if defined (FLASH_OPTCR_PG_OTP)
00230     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00231     {
00232       /* Program an OTP word (16 bits) */
00233       *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
00234     }
00235     else
00236 #endif /* FLASH_OPTCR_PG_OTP */
00237     {
00238       /* Program the flash word */
00239       do
00240       {
00241         *dest_addr = *src_addr;
00242         dest_addr++;
00243         src_addr++;
00244         row_index--;
00245      } while (row_index != 0U);
00246     }
00247 
00248     __ISB();
00249     __DSB();
00250 
00251     /* Wait for last operation to be completed */
00252     status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
00253 
00254 #if defined (DUAL_BANK)
00255 #if defined (FLASH_OPTCR_PG_OTP)
00256     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00257     {
00258       /* If the program operation is completed, disable the OTP_PG */
00259       CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
00260     }
00261     else
00262 #endif /* FLASH_OPTCR_PG_OTP */
00263     {
00264       if(bank == FLASH_BANK_1)
00265       {
00266         /* If the program operation is completed, disable the PG */
00267         CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
00268       }
00269       else
00270       {
00271         /* If the program operation is completed, disable the PG */
00272         CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
00273       }
00274     }
00275 #else /* Single Bank */
00276 #if defined (FLASH_OPTCR_PG_OTP)
00277     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00278     {
00279       /* If the program operation is completed, disable the OTP_PG */
00280       CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
00281     }
00282     else
00283 #endif /* FLASH_OPTCR_PG_OTP */
00284     {
00285       /* If the program operation is completed, disable the PG */
00286       CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
00287     }
00288 #endif /* DUAL_BANK */
00289   }
00290 
00291   /* Process Unlocked */
00292   __HAL_UNLOCK(&pFlash);
00293 
00294   return status;
00295 }
00296 
00297 /**
00298   * @brief  Program a flash word at a specified address with interrupt enabled.
00299   * @param  TypeProgram Indicate the way to program at a specified address.
00300   *                      This parameter can be a value of @ref FLASH_Type_Program
00301   * @param  FlashAddress specifies the address to be programmed.
00302   *         This parameter shall be aligned to the Flash word:
00303   *          - 256 bits for STM32H74x/5X devices (8x 32bits words)
00304   *          - 128 bits for STM32H7Ax/BX devices (4x 32bits words)
00305   *          - 256 bits for STM32H72x/3X devices (8x 32bits words)
00306   * @param  DataAddress specifies the address of data to be programmed.
00307   *         This parameter shall be 32-bit aligned
00308   *
00309   * @retval HAL Status
00310   */
00311 HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
00312 {
00313   HAL_StatusTypeDef status;
00314   __IO uint32_t *dest_addr = (__IO uint32_t*)FlashAddress;
00315   __IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
00316   uint32_t bank;
00317   uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
00318 
00319   /* Check the parameters */
00320   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
00321   assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
00322 
00323   /* Process Locked */
00324   __HAL_LOCK(&pFlash);
00325 
00326   /* Reset error code */
00327   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
00328 
00329 #if defined (FLASH_OPTCR_PG_OTP)
00330   if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
00331 #else
00332   if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
00333 #endif /* FLASH_OPTCR_PG_OTP */
00334   {
00335     bank = FLASH_BANK_1;
00336   }
00337 #if defined (DUAL_BANK)
00338   else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
00339   {
00340     bank = FLASH_BANK_2;
00341   }
00342 #endif /* DUAL_BANK */
00343   else
00344   {
00345     return HAL_ERROR;
00346   }
00347 
00348   /* Wait for last operation to be completed */
00349   status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
00350 
00351   if (status != HAL_OK)
00352   {
00353     /* Process Unlocked */
00354     __HAL_UNLOCK(&pFlash);
00355   }
00356   else
00357   {
00358     pFlash.Address = FlashAddress;
00359 
00360 #if defined (DUAL_BANK)
00361     if(bank == FLASH_BANK_1)
00362     {
00363       /* Set internal variables used by the IRQ handler */
00364       pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
00365 
00366 #if defined (FLASH_OPTCR_PG_OTP)
00367       if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00368       {
00369         /* Set OTP_PG bit */
00370         SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
00371       }
00372       else
00373 #endif /* FLASH_OPTCR_PG_OTP */
00374       {
00375         /* Set PG bit */
00376         SET_BIT(FLASH->CR1, FLASH_CR_PG);
00377       }
00378 
00379       /* Enable End of Operation and Error interrupts for Bank 1 */
00380 #if defined (FLASH_CR_OPERRIE)
00381       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00382                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
00383 #else
00384       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00385                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
00386 #endif /* FLASH_CR_OPERRIE */
00387     }
00388     else
00389     {
00390       /* Set internal variables used by the IRQ handler */
00391       pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK2;
00392 
00393       /* Set PG bit */
00394       SET_BIT(FLASH->CR2, FLASH_CR_PG);
00395 
00396       /* Enable End of Operation and Error interrupts for Bank2 */
00397 #if defined (FLASH_CR_OPERRIE)
00398       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
00399                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
00400 #else
00401       __HAL_FLASH_ENABLE_IT_BANK2(FLASH_IT_EOP_BANK2     | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
00402                                   FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
00403 #endif /* FLASH_CR_OPERRIE */
00404     }
00405 #else /* Single Bank */
00406     /* Set internal variables used by the IRQ handler */
00407     pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM_BANK1;
00408 
00409 #if defined (FLASH_OPTCR_PG_OTP)
00410     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00411     {
00412       /* Set OTP_PG bit */
00413       SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
00414     }
00415     else
00416 #endif /* FLASH_OPTCR_PG_OTP */
00417     {
00418       /* Set PG bit */
00419       SET_BIT(FLASH->CR1, FLASH_CR_PG);
00420     }
00421 
00422       /* Enable End of Operation and Error interrupts for Bank 1 */
00423 #if defined (FLASH_CR_OPERRIE)
00424       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00425                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
00426 #else
00427       __HAL_FLASH_ENABLE_IT_BANK1(FLASH_IT_EOP_BANK1     | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00428                                   FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
00429 #endif /* FLASH_CR_OPERRIE */
00430 #endif /* DUAL_BANK */
00431 
00432     __ISB();
00433     __DSB();
00434 
00435 #if defined (FLASH_OPTCR_PG_OTP)
00436     if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
00437     {
00438       /* Program an OTP word (16 bits) */
00439       *(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
00440     }
00441     else
00442 #endif /* FLASH_OPTCR_PG_OTP */
00443     {
00444       /* Program the flash word */
00445       do
00446       {
00447         *dest_addr = *src_addr;
00448         dest_addr++;
00449         src_addr++;
00450         row_index--;
00451       } while (row_index != 0U);
00452     }
00453 
00454     __ISB();
00455     __DSB();
00456   }
00457 
00458   return status;
00459 }
00460 
00461 /**
00462   * @brief This function handles FLASH interrupt request.
00463   * @retval None
00464   */
00465 void HAL_FLASH_IRQHandler(void)
00466 {
00467   uint32_t temp;
00468   uint32_t errorflag;
00469   FLASH_ProcedureTypeDef procedure;
00470 
00471   /* Check FLASH Bank1 End of Operation flag  */
00472   if(__HAL_FLASH_GET_FLAG_BANK1(FLASH_SR_EOP) != RESET)
00473   {
00474     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK1)
00475     {
00476       /* Nb of sector to erased can be decreased */
00477       pFlash.NbSectorsToErase--;
00478 
00479       /* Check if there are still sectors to erase */
00480       if(pFlash.NbSectorsToErase != 0U)
00481       {
00482         /* Indicate user which sector has been erased */
00483         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
00484 
00485         /* Clear bank 1 End of Operation pending bit */
00486         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
00487 
00488         /* Increment sector number */
00489         pFlash.Sector++;
00490         temp = pFlash.Sector;
00491         FLASH_Erase_Sector(temp, FLASH_BANK_1, pFlash.VoltageForErase);
00492       }
00493       else
00494       {
00495         /* No more sectors to Erase, user callback can be called */
00496         /* Reset Sector and stop Erase sectors procedure */
00497         pFlash.Sector = 0xFFFFFFFFU;
00498         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00499 
00500         /* FLASH EOP interrupt user callback */
00501         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
00502 
00503         /* Clear FLASH End of Operation pending bit */
00504         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
00505       }
00506     }
00507     else
00508     {
00509       procedure = pFlash.ProcedureOnGoing;
00510 
00511       if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
00512       {
00513         /* MassErase ended. Return the selected bank */
00514         /* FLASH EOP interrupt user callback */
00515         HAL_FLASH_EndOfOperationCallback(FLASH_BANK_1);
00516       }
00517       else if(procedure == FLASH_PROC_PROGRAM_BANK1)
00518       {
00519         /* Program ended. Return the selected address */
00520         /* FLASH EOP interrupt user callback */
00521         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00522       }
00523       else
00524       {
00525         /* Nothing to do */
00526       }
00527 
00528       if((procedure != FLASH_PROC_SECTERASE_BANK2) && \
00529          (procedure != FLASH_PROC_MASSERASE_BANK2) && \
00530          (procedure != FLASH_PROC_PROGRAM_BANK2))
00531       {
00532         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00533         /* Clear FLASH End of Operation pending bit */
00534         __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
00535       }
00536     }
00537   }
00538 
00539 #if defined (DUAL_BANK)
00540  /* Check FLASH Bank2 End of Operation flag  */
00541   if(__HAL_FLASH_GET_FLAG_BANK2(FLASH_SR_EOP) != RESET)
00542   {
00543     if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE_BANK2)
00544     {
00545       /*Nb of sector to erased can be decreased*/
00546       pFlash.NbSectorsToErase--;
00547 
00548       /* Check if there are still sectors to erase*/
00549       if(pFlash.NbSectorsToErase != 0U)
00550       {
00551         /*Indicate user which sector has been erased*/
00552         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
00553 
00554         /* Clear bank 2 End of Operation pending bit */
00555         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
00556 
00557         /*Increment sector number*/
00558         pFlash.Sector++;
00559         temp = pFlash.Sector;
00560         FLASH_Erase_Sector(temp, FLASH_BANK_2, pFlash.VoltageForErase);
00561       }
00562       else
00563       {
00564         /* No more sectors to Erase, user callback can be called */
00565         /* Reset Sector and stop Erase sectors procedure */
00566         pFlash.Sector = 0xFFFFFFFFU;
00567         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00568 
00569         /* FLASH EOP interrupt user callback */
00570         HAL_FLASH_EndOfOperationCallback(pFlash.Sector);
00571 
00572         /* Clear FLASH End of Operation pending bit */
00573         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
00574       }
00575     }
00576     else
00577     {
00578       procedure = pFlash.ProcedureOnGoing;
00579 
00580       if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
00581       {
00582         /*MassErase ended. Return the selected bank*/
00583         /* FLASH EOP interrupt user callback */
00584         HAL_FLASH_EndOfOperationCallback(FLASH_BANK_2);
00585       }
00586       else if(procedure == FLASH_PROC_PROGRAM_BANK2)
00587       {
00588         /* Program ended. Return the selected address */
00589         /* FLASH EOP interrupt user callback */
00590         HAL_FLASH_EndOfOperationCallback(pFlash.Address);
00591       }
00592       else
00593       {
00594         /* Nothing to do */
00595       }
00596 
00597       if((procedure != FLASH_PROC_SECTERASE_BANK1) && \
00598          (procedure != FLASH_PROC_MASSERASE_BANK1) && \
00599          (procedure != FLASH_PROC_PROGRAM_BANK1))
00600       {
00601         pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00602         /* Clear FLASH End of Operation pending bit */
00603         __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
00604       }
00605     }
00606   }
00607 #endif /* DUAL_BANK */
00608 
00609   /* Check FLASH Bank1 operation error flags */
00610 #if defined (FLASH_SR_OPERR)
00611   errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
00612                             FLASH_FLAG_INCERR_BANK1 | FLASH_FLAG_OPERR_BANK1);
00613 #else
00614   errorflag = FLASH->SR1 & (FLASH_FLAG_WRPERR_BANK1 | FLASH_FLAG_PGSERR_BANK1 | FLASH_FLAG_STRBERR_BANK1 | \
00615                             FLASH_FLAG_INCERR_BANK1);
00616 #endif /* FLASH_SR_OPERR */
00617 
00618   if(errorflag != 0U)
00619   {
00620     /* Save the error code */
00621     pFlash.ErrorCode |= errorflag;
00622 
00623     /* Clear error programming flags */
00624     __HAL_FLASH_CLEAR_FLAG_BANK1(errorflag);
00625 
00626     procedure = pFlash.ProcedureOnGoing;
00627 
00628     if(procedure == FLASH_PROC_SECTERASE_BANK1)
00629     {
00630       /* Return the faulty sector */
00631       temp = pFlash.Sector;
00632       pFlash.Sector = 0xFFFFFFFFU;
00633     }
00634     else if((procedure == FLASH_PROC_MASSERASE_BANK1) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
00635     {
00636       /* Return the faulty bank */
00637       temp = FLASH_BANK_1;
00638     }
00639     else
00640     {
00641       /* Return the faulty address */
00642       temp = pFlash.Address;
00643     }
00644 
00645     /* Stop the procedure ongoing*/
00646     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00647 
00648     /* FLASH error interrupt user callback */
00649     HAL_FLASH_OperationErrorCallback(temp);
00650   }
00651 
00652 #if defined (DUAL_BANK)
00653   /* Check FLASH Bank2 operation error flags */
00654 #if defined (FLASH_SR_OPERR)
00655   errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
00656                              FLASH_FLAG_INCERR_BANK2 | FLASH_FLAG_OPERR_BANK2) & 0x7FFFFFFFU);
00657 #else
00658   errorflag = FLASH->SR2 & ((FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGSERR_BANK2 | FLASH_FLAG_STRBERR_BANK2 | \
00659                              FLASH_FLAG_INCERR_BANK2) & 0x7FFFFFFFU);
00660 #endif /* FLASH_SR_OPERR */
00661 
00662   if(errorflag != 0U)
00663   {
00664     /* Save the error code */
00665     pFlash.ErrorCode |= (errorflag | 0x80000000U);
00666 
00667     /* Clear error programming flags */
00668     __HAL_FLASH_CLEAR_FLAG_BANK2(errorflag);
00669 
00670     procedure = pFlash.ProcedureOnGoing;
00671 
00672     if(procedure== FLASH_PROC_SECTERASE_BANK2)
00673     {
00674       /*return the faulty sector*/
00675       temp = pFlash.Sector;
00676       pFlash.Sector = 0xFFFFFFFFU;
00677     }
00678     else if((procedure == FLASH_PROC_MASSERASE_BANK2) || (procedure == FLASH_PROC_ALLBANK_MASSERASE))
00679     {
00680       /*return the faulty bank*/
00681       temp = FLASH_BANK_2;
00682     }
00683     else
00684     {
00685       /*return the faulty address*/
00686       temp = pFlash.Address;
00687     }
00688 
00689     /*Stop the procedure ongoing*/
00690     pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
00691 
00692     /* FLASH error interrupt user callback */
00693     HAL_FLASH_OperationErrorCallback(temp);
00694   }
00695 #endif /* DUAL_BANK */
00696 
00697   if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
00698   {
00699 #if defined (FLASH_CR_OPERRIE)
00700     /* Disable Bank1 Operation and Error source interrupt */
00701     __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1    | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00702                                  FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1 | FLASH_IT_OPERR_BANK1);
00703 
00704 #if defined (DUAL_BANK)
00705     /* Disable Bank2 Operation and Error source interrupt */
00706     __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2    | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
00707                                  FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2 | FLASH_IT_OPERR_BANK2);
00708 #endif /* DUAL_BANK */
00709 #else
00710     /* Disable Bank1 Operation and Error source interrupt */
00711     __HAL_FLASH_DISABLE_IT_BANK1(FLASH_IT_EOP_BANK1    | FLASH_IT_WRPERR_BANK1 | FLASH_IT_PGSERR_BANK1 | \
00712                                  FLASH_IT_STRBERR_BANK1 | FLASH_IT_INCERR_BANK1);
00713 
00714 #if defined (DUAL_BANK)
00715     /* Disable Bank2 Operation and Error source interrupt */
00716     __HAL_FLASH_DISABLE_IT_BANK2(FLASH_IT_EOP_BANK2    | FLASH_IT_WRPERR_BANK2 | FLASH_IT_PGSERR_BANK2 | \
00717                                  FLASH_IT_STRBERR_BANK2 | FLASH_IT_INCERR_BANK2);
00718 #endif /* DUAL_BANK */
00719 #endif /* FLASH_CR_OPERRIE */
00720 
00721     /* Process Unlocked */
00722     __HAL_UNLOCK(&pFlash);
00723   }
00724 }
00725 
00726 /**
00727   * @brief  FLASH end of operation interrupt callback
00728   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
00729   *                  Mass Erase: Bank number which has been requested to erase
00730   *                  Sectors Erase: Sector which has been erased
00731   *                    (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
00732   *                  Program: Address which was selected for data program
00733   * @retval None
00734   */
00735 __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
00736 {
00737   /* Prevent unused argument(s) compilation warning */
00738   UNUSED(ReturnValue);
00739 
00740   /* NOTE : This function Should not be modified, when the callback is needed,
00741             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
00742    */
00743 }
00744 
00745 /**
00746   * @brief  FLASH operation error interrupt callback
00747   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
00748   *                 Mass Erase: Bank number which has been requested to erase
00749   *                 Sectors Erase: Sector number which returned an error
00750   *                 Program: Address which was selected for data program
00751   * @retval None
00752   */
00753 __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
00754 {
00755   /* Prevent unused argument(s) compilation warning */
00756   UNUSED(ReturnValue);
00757 
00758   /* NOTE : This function Should not be modified, when the callback is needed,
00759             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
00760    */
00761 }
00762 
00763 /**
00764   * @}
00765   */
00766 
00767 /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
00768  *  @brief   Management functions
00769  *
00770 @verbatim
00771  ===============================================================================
00772                       ##### Peripheral Control functions #####
00773  ===============================================================================
00774     [..]
00775     This subsection provides a set of functions allowing to control the FLASH
00776     memory operations.
00777 
00778 @endverbatim
00779   * @{
00780   */
00781 
00782 /**
00783   * @brief  Unlock the FLASH control registers access
00784   * @retval HAL Status
00785   */
00786 HAL_StatusTypeDef HAL_FLASH_Unlock(void)
00787 {
00788   if(READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
00789   {
00790     /* Authorize the FLASH Bank1 Registers access */
00791     WRITE_REG(FLASH->KEYR1, FLASH_KEY1);
00792     WRITE_REG(FLASH->KEYR1, FLASH_KEY2);
00793 
00794     /* Verify Flash Bank1 is unlocked */
00795     if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) != 0U)
00796     {
00797       return HAL_ERROR;
00798     }
00799   }
00800 
00801 #if defined (DUAL_BANK)
00802   if(READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
00803   {
00804     /* Authorize the FLASH Bank2 Registers access */
00805     WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
00806     WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
00807 
00808     /* Verify Flash Bank2 is unlocked */
00809     if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) != 0U)
00810     {
00811       return HAL_ERROR;
00812     }
00813   }
00814 #endif /* DUAL_BANK */
00815 
00816   return HAL_OK;
00817 }
00818 
00819 /**
00820   * @brief  Locks the FLASH control registers access
00821   * @retval HAL Status
00822   */
00823 HAL_StatusTypeDef HAL_FLASH_Lock(void)
00824 {
00825   /* Set the LOCK Bit to lock the FLASH Bank1 Control Register access */
00826   SET_BIT(FLASH->CR1, FLASH_CR_LOCK);
00827 
00828   /* Verify Flash Bank1 is locked */
00829   if (READ_BIT(FLASH->CR1, FLASH_CR_LOCK) == 0U)
00830   {
00831     return HAL_ERROR;
00832   }
00833 
00834 #if defined (DUAL_BANK)
00835   /* Set the LOCK Bit to lock the FLASH Bank2 Control Register access */
00836   SET_BIT(FLASH->CR2, FLASH_CR_LOCK);
00837 
00838   /* Verify Flash Bank2 is locked */
00839   if (READ_BIT(FLASH->CR2, FLASH_CR_LOCK) == 0U)
00840   {
00841     return HAL_ERROR;
00842   }
00843 #endif /* DUAL_BANK */
00844 
00845   return HAL_OK;
00846 }
00847 
00848 /**
00849   * @brief  Unlock the FLASH Option Control Registers access.
00850   * @retval HAL Status
00851   */
00852 HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
00853 {
00854   if(READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
00855   {
00856     /* Authorizes the Option Byte registers programming */
00857     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
00858     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
00859 
00860     /* Verify that the Option Bytes are unlocked */
00861     if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
00862     {
00863       return HAL_ERROR;
00864     }
00865   }
00866 
00867   return HAL_OK;
00868 }
00869 
00870 /**
00871   * @brief  Lock the FLASH Option Control Registers access.
00872   * @retval HAL Status
00873   */
00874 HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
00875 {
00876   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
00877   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
00878 
00879   /* Verify that the Option Bytes are locked */
00880   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) == 0U)
00881   {
00882     return HAL_ERROR;
00883   }
00884 
00885   return HAL_OK;
00886 }
00887 
00888 /**
00889   * @brief  Launch the option bytes loading.
00890   * @retval HAL Status
00891   */
00892 HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
00893 {
00894   HAL_StatusTypeDef status;
00895 
00896   /* Wait for CRC computation to be completed */
00897   if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_1) != HAL_OK)
00898   {
00899     status = HAL_ERROR;
00900   }
00901 #if defined (DUAL_BANK)
00902   else if (FLASH_CRC_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, FLASH_BANK_2) != HAL_OK)
00903   {
00904     status = HAL_ERROR;
00905   }
00906 #endif /* DUAL_BANK */
00907   else
00908   {
00909     status = HAL_OK;
00910   }
00911 
00912   if (status == HAL_OK)
00913   {
00914     /* Set OPTSTRT Bit */
00915     SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
00916 
00917     /* Wait for OB change operation to be completed */
00918     status = FLASH_OB_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
00919   }
00920 
00921   return status;
00922 }
00923 
00924 /**
00925   * @}
00926   */
00927 
00928 /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
00929  *  @brief   Peripheral Errors functions
00930  *
00931 @verbatim
00932  ===============================================================================
00933                 ##### Peripheral Errors functions #####
00934  ===============================================================================
00935     [..]
00936     This subsection permits to get in run-time Errors of the FLASH peripheral.
00937 
00938 @endverbatim
00939   * @{
00940   */
00941 
00942 /**
00943   * @brief  Get the specific FLASH error flag.
00944   * @retval HAL_FLASH_ERRORCode The returned value can be:
00945   *            @arg HAL_FLASH_ERROR_NONE       : No error set
00946   *
00947   *            @arg HAL_FLASH_ERROR_WRP_BANK1  : Write Protection Error on Bank 1
00948   *            @arg HAL_FLASH_ERROR_PGS_BANK1  : Program Sequence Error on Bank 1
00949   *            @arg HAL_FLASH_ERROR_STRB_BANK1 : Strobe Error on Bank 1
00950   *            @arg HAL_FLASH_ERROR_INC_BANK1  : Inconsistency Error on Bank 1
00951   *            @arg HAL_FLASH_ERROR_OPE_BANK1  : Operation Error on Bank 1
00952   *            @arg HAL_FLASH_ERROR_RDP_BANK1  : Read Protection Error on Bank 1
00953   *            @arg HAL_FLASH_ERROR_RDS_BANK1  : Read Secured Error on Bank 1
00954   *            @arg HAL_FLASH_ERROR_SNECC_BANK1: ECC Single Correction Error on Bank 1
00955   *            @arg HAL_FLASH_ERROR_DBECC_BANK1: ECC Double Detection Error on Bank 1
00956   *            @arg HAL_FLASH_ERROR_CRCRD_BANK1: CRC Read Error on Bank 1
00957   *
00958   *            @arg HAL_FLASH_ERROR_WRP_BANK2  : Write Protection Error on Bank 2
00959   *            @arg HAL_FLASH_ERROR_PGS_BANK2  : Program Sequence Error on Bank 2
00960   *            @arg HAL_FLASH_ERROR_STRB_BANK2 : Strobe Error on Bank 2
00961   *            @arg HAL_FLASH_ERROR_INC_BANK2  : Inconsistency Error on Bank 2
00962   *            @arg HAL_FLASH_ERROR_OPE_BANK2  : Operation Error on Bank 2
00963   *            @arg HAL_FLASH_ERROR_RDP_BANK2  : Read Protection Error on Bank 2
00964   *            @arg HAL_FLASH_ERROR_RDS_BANK2  : Read Secured Error on Bank 2
00965   *            @arg HAL_FLASH_ERROR_SNECC_BANK2: SNECC Error on Bank 2
00966   *            @arg HAL_FLASH_ERROR_DBECC_BANK2: Double Detection ECC on Bank 2
00967   *            @arg HAL_FLASH_ERROR_CRCRD_BANK2: CRC Read Error on Bank 2
00968 */
00969 
00970 uint32_t HAL_FLASH_GetError(void)
00971 {
00972    return pFlash.ErrorCode;
00973 }
00974 
00975 /**
00976   * @}
00977   */
00978 
00979 /**
00980   * @}
00981   */
00982 
00983 /* Private functions ---------------------------------------------------------*/
00984 
00985 /** @addtogroup FLASH_Private_Functions
00986   * @{
00987   */
00988 
00989 /**
00990   * @brief  Wait for a FLASH operation to complete.
00991   * @param  Timeout maximum flash operation timeout
00992   * @param  Bank flash FLASH_BANK_1 or FLASH_BANK_2
00993   * @retval HAL_StatusTypeDef HAL Status
00994   */
00995 HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
00996 {
00997   /* Wait for the FLASH operation to complete by polling on QW flag to be reset.
00998      Even if the FLASH operation fails, the QW flag will be reset and an error
00999      flag will be set */
01000 
01001   uint32_t bsyflag = FLASH_FLAG_QW_BANK1;
01002   uint32_t errorflag = 0;
01003   uint32_t tickstart = HAL_GetTick();
01004 
01005   assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
01006 
01007 #if defined (DUAL_BANK)
01008 
01009   if (Bank == FLASH_BANK_2)
01010   {
01011     /* Select bsyflag depending on Bank */
01012     bsyflag = FLASH_FLAG_QW_BANK2;
01013   }
01014 #endif /* DUAL_BANK */
01015 
01016   while(__HAL_FLASH_GET_FLAG(bsyflag))
01017   {
01018     if(Timeout != HAL_MAX_DELAY)
01019     {
01020       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
01021       {
01022         return HAL_TIMEOUT;
01023       }
01024     }
01025   }
01026 
01027   /* Get Error Flags */
01028   if (Bank == FLASH_BANK_1)
01029   {
01030     errorflag = FLASH->SR1 & FLASH_FLAG_ALL_ERRORS_BANK1;
01031   }
01032 #if defined (DUAL_BANK)
01033   else
01034   {
01035     errorflag = (FLASH->SR2 & FLASH_FLAG_ALL_ERRORS_BANK2) | 0x80000000U;
01036   }
01037 #endif /* DUAL_BANK */
01038 
01039   /* In case of error reported in Flash SR1 or SR2 register */
01040   if((errorflag & 0x7FFFFFFFU) != 0U)
01041   {
01042     /*Save the error code*/
01043     pFlash.ErrorCode |= errorflag;
01044 
01045     /* Clear error programming flags */
01046     __HAL_FLASH_CLEAR_FLAG(errorflag);
01047 
01048     return HAL_ERROR;
01049   }
01050 
01051   /* Check FLASH End of Operation flag  */
01052   if(Bank == FLASH_BANK_1)
01053   {
01054     if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
01055     {
01056       /* Clear FLASH End of Operation pending bit */
01057       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
01058     }
01059   }
01060 #if defined (DUAL_BANK)
01061   else
01062   {
01063     if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
01064     {
01065       /* Clear FLASH End of Operation pending bit */
01066       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
01067     }
01068   }
01069 #endif /* DUAL_BANK */
01070 
01071   return HAL_OK;
01072 }
01073 
01074 /**
01075   * @brief  Wait for a FLASH Option Bytes change operation to complete.
01076   * @param  Timeout maximum flash operation timeout
01077   * @retval HAL_StatusTypeDef HAL Status
01078   */
01079 HAL_StatusTypeDef FLASH_OB_WaitForLastOperation(uint32_t Timeout)
01080 {
01081   /* Get timeout */
01082   uint32_t tickstart = HAL_GetTick();
01083 
01084   /* Wait for the FLASH Option Bytes change operation to complete by polling on OPT_BUSY flag to be reset */
01085   while(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPT_BUSY) != 0U)
01086   {
01087     if(Timeout != HAL_MAX_DELAY)
01088     {
01089       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
01090       {
01091         return HAL_TIMEOUT;
01092       }
01093     }
01094   }
01095 
01096   /* Check option byte change error */
01097   if(READ_BIT(FLASH->OPTSR_CUR, FLASH_OPTSR_OPTCHANGEERR) != 0U)
01098   {
01099     /* Save the error code */
01100     pFlash.ErrorCode |= HAL_FLASH_ERROR_OB_CHANGE;
01101 
01102     /* Clear the OB error flag */
01103     FLASH->OPTCCR |= FLASH_OPTCCR_CLR_OPTCHANGEERR;
01104 
01105     return HAL_ERROR;
01106   }
01107 
01108   /* If there is no error flag set */
01109   return HAL_OK;
01110 }
01111 
01112 /**
01113   * @brief  Wait for a FLASH CRC computation to complete.
01114   * @param  Timeout maximum flash operation timeout
01115   * @param  Bank flash FLASH_BANK_1 or FLASH_BANK_2
01116   * @retval HAL_StatusTypeDef HAL Status
01117   */
01118 HAL_StatusTypeDef FLASH_CRC_WaitForLastOperation(uint32_t Timeout, uint32_t Bank)
01119 {
01120   uint32_t bsyflag;
01121   uint32_t tickstart = HAL_GetTick();
01122 
01123   assert_param(IS_FLASH_BANK_EXCLUSIVE(Bank));
01124 
01125   /* Select bsyflag depending on Bank */
01126   if(Bank == FLASH_BANK_1)
01127   {
01128     bsyflag = FLASH_FLAG_CRC_BUSY_BANK1;
01129   }
01130   else
01131   {
01132     bsyflag = FLASH_FLAG_CRC_BUSY_BANK2;
01133   }
01134 
01135   /* Wait for the FLASH CRC computation to complete by polling on CRC_BUSY flag to be reset */
01136   while(__HAL_FLASH_GET_FLAG(bsyflag))
01137   {
01138     if(Timeout != HAL_MAX_DELAY)
01139     {
01140       if(((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
01141       {
01142         return HAL_TIMEOUT;
01143       }
01144     }
01145   }
01146 
01147   /* Check FLASH CRC read error flag  */
01148   if(Bank == FLASH_BANK_1)
01149   {
01150     if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1))
01151     {
01152       /* Save the error code */
01153       pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK1;
01154 
01155       /* Clear FLASH CRC read error pending bit */
01156       __HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_CRCRDERR_BANK1);
01157 
01158       return HAL_ERROR;
01159     }
01160   }
01161 #if defined (DUAL_BANK)
01162   else
01163   {
01164     if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2))
01165     {
01166       /* Save the error code */
01167       pFlash.ErrorCode |= HAL_FLASH_ERROR_CRCRD_BANK2;
01168 
01169       /* Clear FLASH CRC read error pending bit */
01170       __HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_CRCRDERR_BANK2);
01171 
01172       return HAL_ERROR;
01173     }
01174   }
01175 #endif /* DUAL_BANK */
01176 
01177   /* If there is no error flag set */
01178   return HAL_OK;
01179 }
01180 
01181 /**
01182   * @}
01183   */
01184 
01185 #endif /* HAL_FLASH_MODULE_ENABLED */
01186 
01187 /**
01188   * @}
01189   */
01190 
01191 /**
01192   * @}
01193   */
01194 
01195