generated from Template/H563ZI-HAL-CMake-Template
	
		
			
				
	
	
		
			965 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			965 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|   ******************************************************************************
 | |
|   * @file    stm32h5xx_hal_flash.c
 | |
|   * @author  MCD Application Team
 | |
|   * @brief   FLASH HAL module driver.
 | |
|   *          This file provides firmware functions to manage the following
 | |
|   *          functionalities of the internal FLASH memory:
 | |
|   *           + Program operations functions
 | |
|   *           + Memory Control functions
 | |
|   *           + Peripheral Errors functions
 | |
|   *
 | |
|   ******************************************************************************
 | |
|   * @attention
 | |
|   *
 | |
|   * Copyright (c) 2023 STMicroelectronics.
 | |
|   * All rights reserved.
 | |
|   *
 | |
|   * This software is licensed under terms that can be found in the LICENSE file
 | |
|   * in the root directory of this software component.
 | |
|   * If no LICENSE file comes with this software, it is provided AS-IS.
 | |
|   *
 | |
|   ******************************************************************************
 | |
|  @verbatim
 | |
|   ==============================================================================
 | |
|                         ##### FLASH peripheral features #####
 | |
|   ==============================================================================
 | |
| 
 | |
|   [..] The Flash memory interface manages CPU AHB C-Bus accesses to the Flash memory.
 | |
|        It implements the erase and program Flash memory operations and the read
 | |
|        and write protection mechanisms.
 | |
| 
 | |
|   [..] The FLASH main features are:
 | |
|       (+) Flash memory read operations
 | |
|       (+) Flash memory program/erase operations
 | |
|       (+) Read / write protections
 | |
|       (+) Option bytes programming
 | |
|       (+) TrustZone aware
 | |
|       (+) Watermark-based area protection
 | |
|       (+) Block-based sector protection
 | |
|       (+) Error code correction (ECC)
 | |
| 
 | |
| 
 | |
|                         ##### How to use this driver #####
 | |
|  ==============================================================================
 | |
|     [..]
 | |
|       This driver provides functions and macros to configure and program the FLASH
 | |
|       memory of all STM32H5xx devices.
 | |
| 
 | |
|       (#) FLASH Memory IO Programming functions:
 | |
|            (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and
 | |
|                 HAL_FLASH_Lock() functions
 | |
|            (++) Flash memory programming by 128 bits (user area, OBKeys) and 16 bits (OTP and Flash high-cycle
 | |
|                 data area)
 | |
|            (++) There Two modes of programming :
 | |
|             (+++) Polling mode using HAL_FLASH_Program() function
 | |
|             (+++) Interrupt mode using HAL_FLASH_Program_IT() function
 | |
| 
 | |
|       (#) Interrupts and flags management functions :
 | |
|            (++) Handle FLASH interrupts by calling HAL_FLASH_IRQHandler()
 | |
|            (++) Callback functions are called when the flash operations are finished :
 | |
|                 HAL_FLASH_EndOfOperationCallback() when everything is ok, otherwise
 | |
|                 HAL_FLASH_OperationErrorCallback()
 | |
|            (++) Get error flag status by calling HAL_FLASH_GetError()
 | |
| 
 | |
|       (#) Option bytes management functions :
 | |
|            (++) Lock and Unlock the option bytes using HAL_FLASH_OB_Unlock() and
 | |
|                 HAL_FLASH_OB_Lock() functions
 | |
|            (++) Launch the reload of the option bytes using HAL_FLASH_OB_Launch() function.
 | |
|                 In this case, a reset is generated
 | |
|     [..]
 | |
|       In addition to these functions, this driver includes a set of macros allowing
 | |
|       to handle the following operations:
 | |
|        (+) Set the latency
 | |
|        (+) Enable/Disable the FLASH interrupts
 | |
|        (+) Monitor the FLASH flags status
 | |
|      [..]
 | |
|     (@) The contents of the Flash memory are not guaranteed if a device reset occurs during
 | |
|         a Flash memory operation.
 | |
| 
 | |
|  @endverbatim
 | |
|   */
 | |
| 
 | |
| /* Includes ------------------------------------------------------------------*/
 | |
| #include "stm32h5xx_hal.h"
 | |
| 
 | |
| /** @addtogroup STM32H5xx_HAL_Driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup FLASH FLASH
 | |
|   * @brief FLASH HAL module driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| #ifdef HAL_FLASH_MODULE_ENABLED
 | |
| 
 | |
| /* Private typedef -----------------------------------------------------------*/
 | |
| /* Private define ------------------------------------------------------------*/
 | |
| /* Private macro -------------------------------------------------------------*/
 | |
| /* Private variables ---------------------------------------------------------*/
 | |
| /** @defgroup FLASH_Private_Variables FLASH Private Variables
 | |
|   * @{
 | |
|   */
 | |
| /**
 | |
|   * @brief  Variable used for Program/Erase sectors under interruption
 | |
|   */
 | |
| FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
 | |
|                                .ErrorCode = HAL_FLASH_ERROR_NONE, \
 | |
|                                .ProcedureOnGoing = 0U, \
 | |
|                                .Address = 0U, \
 | |
|                                .Bank = FLASH_BANK_1, \
 | |
|                                .Sector = 0U, \
 | |
|                                .NbSectorsToErase = 0U
 | |
|                               };
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| /* Private function prototypes -----------------------------------------------*/
 | |
| /** @defgroup FLASH_Private_Functions FLASH Private Functions
 | |
|   * @{
 | |
|   */
 | |
| static void          FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress);
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
| static void          FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress);
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
| static void          FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress);
 | |
