| /** |
| ****************************************************************************** |
| * @file stm32f7xx_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 |
| * |
| @verbatim |
| ============================================================================== |
| ##### FLASH peripheral features ##### |
| ============================================================================== |
| |
| [..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses |
| to the Flash memory. It implements the erase and program Flash memory operations |
| and the read and write protection mechanisms. |
| |
| [..] The Flash memory interface accelerates code execution with a system of instruction |
| prefetch and cache lines. |
| |
| [..] The FLASH main features are: |
| (+) Flash memory read operations |
| (+) Flash memory program/erase operations |
| (+) Read / write protections |
| (+) Prefetch on I-Code |
| (+) 64 cache lines of 128 bits on I-Code |
| (+) 8 cache lines of 128 bits on D-Code |
| |
| ##### How to use this driver ##### |
| ============================================================================== |
| [..] |
| This driver provides functions and macros to configure and program the FLASH |
| memory of all STM32F7xx devices. |
| |
| (#) FLASH Memory IO Programming functions: |
| (++) Lock and Unlock the FLASH interface using HAL_FLASH_Unlock() and |
| HAL_FLASH_Lock() functions |
| (++) Program functions: byte, half word, word and double word |
| (++) 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() |
| (++) Wait for last FLASH operation according to its status |
| (++) Get error flag status by calling HAL_SetErrorCode() |
| [..] |
| In addition to these functions, this driver includes a set of macros allowing |
| to handle the following operations: |
| (+) Set the latency |
| (+) Enable/Disable the prefetch buffer |
| (+) Enable/Disable the Instruction cache and the Data cache |
| (+) Reset the Instruction cache and the Data cache |
| (+) Enable/Disable the FLASH interrupts |
| (+) Monitor the FLASH flags status |
| [..] |
| (@) For any Flash memory program operation (erase or program), the CPU clock frequency |
| (HCLK) must be at least 1MHz. |
| (@) The contents of the Flash memory are not guaranteed if a device reset occurs during |
| a Flash memory operation. |
| (@) Any attempt to read the Flash memory while it is being written or erased, causes the |
| bus to stall. Read operations are processed correctly once the program operation has |
| completed. This means that code or data fetches cannot be performed while a write/erase |
| operation is ongoing. |
| |
| @endverbatim |
| ****************************************************************************** |
| * @attention |
| * |
| * Copyright (c) 2017 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. |
| ****************************************************************************** |
| */ |
| |
| /* Includes ------------------------------------------------------------------*/ |
| #include "stm32f7xx_hal.h" |
| |
| /** @addtogroup STM32F7xx_HAL_Driver |
| * @{ |
| */ |
| |
| /** @defgroup FLASH FLASH |
| * @brief FLASH HAL module driver |
| * @{ |
| */ |
| |
| #ifdef HAL_FLASH_MODULE_ENABLED |
| |
| /* Private typedef -----------------------------------------------------------*/ |
| /* Private define ------------------------------------------------------------*/ |
| /** @addtogroup FLASH_Private_Constants |
| * @{ |
| */ |
| #define SECTOR_MASK ((uint32_t)0xFFFFFF07U) |
| #define FLASH_TIMEOUT_VALUE ((uint32_t)50000U)/* 50 s */ |
| /** |
| * @} |
| */ |
| /* Private macro -------------------------------------------------------------*/ |
| /* Private variables ---------------------------------------------------------*/ |
| /** @addtogroup FLASH_Private_Variables |
| * @{ |
| */ |
| /* Variable used for Erase sectors under interruption */ |
| FLASH_ProcessTypeDef pFlash; |
| /** |
| * @} |
| */ |
| |
| /* Private function prototypes -----------------------------------------------*/ |
| /** @addtogroup FLASH_Private_Functions |
| * @{ |
| */ |
| /* Program operations */ |
| static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data); |
| static void FLASH_Program_Word(uint32_t Address, uint32_t Data); |
| static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data); |
| static void FLASH_Program_Byte(uint32_t Address, uint8_t Data); |
| static void FLASH_SetErrorCode(void); |
| |
| HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout); |
| /** |
| * @} |
| */ |
| |
| /* 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 byte, halfword, word or double 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 Address specifies the address to be programmed. |
| * @param Data specifies the data to be programmed |
| * |
| * @retval HAL_StatusTypeDef HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) |
| { |
| HAL_StatusTypeDef status = HAL_ERROR; |
| |
| /* Process Locked */ |
| __HAL_LOCK(&pFlash); |
| |
| /* Check the parameters */ |
| assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); |
| |
| /* Wait for last operation to be completed */ |
| status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); |
| |
| if(status == HAL_OK) |
| { |
| switch(TypeProgram) |
| { |
| case FLASH_TYPEPROGRAM_BYTE : |
| { |
| /*Program byte (8-bit) at a specified address.*/ |
| FLASH_Program_Byte(Address, (uint8_t) Data); |
| break; |
| } |
| |
| case FLASH_TYPEPROGRAM_HALFWORD : |
| { |
| /*Program halfword (16-bit) at a specified address.*/ |
| FLASH_Program_HalfWord(Address, (uint16_t) Data); |
| break; |
| } |
| |
| case FLASH_TYPEPROGRAM_WORD : |
| { |
| /*Program word (32-bit) at a specified address.*/ |
| FLASH_Program_Word(Address, (uint32_t) Data); |
| break; |
| } |
| |
| case FLASH_TYPEPROGRAM_DOUBLEWORD : |
| { |
| /*Program double word (64-bit) at a specified address.*/ |
| FLASH_Program_DoubleWord(Address, Data); |
| break; |
| } |
| default : |
| break; |
| } |
| /* Wait for last operation to be completed */ |
| status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE); |
| |
| /* If the program operation is completed, disable the PG Bit */ |
| FLASH->CR &= (~FLASH_CR_PG); |
| } |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(&pFlash); |
| |
| return status; |
| } |
| |
| /** |
| * @brief Program byte, halfword, word or double 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 Address specifies the address to be programmed. |
| * @param Data specifies the data to be programmed |
| * |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Process Locked */ |
| __HAL_LOCK(&pFlash); |
| |
| /* Check the parameters */ |
| assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram)); |
| |
| /* Enable End of FLASH Operation interrupt */ |
| __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP); |
| |
| /* Enable Error source interrupt */ |
| __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR); |
| |
| /* Clear pending flags (if any) */ |
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\ |
| FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_ERSERR); |
| |
| pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM; |
| pFlash.Address = Address; |
| |
| switch(TypeProgram) |
| { |
| case FLASH_TYPEPROGRAM_BYTE : |
| { |
| /*Program byte (8-bit) at a specified address.*/ |
| FLASH_Program_Byte(Address, (uint8_t) Data); |
| break; |
| } |
| |
| case FLASH_TYPEPROGRAM_HALFWORD : |
| { |
| /*Program halfword (16-bit) at a specified address.*/ |
| FLASH_Program_HalfWord(Address, (uint16_t) Data); |
| break; |
| } |
| |
| case FLASH_TYPEPROGRAM_WORD : |
| { |
| /*Program word (32-bit) at a specified address.*/ |
| FLASH_Program_Word(Address, (uint32_t) Data); |
| break; |
| } |
| |
| case FLASH_TYPEPROGRAM_DOUBLEWORD : |
| { |
| /*Program double word (64-bit) at a specified address.*/ |
| FLASH_Program_DoubleWord(Address, Data); |
| break; |
| } |
| default : |
| break; |
| } |
| return status; |
| } |
| |
| /** |
| * @brief This function handles FLASH interrupt request. |
| * @retval None |
| */ |
| void HAL_FLASH_IRQHandler(void) |
| { |
| uint32_t temp = 0; |
| |
| /* If the program operation is completed, disable the PG Bit */ |
| FLASH->CR &= (~FLASH_CR_PG); |
| |
| /* If the erase operation is completed, disable the SER Bit */ |
| FLASH->CR &= (~FLASH_CR_SER); |
| FLASH->CR &= SECTOR_MASK; |
| |
| /* if the erase operation is completed, disable the MER Bit */ |
| FLASH->CR &= (~FLASH_MER_BIT); |
| |
| /* Check FLASH End of Operation flag */ |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) |
| { |
| /* Clear FLASH End of Operation pending bit */ |
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
| |
| switch (pFlash.ProcedureOnGoing) |
| { |
| case FLASH_PROC_SECTERASE : |
| { |
| /* Nb of sector to erased can be decreased */ |
| pFlash.NbSectorsToErase--; |
| |
| /* Check if there are still sectors to erase */ |
| if(pFlash.NbSectorsToErase != 0) |
| { |
| temp = pFlash.Sector; |
| /* Indicate user which sector has been erased */ |
| HAL_FLASH_EndOfOperationCallback(temp); |
| |
| /* Increment sector number */ |
| temp = ++pFlash.Sector; |
| FLASH_Erase_Sector(temp, pFlash.VoltageForErase); |
| } |
| else |
| { |
| /* No more sectors to Erase, user callback can be called.*/ |
| /* Reset Sector and stop Erase sectors procedure */ |
| pFlash.Sector = temp = 0xFFFFFFFFU; |
| /* FLASH EOP interrupt user callback */ |
| HAL_FLASH_EndOfOperationCallback(temp); |
| /* Sector Erase procedure is completed */ |
| pFlash.ProcedureOnGoing = FLASH_PROC_NONE; |
| } |
| break; |
| } |
| |
| case FLASH_PROC_MASSERASE : |
| { |
| /* MassErase ended. Return the selected bank : in this product we don't have Banks */ |
| /* FLASH EOP interrupt user callback */ |
| HAL_FLASH_EndOfOperationCallback(0); |
| /* MAss Erase procedure is completed */ |
| pFlash.ProcedureOnGoing = FLASH_PROC_NONE; |
| break; |
| } |
| |
| case FLASH_PROC_PROGRAM : |
| { |
| /*Program ended. Return the selected address*/ |
| /* FLASH EOP interrupt user callback */ |
| HAL_FLASH_EndOfOperationCallback(pFlash.Address); |
| /* Programming procedure is completed */ |
| pFlash.ProcedureOnGoing = FLASH_PROC_NONE; |
| break; |
| } |
| default : |
| break; |
| } |
| } |
| |
| /* Check FLASH operation error flags */ |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ALL_ERRORS) != RESET) |
| { |
| switch (pFlash.ProcedureOnGoing) |
| { |
| case FLASH_PROC_SECTERASE : |
| { |
| /* return the faulty sector */ |
| temp = pFlash.Sector; |
| pFlash.Sector = 0xFFFFFFFFU; |
| break; |
| } |
| case FLASH_PROC_MASSERASE : |
| { |
| /* No return in case of Mass Erase */ |
| temp = 0; |
| break; |
| } |
| case FLASH_PROC_PROGRAM : |
| { |
| /*return the faulty address*/ |
| temp = pFlash.Address; |
| break; |
| } |
| default : |
| break; |
| } |
| /*Save the Error code*/ |
| FLASH_SetErrorCode(); |
| |
| /* FLASH error interrupt user callback */ |
| HAL_FLASH_OperationErrorCallback(temp); |
| |
| /*Stop the procedure ongoing */ |
| pFlash.ProcedureOnGoing = FLASH_PROC_NONE; |
| } |
| |
| if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE) |
| { |
| /* Disable End of FLASH Operation interrupt */ |
| __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP); |
| |
| /* Disable Error source interrupt */ |
| __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR); |
| |
| /* Process Unlocked */ |
| __HAL_UNLOCK(&pFlash); |
| } |
| |
| } |
| |
| /** |
| * @brief FLASH end of operation interrupt callback |
| * @param ReturnValue The value saved in this parameter depends on the ongoing procedure |
| * - 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 |
| * - Mass Erase : No return value expected |
| * @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 |
| * - 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 |
| * - Mass Erase : No return value expected |
| * @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 register access |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASH_Unlock(void) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) |
| { |
| /* Authorize the FLASH Registers access */ |
| WRITE_REG(FLASH->KEYR, FLASH_KEY1); |
| WRITE_REG(FLASH->KEYR, FLASH_KEY2); |
| |
| /* Verify Flash is unlocked */ |
| if(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET) |
| { |
| status = HAL_ERROR; |
| } |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Locks the FLASH control register access |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASH_Lock(void) |
| { |
| /* Set the LOCK Bit to lock the FLASH Registers access */ |
| FLASH->CR |= FLASH_CR_LOCK; |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Unlock the FLASH Option Control Registers access. |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void) |
| { |
| if((FLASH->OPTCR & FLASH_OPTCR_OPTLOCK) != RESET) |
| { |
| /* Authorizes the Option Byte register programming */ |
| FLASH->OPTKEYR = FLASH_OPT_KEY1; |
| FLASH->OPTKEYR = FLASH_OPT_KEY2; |
| } |
| else |
| { |
| 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 */ |
| FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK; |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Launch the option byte loading. |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef HAL_FLASH_OB_Launch(void) |
| { |
| /* Set the OPTSTRT bit in OPTCR register */ |
| FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT; |
| |
| /* Wait for last operation to be completed */ |
| return(FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE)); |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @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 FLASH_ErrorCode: The returned value can be: |
| * @arg FLASH_ERROR_ERS: FLASH Erasing Sequence error flag |
| * @arg FLASH_ERROR_PGP: FLASH Programming Parallelism error flag |
| * @arg FLASH_ERROR_PGA: FLASH Programming Alignment error flag |
| * @arg FLASH_ERROR_WRP: FLASH Write protected error flag |
| * @arg FLASH_ERROR_OPERATION: FLASH operation Error flag |
| */ |
| uint32_t HAL_FLASH_GetError(void) |
| { |
| return pFlash.ErrorCode; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @brief Wait for a FLASH operation to complete. |
| * @param Timeout maximum flash operationtimeout |
| * @retval HAL Status |
| */ |
| HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout) |
| { |
| uint32_t tickstart = 0; |
| |
| /* Clear Error Code */ |
| pFlash.ErrorCode = HAL_FLASH_ERROR_NONE; |
| |
| /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset. |
| Even if the FLASH operation fails, the BUSY flag will be reset and an error |
| flag will be set */ |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) |
| { |
| if(Timeout != HAL_MAX_DELAY) |
| { |
| if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) |
| { |
| return HAL_TIMEOUT; |
| } |
| } |
| } |
| |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ALL_ERRORS) != RESET) |
| { |
| /*Save the error code*/ |
| FLASH_SetErrorCode(); |
| return HAL_ERROR; |
| } |
| |
| /* Check FLASH End of Operation flag */ |
| if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET) |
| { |
| /* Clear FLASH End of Operation pending bit */ |
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); |
| } |
| |
| /* If there is an error flag set */ |
| return HAL_OK; |
| |
| } |
| |
| /** |
| * @brief Program a double word (64-bit) at a specified address. |
| * @note This function must be used when the device voltage range is from |
| * 2.7V to 3.6V and an External Vpp is present. |
| * |
| * @note If an erase and a program operations are requested simultaneously, |
| * the erase operation is performed before the program one. |
| * |
| * @param Address specifies the address to be programmed. |
| * @param Data specifies the data to be programmed. |
| * @retval None |
| */ |
| static void FLASH_Program_DoubleWord(uint32_t Address, uint64_t Data) |
| { |
| /* Check the parameters */ |
| assert_param(IS_FLASH_ADDRESS(Address)); |
| |
| /* If the previous operation is completed, proceed to program the new data */ |
| FLASH->CR &= CR_PSIZE_MASK; |
| FLASH->CR |= FLASH_PSIZE_DOUBLE_WORD; |
| FLASH->CR |= FLASH_CR_PG; |
| |
| /* Program first word */ |
| *(__IO uint32_t*)Address = (uint32_t)Data; |
| /* Barrier to ensure programming is performed in 2 steps, in right order |
| (independently of compiler optimization behavior) */ |
| __ISB(); |
| |
| /* Program second word */ |
| *(__IO uint32_t*)(Address+4) = (uint32_t)(Data >> 32); |
| |
| /* Data synchronous Barrier (DSB) Just after the write operation |
| This will force the CPU to respect the sequence of instruction (no optimization).*/ |
| __DSB(); |
| } |
| |
| |
| /** |
| * @brief Program word (32-bit) at a specified address. |
| * @note This function must be used when the device voltage range is from |
| * 2.7V to 3.3V. |
| * |
| * @note If an erase and a program operations are requested simultaneously, |
| * the erase operation is performed before the program one. |
| * |
| * @param Address specifies the address to be programmed. |
| * @param Data specifies the data to be programmed. |
| * @retval None |
| */ |
| static void FLASH_Program_Word(uint32_t Address, uint32_t Data) |
| { |
| /* Check the parameters */ |
| assert_param(IS_FLASH_ADDRESS(Address)); |
| |
| /* If the previous operation is completed, proceed to program the new data */ |
| FLASH->CR &= CR_PSIZE_MASK; |
| FLASH->CR |= FLASH_PSIZE_WORD; |
| FLASH->CR |= FLASH_CR_PG; |
| |
| *(__IO uint32_t*)Address = Data; |
| |
| /* Data synchronous Barrier (DSB) Just after the write operation |
| This will force the CPU to respect the sequence of instruction (no optimization).*/ |
| __DSB(); |
| } |
| |
| /** |
| * @brief Program a half-word (16-bit) at a specified address. |
| * @note This function must be used when the device voltage range is from |
| * 2.1V to 3.6V. |
| * |
| * @note If an erase and a program operations are requested simultaneously, |
| * the erase operation is performed before the program one. |
| * |
| * @param Address specifies the address to be programmed. |
| * @param Data specifies the data to be programmed. |
| * @retval None |
| */ |
| static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data) |
| { |
| /* Check the parameters */ |
| assert_param(IS_FLASH_ADDRESS(Address)); |
| |
| /* If the previous operation is completed, proceed to program the new data */ |
| FLASH->CR &= CR_PSIZE_MASK; |
| FLASH->CR |= FLASH_PSIZE_HALF_WORD; |
| FLASH->CR |= FLASH_CR_PG; |
| |
| *(__IO uint16_t*)Address = Data; |
| |
| /* Data synchronous Barrier (DSB) Just after the write operation |
| This will force the CPU to respect the sequence of instruction (no optimization).*/ |
| __DSB(); |
| |
| } |
| |
| /** |
| * @brief Program byte (8-bit) at a specified address. |
| * @note This function must be used when the device voltage range is from |
| * 1.7V to 3.6V. |
| * |
| * @note If an erase and a program operations are requested simultaneously, |
| * the erase operation is performed before the program one. |
| * |
| * @param Address specifies the address to be programmed. |
| * @param Data specifies the data to be programmed. |
| * @retval None |
| */ |
| static void FLASH_Program_Byte(uint32_t Address, uint8_t Data) |
| { |
| /* Check the parameters */ |
| assert_param(IS_FLASH_ADDRESS(Address)); |
| |
| /* If the previous operation is completed, proceed to program the new data */ |
| FLASH->CR &= CR_PSIZE_MASK; |
| FLASH->CR |= FLASH_PSIZE_BYTE; |
| FLASH->CR |= FLASH_CR_PG; |
| |
| *(__IO uint8_t*)Address = Data; |
| |
| /* Data synchronous Barrier (DSB) Just after the write operation |
| This will force the CPU to respect the sequence of instruction (no optimization).*/ |
| __DSB(); |
| } |
| |
| /** |
| * @brief Set the specific FLASH error flag. |
| * @retval None |
| */ |
| static void FLASH_SetErrorCode(void) |
| { |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET) |
| { |
| pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION; |
| } |
| |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET) |
| { |
| pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP; |
| } |
| |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET) |
| { |
| pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA; |
| } |
| |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET) |
| { |
| pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP; |
| } |
| |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ERSERR) != RESET) |
| { |
| pFlash.ErrorCode |= HAL_FLASH_ERROR_ERS; |
| } |
| |
| #if defined (FLASH_OPTCR2_PCROP) |
| if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET) |
| { |
| pFlash.ErrorCode |= HAL_FLASH_ERROR_RD; |
| } |
| #endif /* FLASH_OPTCR2_PCROP */ |
| |
| /* Clear error programming flags */ |
| __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); |
| } |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* HAL_FLASH_MODULE_ENABLED */ |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |