123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- /**
- ******************************************************************************
- * @file IAP/IAP_Main/Src/flash_if.c
- * @author MCD Application Team
- * @brief This file provides all the memory related operation functions.
- ******************************************************************************
- * @attention
- *
- * <h2><center>© Copyright (c) 2017 STMicroelectronics International N.V.
- * All rights reserved.</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted, provided that the following conditions are met:
- *
- * 1. Redistribution of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of other
- * contributors to this software may be used to endorse or promote products
- * derived from this software without specific written permission.
- * 4. This software, including modifications and/or derivative works of this
- * software, must execute solely and exclusively on microcontroller or
- * microprocessor devices manufactured by or for STMicroelectronics.
- * 5. Redistribution and use of this software other than as permitted under
- * this license is void and will automatically terminate your rights under
- * this license.
- *
- * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
- * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
- * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
- /** @addtogroup STM32F4xx_IAP_Main
- * @{
- */
- /* Includes ------------------------------------------------------------------*/
- #include "flash_if.h"
- #include "usart.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 NumberOfSector)
- {
- uint32_t UserStartSector;
- uint32_t SectorError;
- FLASH_EraseInitTypeDef pEraseInit;
- /* Unlock the Flash to enable the flash control register access *************/
- FLASH_If_Init();
-
- /* Get the sector where start the user flash area */
- UserStartSector = GetSector(StartSector);
-
- pEraseInit.TypeErase = TYPEERASE_SECTORS;
- pEraseInit.Sector = UserStartSector;
- pEraseInit.NbSectors = NumberOfSector;
- 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(uint32_t FlashAddress, uint32_t* Data ,uint32_t DataLength)
- {
- uint32_t i = 0;
- for (i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDRESS-0)); i++)
- {
- /* Device voltage range supposed to be [2.7V to 3.6V], the operation will
- be done by word */
- if (HAL_FLASH_Program(TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(Data+i)) == HAL_OK)
- {
- /* Check the written value */
- if (*(uint32_t*)FlashAddress != *(uint32_t*)(Data+i))
- {
- /* Flash content doesn't match SRAM content */
- return(FLASHIF_WRITINGCTRL_ERROR);
- }
- /* Increment FLASH destination address */
- FlashAddress += 4;
- }
- else
- {
- /* Error occurred while writing data in Flash memory */
- return (FLASHIF_WRITING_ERROR);
- }
- }
- return (FLASHIF_OK);
- }
- /**
- * @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 ProtectedSECTOR = 0xFFF;
- FLASH_OBProgramInitTypeDef OptionsBytesStruct;
- /* Unlock the Flash to enable the flash control register access *************/
- HAL_FLASH_Unlock();
- /* Check if there are write protected sectors inside the user flash area ****/
- HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) *********/
- HAL_FLASH_Lock();
- /* Get pages already write protected ****************************************/
- ProtectedSECTOR = ~(OptionsBytesStruct.WRPSector) & FLASH_SECTOR_TO_BE_PROTECTED;
- /* Check if desired pages are already write protected ***********************/
- if(ProtectedSECTOR != 0)
- {
- /* Some sectors inside the user flash area are write protected */
- return FLASHIF_PROTECTION_WRPENABLED;
- }
- else
- {
- /* No write protected sectors inside the user flash area */
- return FLASHIF_PROTECTION_NONE;
- }
- }
- /**
- * @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 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;
- }
- /**
- * @brief Configure the write protection status of user flash area.
- * @param modifier DISABLE or ENABLE the protection
- * @retval HAL_StatusTypeDef HAL_OK if change is applied.
- */
- HAL_StatusTypeDef FLASH_If_WriteProtectionConfig(uint32_t modifier)
- {
- uint32_t ProtectedSECTOR = 0xFFF;
- FLASH_OBProgramInitTypeDef config_new, config_old;
- HAL_StatusTypeDef result = HAL_OK;
-
- /* Get pages write protection status ****************************************/
- HAL_FLASHEx_OBGetConfig(&config_old);
- /* The parameter says whether we turn the protection on or off */
- config_new.WRPState = modifier;
- /* We want to modify only the Write protection */
- config_new.OptionType = OPTIONBYTE_WRP;
-
- /* No read protection, keep BOR and reset settings */
- config_new.RDPLevel = OB_RDP_LEVEL_0;
- config_new.USERConfig = config_old.USERConfig;
- /* Get pages already write protected ****************************************/
- ProtectedSECTOR = config_old.WRPSector | FLASH_SECTOR_TO_BE_PROTECTED;
- /* Unlock the Flash to enable the flash control register access *************/
- HAL_FLASH_Unlock();
- /* Unlock the Options Bytes *************************************************/
- HAL_FLASH_OB_Unlock();
-
- config_new.WRPSector = ProtectedSECTOR;
- result = HAL_FLASHEx_OBProgram(&config_new);
-
- return result;
- }
- //================================================
- // Phihong IAP custom routine
- //================================================
- uint8_t PH_CalNewCodeChecksum(void)
- {
- uint32_t CheckSum=0;
- __IO uint32_t flashdestination = NEW_CODE_ADDRESS;
-
- for(uint32_t i=0;i<0x60000;i++)
- {
- CheckSum += (*(uint16_t *)(flashdestination+i));
- }
-
- #ifdef DEBUG
- DEBUG_INFO("\r\nChecksum = 0x%X", CheckSum);
- #endif
-
- if(CheckSum == *(uint16_t *)0x080fffff)
- {
- return(1);
- }
- else
- {
- return(0);
- }
- }
- uint8_t PH_isMoveOK(void)
- {
- uint8_t isSuccess = 1;
-
- //__IO uint32_t flashdestination = APPLICATION_ADDRESS;
- //__IO uint32_t newdestination = NEW_CODE_ADDRESS;
- uint32_t flashdestination = APPLICATION_ADDRESS;
- uint32_t newdestination = NEW_CODE_ADDRESS;
-
- for(uint32_t i=0;i<0x60000;i++)
- {
- HAL_IWDG_Refresh(&hiwdg);
- if((*((uint8_t *)newdestination++)) != (*((uint8_t *)flashdestination++)))
- {
- isSuccess = 0;
- }
- }
-
- #ifdef DEBUG
- if(isSuccess)
- DEBUG_INFO("Move code compare OK...\r\n");
- else
- DEBUG_INFO("Move code compare fail...\r\n");
- #endif
-
- return isSuccess;
- }
- void PH_ClearUpgradeReq(void)
- {
- FLASH_If_Erase(UPGRADE_REQ_ADDRESS, 1);
- #ifdef DEBUG
- DEBUG_INFO("Clean firmware upgrade request flag...\r\n");
- #endif
- }
- uint8_t PH_isUpgradeReq(void)
- {
- uint8_t isSuccess = 0;
- __IO uint32_t flashdestination = UPGRADE_REQ_ADDRESS;
-
- if(*((uint32_t *)flashdestination) == 0x0aa55aa55)
- {
- #ifdef DEBUG
- DEBUG_INFO("Firmware upgrade request detect...\r\n");
- #endif
- isSuccess = 1;
- }
- else if(*((uint32_t *)flashdestination) != 0x0ffffffff)
- {
- PH_ClearUpgradeReq();
- }
- else
- {
- #ifdef DEBUG
- DEBUG_INFO("Firmware upgrade request does not detect...\r\n");
- #endif
- }
-
- return isSuccess;
- }
- void PH_MoveCode2Ap(void)
- {
- uint32_t packet_length = 0x10000;
- uint8_t flag_flash_write_err = 0;
-
- //__IO uint32_t flashdestination = APPLICATION_ADDRESS;
- //__IO uint32_t newdestination = NEW_CODE_ADDRESS;
- uint32_t flashdestination = APPLICATION_ADDRESS;
- uint32_t newdestination = NEW_CODE_ADDRESS;
-
- FLASH_If_Erase(ADDR_FLASH_SECTOR_6, 3);
- #ifdef DEBUG
- DEBUG_INFO("AP flash(0x8040000 erase finish\r\n");
- DEBUG_INFO("Move flash data form 0x80A0000( length 0x60000) to 0x8040000");
- #endif
- for(uint32_t i=0;i<6;i++)
- {
- if ((FLASH_If_Write(flashdestination, (uint32_t*) newdestination, packet_length/4)) == FLASHIF_OK)
- {
- flashdestination += packet_length;
- newdestination += packet_length;
- #ifdef DEBUG
- DEBUG_INFO(".");
- if(i==5)
- DEBUG_INFO("\r\n");
- #endif
- }
- else
- {
- #ifdef DEBUG
- DEBUG_INFO("Fail\r\n");
- #endif
- flag_flash_write_err = 1;
- }
- }
-
- //CalNewCodeChecksum();
- if(!PH_isMoveOK())
- {
- flag_flash_write_err = 1;
- }
-
- if(!flag_flash_write_err)
- {
- PH_ClearUpgradeReq();
- #ifdef DEBUG
- DEBUG_INFO("Upgrade finish, MCU reboot...\r\n");
- #endif
- NVIC_SystemReset();
- }
- }
- /**
- * @}
- */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|