| #if defined(FLASH_EDATAR_EDATA_EN)
 | |
| static void          FLASH_Program_Word(uint32_t FlashAddress, uint32_t DataAddress);
 | |
| #endif /* FLASH_EDATAR_EDATA_EN */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| /* Exported functions ---------------------------------------------------------*/
 | |
| 
 | |
| /** @defgroup FLASH_Exported_Functions FLASH Exported functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
 | |
|   *  @brief   Programming operation functions
 | |
|   *
 | |
| @verbatim
 | |
|  ===============================================================================
 | |
|                   ##### Programming operation functions #####
 | |
|  ===============================================================================
 | |
|     [..]
 | |
|     This subsection provides a set of functions allowing to manage the FLASH
 | |
|     program operations.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Program a quad-word at a specified address.
 | |
|   * @param  TypeProgram Indicate the way to program at a specified address.
 | |
|   *         This parameter can be a value of @ref FLASH_Type_Program
 | |
|   * @param  FlashAddress specifies the address to be programmed.
 | |
|   *         This parameter shall be aligned to the Flash word (128-bit)
 | |
|   * @param  DataAddress specifies the address of data to be programmed
 | |
|   *         This parameter shall be 32-bit aligned
 | |
|   * @retval HAL_StatusTypeDef HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
 | |
| {
 | |
|   HAL_StatusTypeDef status;
 | |
|   __IO uint32_t *reg_cr;
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
|   __IO uint32_t *reg_obkcfgr;
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
 | |
| 
 | |
|   /* Reset error code */
 | |
|   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 | |
| 
 | |
|   /* Wait for last operation to be completed */
 | |
|   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
 | |
| 
 | |
|   if (status == HAL_OK)
 | |
|   {
 | |
|     /* Set current operation type */
 | |
|     pFlash.ProcedureOnGoing = TypeProgram;
 | |
| 
 | |
|     /* Access to SECCR or NSCR depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
| #else
 | |
|     reg_cr = &(FLASH_NS->NSCR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a quad-word (128-bit) at a specified address */
 | |
|       FLASH_Program_QuadWord(FlashAddress, DataAddress);
 | |
|     }
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
|     else if ((TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK) || (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a quad-word (128-bit) of OBK at a specified address */
 | |
|       FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
 | |
|     }
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
| #if defined (FLASH_EDATAR_EDATA_EN)
 | |
|     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a Flash high-cycle data half-word at a specified address */
 | |
|       FLASH_Program_HalfWord(FlashAddress, DataAddress);
 | |
|     }
 | |
|     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_WORD_EDATA)
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a Flash high-cycle data half-word at a specified address */
 | |
|       FLASH_Program_Word(FlashAddress, DataAddress);
 | |
|     }
 | |
| #endif /* FLASH_EDATAR_EDATA_EN */
 | |
|     else
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program an OTP half-word at a specified address */
 | |
|       FLASH_Program_HalfWord(FlashAddress, DataAddress);
 | |
