/** ****************************************************************************** * @file STM32F4xx_IAP/src/flash_if.c * @author MCD Application Team * @version V1.0.0 * @date 10-October-2011 * @brief This file provides all the memory related operation functions. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *

© COPYRIGHT 2011 STMicroelectronics

****************************************************************************** */ /** @addtogroup STM32F4xx_IAP * @{ */ /* Includes ------------------------------------------------------------------*/ #include "flash_if.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ static uint32_t GetSector(uint32_t Address); /* Private functions ---------------------------------------------------------*/ /** * @brief Unlocks Flash for write access * @param None * @retval None */ void FLASH_If_Init(void) { HAL_FLASH_Unlock(); /* 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_PGSERR); } /** * @brief This function does an erase of all user flash area * @param StartSector: start of user flash area * @retval 0: user flash area successfully erased * 1: error occurred */ uint32_t FLASH_If_Erase(uint32_t StartSector) { uint32_t UserStartSector; uint32_t SectorError; FLASH_EraseInitTypeDef pEraseInit; /* Unlock the Flash to enable the flash control register access *************/ /* Get the sector where start the user flash area */ UserStartSector = GetSector(APPLICATION_ADDRESS); pEraseInit.TypeErase = TYPEERASE_SECTORS; pEraseInit.Sector = UserStartSector; pEraseInit.NbSectors = GetSector(USER_FLASH_END_ADDRESS)-UserStartSector+1 ; pEraseInit.VoltageRange = VOLTAGE_RANGE_3; if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK) { /* Error occurred while page erase */ return (1); } return (0); } /** * @brief This function erase one sector * @param StartSector: start of user flash area * @retval 0: user flash area successfully erased * 1: error occurred */ uint32_t FLASH_If_Erase_One_Sector(uint32_t StartSector) { uint32_t SectorError; FLASH_EraseInitTypeDef pEraseInit; pEraseInit.TypeErase = TYPEERASE_SECTORS; pEraseInit.Sector = StartSector; pEraseInit.NbSectors = 1 ; pEraseInit.VoltageRange = VOLTAGE_RANGE_3; if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK) { /* Error occurred while page erase */ return (1); } return (0); } /** * @brief This function writes a data buffer in flash (data are 32-bit aligned). * @note After writing data buffer, the flash content is checked. * @param FlashAddress: start address for writing data buffer * @param Data: pointer on data buffer * @param DataLength: length of data buffer (unit is 32-bit word) * @retval 0: Data successfully written to Flash memory * 1: Error occurred while writing data in Flash memory * 2: Written Data in flash memory is different from expected one */ uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength) { uint32_t i = 0; for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++) { /* Device voltage range supposed to be [2.7V to 3.6V], the operation will be done by word */ FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i)); /* Check the written value */ if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i)) { /* Flash content doesn't match SRAM content */ return(2); } /* Increment FLASH destination address */ *FlashAddress += 4; } return (0); } /** * @brief Returns the write protection status of user flash area. * @param None * @retval 0: No write protected sectors inside the user flash area * 1: Some sectors inside the user flash area are write protected */ uint16_t FLASH_If_GetWriteProtectionStatus(void) { uint32_t UserStartSector = FLASH_SECTOR_1; /* Get the sector where start the user flash area */ UserStartSector = GetSector(APPLICATION_ADDRESS); /* Check if there are write protected sectors inside the user flash area */ if ((*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS) >> (UserStartSector/8)) == (0xFFF >> (UserStartSector/8))) { /* No write protected sectors inside the user flash area */ return 1; } else { /* Some sectors inside the user flash area are write protected */ return 0; } } /** * @brief Disables the write protection of user flash area. * @param None * @retval 1: Write Protection successfully disabled * 2: Error: Flash write unprotection failed */ uint32_t FLASH_If_DisableWriteProtection(void) { __IO uint32_t UserStartSector = FLASH_SECTOR_1, UserWrpSectors = OB_WRP_SECTOR_1; /* Get the sector where start the user flash area */ UserStartSector = GetSector(APPLICATION_ADDRESS); /* Mark all sectors inside the user flash area as non protected */ UserWrpSectors = 0xFFF-((1 << (UserStartSector/8))-1); /* Unlock the Option Bytes */ HAL_FLASH_Unlock(); /* Disable the write protection for all sectors inside the user flash area */ FLASH_OB_DisableWRP(UserWrpSectors, FLASH_BANK_1); /* Start the Option Bytes programming process. */ if (HAL_FLASH_OB_Launch( ) != HAL_OK) { /* Error: Flash write unprotection failed */ return (2); } /* Write Protection successfully disabled */ return (1); } /** * @brief Gets the sector of a given address * @param Address: Flash address * @retval The sector of a given address */ static uint32_t GetSector(uint32_t Address) { uint32_t sector = 0; if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) { sector = FLASH_SECTOR_0; } else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) { sector = FLASH_SECTOR_1; } else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) { sector = FLASH_SECTOR_2; } else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) { sector = FLASH_SECTOR_3; } else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) { sector = FLASH_SECTOR_4; } else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) { sector = FLASH_SECTOR_5; } else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) { sector = FLASH_SECTOR_6; } else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_7))*/ { sector = FLASH_SECTOR_7; } // else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) // { // sector = FLASH_SECTOR_7; // } // else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) // { // sector = FLASH_SECTOR_8; // } // else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) // { // sector = FLASH_SECTOR_9; // } // else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) // { // sector = FLASH_SECTOR_10; // } // else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/ // { // sector = FLASH_SECTOR_11; // } return sector; } HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_OB_WRP_SECTOR(WRPSector)); assert_param(IS_FLASH_BANK(Banks)); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(50000); if(status == HAL_OK) { *(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector; } return status; } void FLASH_ProgramWord(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 */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= FLASH_PSIZE_WORD; FLASH->CR |= FLASH_CR_PG; *(__IO uint32_t*)Address = Data; } /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/