|     }
 | |
| 
 | |
|     /* Wait for last operation to be completed */
 | |
|     status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
 | |
| 
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
|     /* If the program operation is completed, disable the PG */
 | |
|     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK | FLASH_OBK | FLASH_OTP | FLASH_OBKCFGR_ALT_SECT)));
 | |
| 
 | |
|     /* Clear alternate sector bit */
 | |
|     if (TypeProgram == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT)
 | |
|     {
 | |
|       reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
 | |
|       CLEAR_BIT((*reg_obkcfgr), FLASH_OBKCFGR_ALT_SECT);
 | |
|     }
 | |
| #else
 | |
|     /* If the program operation is completed, disable the PG */
 | |
|     CLEAR_BIT((*reg_cr), (TypeProgram & ~(FLASH_NON_SECURE_MASK |  FLASH_OTP)));
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
|   }
 | |
|   /* return status */
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Program a quad-word at a specified address with interrupt enabled.
 | |
|   * @param  TypeProgram Indicate the way to program at a specified address.
 | |
|   *                      This parameter can be a value of @ref FLASH_Type_Program
 | |
|   * @param  FlashAddress specifies the address to be programmed.
 | |
|   *         This parameter shall be aligned to the Flash word (128-bit)
 | |
|   * @param  DataAddress specifies the address of data to be programmed
 | |
|   *         This parameter shall be 32-bit aligned
 | |
|   * @retval HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
 | |
| {
 | |
|   HAL_StatusTypeDef status;
 | |
|   __IO uint32_t *reg_cr;
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
 | |
| 
 | |
|   /* Reset error code */
 | |
|   pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
 | |
| 
 | |
|   /* Wait for last operation to be completed */
 | |
|   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
 | |
| 
 | |
|   if (status != HAL_OK)
 | |
|   {
 | |
|     /* Process Unlocked */
 | |
|     __HAL_UNLOCK(&pFlash);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set internal variables used by the IRQ handler */
 | |
|     pFlash.ProcedureOnGoing = TypeProgram;
 | |
|     pFlash.Address = FlashAddress;
 | |
| 
 | |
|     /* Access to SECCR or NSCR depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|     reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
| #else
 | |
|     reg_cr = &(FLASH_NS->NSCR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|     /* Enable End of Operation and Error interrupts */
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
|     (*reg_cr) |= (FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
 | |
|                   FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
 | |
|                   FLASH_IT_OBKWERR);
 | |
| #else
 | |
|     (*reg_cr) |= (FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
 | |
|                   FLASH_IT_STRBERR | FLASH_IT_INCERR);
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
| 
 | |
|     if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_USER_MEM_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a quad-word (128-bit) at a specified address */
 | |
|       FLASH_Program_QuadWord(FlashAddress, DataAddress);
 | |
|     }
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
|     else if (((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK) || \
 | |
|              ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD_OBK_ALT))
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_OBK_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a quad-word (128-bit) of OBK at a specified address */
 | |
|       FLASH_Program_QuadWord_OBK(FlashAddress, DataAddress);
 | |
|     }
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
| #if defined (FLASH_EDATAR_EDATA_EN)
 | |
|     else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_HALFWORD_EDATA)
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a Flash high-cycle data half-word at a specified address */
 | |
|       FLASH_Program_HalfWord(FlashAddress, DataAddress);
 | |
|     }
 | |
|      else if ((TypeProgram & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_WORD_EDATA)
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_EDATA_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program a Flash high-cycle data word at a specified address */
 | |
|       FLASH_Program_Word(FlashAddress, DataAddress);
 | |
|     }
 | |
| #endif /* FLASH_EDATAR_EDATA_EN */
 | |
|     else
 | |
|     {
 | |
|       /* Check the parameters */
 | |
|       assert_param(IS_FLASH_OTP_ADDRESS(FlashAddress));
 | |
| 
 | |
|       /* Program an OTP word at a specified address */
 | |
|       FLASH_Program_HalfWord(FlashAddress, DataAddress);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* return status */
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief This function handles FLASH interrupt request.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_FLASH_IRQHandler(void)
 | |
| {
 | |
|   uint32_t param = 0U;
 | |
|   uint32_t errorflag;
 | |
|   __IO uint32_t *reg_cr;
 | |
|   __IO uint32_t *reg_ccr;
 | |
|   const __IO uint32_t *reg_sr;
 | |
|   const __IO uint32_t *reg_ecccorr;
 | |
| 
 | |
|   /* Access to CR, CCR and SR registers depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
|   reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
 | |
|   reg_sr  = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
 | |
| #else
 | |
|   reg_cr = &(FLASH_NS->NSCR);
 | |
|   reg_ccr = &(FLASH_NS->NSCCR);
 | |
|   reg_sr = &(FLASH_NS->NSSR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
|   reg_ecccorr = &(FLASH->ECCCORR);
 | |
| 
 | |
|   /* Save Flash errors */
 | |
|   errorflag = (*reg_sr) & FLASH_FLAG_SR_ERRORS;
 | |
|   /* Add option byte error flag, if any */
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
 | |
| #endif /* __ARM_FEATURE_CMSE */
 | |
| 
 | |
|   /* Set parameter of the callback */
 | |
|   if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
 | |
|   {
 | |
|     param = pFlash.Sector;
 | |
|   }
 | |
|   else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_MASSERASE)
 | |
|   {
 | |
|     param = pFlash.Bank;
 | |
|   }
 | |
|   else if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEPROGRAM_QUADWORD)
 | |
|   {
 | |
|     param = pFlash.Address;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Empty statement (to be compliant MISRA 15.7) */
 | |
|   }
 | |
| 
 | |
|   /* Clear operation bit on the on-going procedure */
 | |
|   CLEAR_BIT((*reg_cr), (pFlash.ProcedureOnGoing & ~(FLASH_NON_SECURE_MASK)));
 | |
| 
 | |
|   /* Check FLASH operation error flags */
 | |
|   if (errorflag != 0U)
 | |
|   {
 | |
|     /* Save the error code */
 | |
|     pFlash.ErrorCode |= errorflag;
 | |
| 
 | |
|     /* Clear error programming flags */
 | |
|     (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|     if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
 | |
|     {
 | |
|       FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
 | |
|     }
 | |
| #endif /* __ARM_FEATURE_CMSE */
 | |
| 
 | |
|     /* Stop the procedure ongoing */
 | |
|     pFlash.ProcedureOnGoing = 0U;
 | |
| 
 | |
|     /* FLASH error interrupt user callback */
 | |
|     HAL_FLASH_OperationErrorCallback(param);
 | |
|   }
 | |
| 
 | |
|   /* Check FLASH End of Operation flag */
 | |
|   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
 | |
|   {
 | |
|     /* Clear FLASH End of Operation pending bit */
 | |
|     (*reg_ccr) = FLASH_FLAG_EOP;
 | |
| 
 | |
|     if ((pFlash.ProcedureOnGoing & (~FLASH_NON_SECURE_MASK)) == FLASH_TYPEERASE_SECTORS)
 | |
|     {
 | |
|       /* Nb of sector to erased can be decreased */
 | |
|       pFlash.NbSectorsToErase--;
 | |
| 
 | |
|       /* Check if there are still sectors to erase */
 | |
|       if (pFlash.NbSectorsToErase != 0U)
 | |
|       {
 | |
|         /* Increment sector number */
 | |
|         pFlash.Sector++;
 | |
|         FLASH_Erase_Sector(pFlash.Sector, pFlash.Bank);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* No more sectors to erase */
 | |
|         /* Reset sector parameter and stop erase sectors procedure */
 | |
|         param = 0xFFFFFFFFU;
 | |
|         pFlash.ProcedureOnGoing = 0U;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Clear the procedure ongoing */
 | |
|       pFlash.ProcedureOnGoing = 0U;
 | |
|     }
 | |
| 
 | |
|     /* FLASH EOP interrupt user callback */
 | |
|     HAL_FLASH_EndOfOperationCallback(param);
 | |
|   }
 | |
| 
 | |
|   /* Check FLASH ECC correction flag */
 | |
|   if ((*reg_ecccorr & FLASH_ECCR_ECCC) != 0U)
 | |
|   {
 | |
|     /* Call User callback */
 | |
|     HAL_FLASHEx_EccCorrectionCallback();
 | |
| 
 | |
|     /* Clear ECC correction flag in order to allow new ECC error record */
 | |
|     FLASH->ECCCORR |= FLASH_ECCR_ECCC;
 | |
|   }
 | |
| 
 | |
|   if (pFlash.ProcedureOnGoing == 0U)
 | |
|   {
 | |
|     /* Disable Flash Operation and Error source interrupt */
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
|     (*reg_cr) &= ~(FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
 | |
|                    FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OBKERR | \
 | |
|                    FLASH_IT_OBKWERR | FLASH_IT_OPTCHANGEERR);
 | |
| #else
 | |
|     (*reg_cr) &= ~(FLASH_IT_EOP     | FLASH_IT_WRPERR | FLASH_IT_PGSERR | \
 | |
|                    FLASH_IT_STRBERR | FLASH_IT_INCERR | FLASH_IT_OPTCHANGEERR);
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  FLASH end of operation interrupt callback
 | |
|   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
 | |
|   *                  Mass Erase: Bank number which has been requested to erase
 | |
|   *                  Sectors Erase: Sector which has been erased
 | |
|   *                    (if 0xFFFFFFFF, it means that all the selected sectors have been erased)
 | |
|   *                  Program: Address which was selected for data program
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
 | |
| {
 | |
|   /* Prevent unused argument(s) compilation warning */
 | |
|   UNUSED(ReturnValue);
 | |
| 
 | |
|   /* NOTE : This function Should not be modified, when the callback is needed,
 | |
|             the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  FLASH operation error interrupt callback
 | |
|   * @param  ReturnValue The value saved in this parameter depends on the ongoing procedure
 | |
|   *                 Mass Erase: Bank number which has been requested to erase
 | |
|   *                 Sectors Erase: Sector number which returned an error
 | |
|   *                 Program: Address which was selected for data program
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
 | |
| {
 | |
|   /* Prevent unused argument(s) compilation warning */
 | |
|   UNUSED(ReturnValue);
 | |
| 
 | |
|   /* NOTE : This function Should not be modified, when the callback is needed,
 | |
|             the HAL_FLASH_OperationErrorCallback could be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
 | |
|   *  @brief    Management functions
 | |
|   *
 | |
| @verbatim
 | |
|  ===============================================================================
 | |
|                       ##### Peripheral Control functions #####
 | |
|  ===============================================================================
 | |
|     [..]
 | |
|     This subsection provides a set of functions allowing to control the FLASH
 | |
|     memory operations.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Unlock the FLASH control registers access
 | |
|   * @retval HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_Unlock(void)
 | |
| {
 | |
|   HAL_StatusTypeDef status = HAL_OK;
 | |
| 
 | |
|   if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
 | |
|   {
 | |
|     /* Authorize the FLASH Control Register access */
 | |
|     WRITE_REG(FLASH->NSKEYR, FLASH_KEY1);
 | |
|     WRITE_REG(FLASH->NSKEYR, FLASH_KEY2);
 | |
| 
 | |
|     /* Verify Flash CR is unlocked */
 | |
|     if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) != 0U)
 | |
|     {
 | |
|       status = HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   if (status == HAL_OK)
 | |
|   {
 | |
|     if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
 | |
|     {
 | |
|       /* Authorize the FLASH Control Register access */
 | |
|       WRITE_REG(FLASH->SECKEYR, FLASH_KEY1);
 | |
|       WRITE_REG(FLASH->SECKEYR, FLASH_KEY2);
 | |
| 
 | |
|       /* verify Flash CR is unlocked */
 | |
|       if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) != 0U)
 | |
|       {
 | |
|         status = HAL_ERROR;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #endif /* __ARM_FEATURE_CMSE */
 | |
| 
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Locks the FLASH control registers access
 | |
|   * @retval HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_Lock(void)
 | |
| {
 | |
|   HAL_StatusTypeDef status = HAL_OK;
 | |
| 
 | |
|   /* Set the LOCK Bit to lock the FLASH Control Register access */
 | |
|   SET_BIT(FLASH->NSCR, FLASH_CR_LOCK);
 | |
| 
 | |
|   /* Verify Flash is locked */
 | |
|   if (READ_BIT(FLASH->NSCR, FLASH_CR_LOCK) == 0U)
 | |
|   {
 | |
|     status = HAL_ERROR;
 | |
|   }
 | |
| 
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   if (status == HAL_OK)
 | |
|   {
 | |
|     /* Set the LOCK Bit to lock the FLASH Control Register access */
 | |
|     SET_BIT(FLASH->SECCR, FLASH_CR_LOCK);
 | |
| 
 | |
|     /* verify Flash is locked */
 | |
|     if (READ_BIT(FLASH->SECCR, FLASH_CR_LOCK) == 0U)
 | |
|     {
 | |
|       status = HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
| #endif /* __ARM_FEATURE_CMSE */
 | |
| 
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Unlock the FLASH Option Control Registers access.
 | |
|   * @retval HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
 | |
| {
 | |
|   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
 | |
|   {
 | |
|     /* Authorizes the Option Byte registers programming */
 | |
|     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY1);
 | |
|     WRITE_REG(FLASH->OPTKEYR, FLASH_OPT_KEY2);
 | |
| 
 | |
|     /* Verify that the Option Bytes are unlocked */
 | |
|     if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
 | |
|     {
 | |
|       return HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Lock the FLASH Option Control Registers access.
 | |
|   * @retval HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
 | |
| {
 | |
|   /* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
 | |
|   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK);
 | |
| 
 | |
|   /* Verify that the Option Bytes are locked */
 | |
|   if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTLOCK) != 0U)
 | |
|   {
 | |
|     return HAL_OK;
 | |
|   }
 | |
| 
 | |
|   return HAL_ERROR;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Launch the option bytes loading.
 | |
|   * @retval HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
 | |
| {
 | |
|   HAL_StatusTypeDef status;
 | |
| 
 | |
|   /* Set OPTSTRT Bit */
 | |
|   SET_BIT(FLASH->OPTCR, FLASH_OPTCR_OPTSTART);
 | |
| 
 | |
|   /* Wait for OB change operation to be completed */
 | |
|   status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
 | |
| 
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @defgroup FLASH_Exported_Functions_Group3 Peripheral State and Errors functions
 | |
|   *  @brief   Peripheral Errors functions
 | |
|   *
 | |
| @verbatim
 | |
|  ===============================================================================
 | |
|                 ##### Peripheral Errors functions #####
 | |
|  ===============================================================================
 | |
|     [..]
 | |
|     This subsection permits to get in run-time Errors of the FLASH peripheral.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Get the specific FLASH error flag.
 | |
|   * @retval HAL_FLASH_ERRORCode The returned value can be:
 | |
|   *            @arg HAL_FLASH_ERROR_NONE  : No error set
 | |
|   *            @arg HAL_FLASH_ERROR_WRP   : Write Protection Error
 | |
|   *            @arg HAL_FLASH_ERROR_PGS   : Program Sequence Error
 | |
|   *            @arg HAL_FLASH_ERROR_STRB  : Strobe Error
 | |
|   *            @arg HAL_FLASH_ERROR_INC   : Inconsistency Error
 | |
|   *            @arg HAL_FLASH_ERROR_OBK   : OBK Error
 | |
|   *            @arg HAL_FLASH_ERROR_OBKW  : OBK Write Error
 | |
|   *            @arg HAL_FLASH_ERROR_OB_CHANGE : Option Byte Change Error
 | |
|   *            @arg HAL_FLASH_ERROR_ECCC  : ECC Single Correction Error
 | |
|   *            @arg HAL_FLASH_ERROR_ECCD  : ECC Double Detection Error
 | |
|   */
 | |
| uint32_t HAL_FLASH_GetError(void)
 | |
| {
 | |
|   return pFlash.ErrorCode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /* Private functions ---------------------------------------------------------*/
 | |
| 
 | |
| /** @addtogroup FLASH_Private_Functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Wait for a FLASH operation to complete.
 | |
|   * @param  Timeout maximum flash operation timeout
 | |
|   * @retval HAL_StatusTypeDef HAL Status
 | |
|   */
 | |
| HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
 | |
| {
 | |
|   /* Wait for the FLASH operation to complete by polling on BUSY, WBNE and DBNE flags to be reset.
 | |
|      Even if the FLASH operation fails, the BUSY, WBNE and DBNE flags will be reset and an error
 | |
|      flag will be set */
 | |
| 
 | |
|   uint32_t errorflag;
 | |
|   const __IO uint32_t *reg_sr;
 | |
|   __IO uint32_t *reg_ccr;
 | |
| 
 | |
|   uint32_t tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Access to SR register depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|   reg_sr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECSR) : &(FLASH_NS->NSSR);
 | |
| #else
 | |
|   reg_sr = &(FLASH_NS->NSSR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|   /* Wait on BSY, WBNE and DBNE flags to be reset */
 | |
|   while (((*reg_sr) & (FLASH_FLAG_BSY | FLASH_FLAG_WBNE | FLASH_FLAG_DBNE)) != 0U)
 | |
|   {
 | |
|     if (Timeout != HAL_MAX_DELAY)
 | |
|     {
 | |
|       if (((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U))
 | |
|       {
 | |
|         return HAL_TIMEOUT;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Access to CCR register depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|   reg_ccr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCCR) : &(FLASH_NS->NSCCR);
 | |
| #else
 | |
|   reg_ccr = &(FLASH_NS->NSCCR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|   /* Check FLASH operation error flags */
 | |
|   errorflag = ((*reg_sr) & FLASH_FLAG_SR_ERRORS);
 | |
|   /* Add option byte error flag, if any */
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|   errorflag |= (FLASH->NSSR & FLASH_FLAG_OPTCHANGEERR);
 | |
| #endif /* __ARM_FEATURE_CMSE */
 | |
| 
 | |
|   /* In case of error reported in Flash SR or OPTSR registers */
 | |
|   if (errorflag != 0U)
 | |
|   {
 | |
|     /*Save the error code*/
 | |
|     pFlash.ErrorCode |= errorflag;
 | |
| 
 | |
|     /* Clear error flags */
 | |
|     (*reg_ccr) = errorflag & FLASH_FLAG_SR_ERRORS;
 | |
| #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
 | |
|     if ((errorflag & FLASH_FLAG_OPTCHANGEERR) != 0U)
 | |
|     {
 | |
|       FLASH->NSCCR = FLASH_FLAG_OPTCHANGEERR;
 | |
|     }
 | |
| #endif /* __ARM_FEATURE_CMSE */
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check FLASH End of Operation flag  */
 | |
|   if (((*reg_sr) & FLASH_FLAG_EOP) != 0U)
 | |
|   {
 | |
|     /* Clear FLASH End of Operation pending bit */
 | |
|     (*reg_ccr) = FLASH_FLAG_EOP;
 | |
|   }
 | |
| 
 | |
|   /* If there is no error flag set */
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Program a quad-word (128-bit) at a specified address.
 | |
|   * @param  FlashAddress specifies the address to be programmed.
 | |
|   * @param  DataAddress specifies the address of data to be programmed.
 | |
|   * @retval None
 | |
|   */
 | |
| static void FLASH_Program_QuadWord(uint32_t FlashAddress, uint32_t DataAddress)
 | |
| {
 | |
|   uint8_t index = 4;
 | |
|   uint32_t *dest_addr = (uint32_t *)FlashAddress;
 | |
|   uint32_t *src_addr  = (uint32_t *)DataAddress;
 | |
|   uint32_t primask_bit;
 | |
|   __IO uint32_t *reg_cr;
 | |
| 
 | |
|   /* Access to SECCR or NSCR registers depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
| #else
 | |
|   reg_cr = &(FLASH_NS->NSCR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|   /* Set PG bit */
 | |
|   SET_BIT((*reg_cr), FLASH_CR_PG);
 | |
| 
 | |
|   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
 | |
|   primask_bit = __get_PRIMASK();
 | |
|   __disable_irq();
 | |
| 
 | |
|   /* Program the quad-word */
 | |
|   do
 | |
|   {
 | |
|     *dest_addr = *src_addr;
 | |
|     dest_addr++;
 | |
|     src_addr++;
 | |
|     index--;
 | |
|   } while (index != 0U);
 | |
| 
 | |
|   /* Exit critical section: restore previous priority mask */
 | |
|   __set_PRIMASK(primask_bit);
 | |
| }
 | |
| 
 | |
| #if defined (FLASH_SR_OBKERR)
 | |
| /**
 | |
|   * @brief  Program a quad-word (128-bit) of OBK at a specified address.
 | |
|   * @param  FlashAddress specifies the address to be programmed.
 | |
|   * @param  DataAddress specifies the address of data to be programmed.
 | |
|   * @retval None
 | |
|   */
 | |
| static void FLASH_Program_QuadWord_OBK(uint32_t FlashAddress, uint32_t DataAddress)
 | |
| {
 | |
|   uint8_t index = 4;
 | |
|   uint32_t *dest_addr = (uint32_t *)FlashAddress;
 | |
|   uint32_t *src_addr  = (uint32_t *)DataAddress;
 | |
|   uint32_t primask_bit;
 | |
|   __IO uint32_t *reg_cr;
 | |
|   __IO uint32_t *reg_obkcfgr;
 | |
| 
 | |
|   /* Access to SECCR or NSCR registers depends on operation type */
 | |
|   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
|   reg_obkcfgr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECOBKCFGR) : &(FLASH_NS->NSOBKCFGR);
 | |
| 
 | |
|   /* Set PG bit */
 | |
|   SET_BIT((*reg_cr), FLASH_CR_PG);
 | |
| 
 | |
|   /* Set ALT_SECT bit */
 | |
|   SET_BIT((*reg_obkcfgr), pFlash.ProcedureOnGoing & FLASH_OBKCFGR_ALT_SECT);
 | |
| 
 | |
|   /* Enter critical section: Disable interrupts to avoid any interruption during the loop */
 | |
|   primask_bit = __get_PRIMASK();
 | |
|   __disable_irq();
 | |
| 
 | |
|   /* Program the quad-word */
 | |
|   do
 | |
|   {
 | |
|     *dest_addr = *src_addr;
 | |
|     dest_addr++;
 | |
|     src_addr++;
 | |
|     index--;
 | |
|   } while (index != 0U);
 | |
| 
 | |
|   /* Exit critical section: restore previous priority mask */
 | |
|   __set_PRIMASK(primask_bit);
 | |
| }
 | |
| #endif /* FLASH_SR_OBKERR */
 | |
| 
 | |
| /**
 | |
|   * @brief  Program a half-word (16-bit) at a specified address.
 | |
|   * @param  FlashAddress specifies the address to be programmed.
 | |
|   * @param  DataAddress specifies the address of data to be programmed.
 | |
|   * @retval None
 | |
|   */
 | |
| static void FLASH_Program_HalfWord(uint32_t FlashAddress, uint32_t DataAddress)
 | |
| {
 | |
|   __IO uint32_t *reg_cr;
 | |
| 
 | |
|   /* Access to SECCR or NSCR registers depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
| #else
 | |
|   reg_cr = &(FLASH_NS->NSCR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|   /* Set HalfWord_PG bit */
 | |
|   SET_BIT((*reg_cr), FLASH_CR_PG);
 | |
| 
 | |
|   /* Program a halfword word (16 bits) */
 | |
|   *(__IO uint16_t *)FlashAddress = *(__IO uint16_t *)DataAddress;
 | |
| }
 | |
| 
 | |
| #if defined(FLASH_EDATAR_EDATA_EN)
 | |
| /**
 | |
|   * @brief  Program a word (32-bit) at a specified address.
 | |
|   * @param  FlashAddress specifies the address to be programmed.
 | |
|   * @param  DataAddress specifies the address of data to be programmed.
 | |
|   * @retval None
 | |
|   */
 | |
| static void FLASH_Program_Word(uint32_t FlashAddress, uint32_t DataAddress)
 | |
| {
 | |
|   __IO uint32_t *reg_cr;
 | |
| 
 | |
|   /* Access to SECCR or NSCR registers depends on operation type */
 | |
| #if defined (FLASH_OPTSR2_TZEN)
 | |
|   reg_cr = IS_FLASH_SECURE_OPERATION() ? &(FLASH->SECCR) : &(FLASH_NS->NSCR);
 | |
| #else
 | |
|   reg_cr = &(FLASH_NS->NSCR);
 | |
| #endif /* FLASH_OPTSR2_TZEN */
 | |
| 
 | |
|   /* Set PG bit */
 | |
|   SET_BIT((*reg_cr), FLASH_CR_PG);
 | |
| 
 | |
|     *(__IO uint32_t *)FlashAddress = *(__IO uint32_t *)DataAddress;
 | |
| }
 | |
| #endif /* FLASH_EDATAR_EDATA_EN */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| #endif /* HAL_FLASH_MODULE_ENABLED */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 |