| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- /**
- ******************************************************************************
- * @file FLASH.c
- * @author
- * @brief program the STM32F4xx FLASH.
- ******************************************************************************
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "flash.h"
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /*Variable used for Erase procedure*/
- uint8_t flashBuf[FLASH_BUFFER_SIZE] = {0};
- /* Private function prototypes -----------------------------------------------*/
- static uint32_t GetSector(uint32_t Address);
- static uint32_t GetSectorSize(uint32_t Sector);
- /* Private functions ---------------------------------------------------------*/
- /**
- * @brief program
- * @param None
- * @retval None
- */
- #if 0
- int ProgramFlashPage(uint32_t startAddress, uint32_t endAddress, uint32_t data)
- {
- uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0;
- uint32_t SectorError = 0;
- __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
- FLASH_EraseInitTypeDef EraseInitStruct;
- int retval=0;
- /* Unlock the Flash to enable the flash control register access *************/
- HAL_FLASH_Unlock();
- /* Get the 1st sector to erase */
- FirstSector = GetSector(startAddress);
- /* Get the number of sector to erase from 1st sector*/
- NbOfSectors = GetSector(endAddress) - FirstSector + 1;
- /* Fill EraseInit structure*/
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
- EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
- EraseInitStruct.Sector = FirstSector;
- EraseInitStruct.NbSectors = NbOfSectors;
- if(HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
- {
- /*
- Error occurred while sector erase.
- User can add here some code to deal with this error.
- SectorError will contain the faulty sector and then to know the code error on this sector,
- user can call function 'HAL_FLASH_GetError()'
- */
- retval = -1;
- }
- else
- {
- /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
- you have to make sure that these data are rewritten before they are accessed during code
- execution. If this cannot be done safely, it is recommended to flush the caches by setting the
- DCRST and ICRST bits in the FLASH_CR register. */
- __HAL_FLASH_DATA_CACHE_DISABLE();
- __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
- __HAL_FLASH_DATA_CACHE_RESET();
- __HAL_FLASH_INSTRUCTION_CACHE_RESET();
- __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
- __HAL_FLASH_DATA_CACHE_ENABLE();
- /* Program the user Flash area word by word ***********/
- Address = startAddress;
- while (Address < endAddress)
- {
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, data) == HAL_OK)
- {
- Address = Address + 4;
- }
- else
- {
- /* Error occurred while writing data in Flash memory.
- User can add here some code to deal with this error */
- retval = -2;
- }
- }
- }
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) *********/
- HAL_FLASH_Lock();
- if(retval==0)
- {
- /* Check if the programmed data is OK
- MemoryProgramStatus = 0: data programmed correctly
- MemoryProgramStatus != 0: number of words not programmed correctly ******/
- Address = startAddress;
- MemoryProgramStatus = 0;
- while (Address < endAddress)
- {
- data32 = *(__IO uint32_t*)Address;
- if (data32 != data)
- {
- MemoryProgramStatus++;
- }
- Address = Address + 4;
- }
- }
- /* Check if there is an issue to program data */
- if (MemoryProgramStatus == 0)
- {
- }
- else
- {
- retval = -3;
- }
- return retval;
- }
- #else
- int ProgramFlashPage(uint32_t startAddress, const uint8_t* data, uint32_t len)
- {
- uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0, endAddress = 0;
- uint32_t SectorError = 0;
- __IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
- uint32_t* pData = 0;
- FLASH_EraseInitTypeDef EraseInitStruct;
- int retval=0;
- HAL_StatusTypeDef status;
- Address = startAddress & (uint32_t)(~(FLASH_USER_PAGE_SIZE - 1));
- endAddress = (startAddress + len + sizeof(uint64_t) -1) & (uint32_t)(~(sizeof(uint64_t)-1));
- if( endAddress >= Address + FLASH_USER_PAGE_SIZE || FLASH_BUFFER_SIZE < len)//
- {
- return -1;
- }
- memcpy((void*)flashBuf, (void const*)Address, FLASH_BUFFER_SIZE);
- memcpy((void*)(flashBuf + (startAddress - Address)), (void const*)data, len);
- /* Unlock the Flash to enable the flash control register access *************/
- ClearFlashWriteProtect();
- HAL_FLASH_Unlock();
- /* Get the 1st sector to erase */
- FirstSector = GetSector(startAddress);
- /* Get the number of sector to erase from 1st sector*/
- //NbOfSectors = GetSector(endAddress) - FirstSector + 1;
- NbOfSectors = 1;
- /* Fill EraseInit structure*/
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
- EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
- EraseInitStruct.Sector = FirstSector;
- EraseInitStruct.NbSectors = NbOfSectors;
- status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
- if(status != HAL_OK)
- {
- /*
- Error occurred while sector erase.
- User can add here some code to deal with this error.
- SectorError will contain the faulty sector and then to know the code error on this sector,
- user can call function 'HAL_FLASH_GetError()'
- */
- retval = -1;
- }
- else
- {
- /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
- you have to make sure that these data are rewritten before they are accessed during code
- execution. If this cannot be done safely, it is recommended to flush the caches by setting the
- DCRST and ICRST bits in the FLASH_CR register. */
- __HAL_FLASH_DATA_CACHE_DISABLE();
- __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
- __HAL_FLASH_DATA_CACHE_RESET();
- __HAL_FLASH_INSTRUCTION_CACHE_RESET();
- __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
- __HAL_FLASH_DATA_CACHE_ENABLE();
- /* Program the user Flash area word by word ***********/
- Address = FLASH_USER_START_ADDR;
- endAddress = Address + FLASH_BUFFER_SIZE;
- pData = (uint32_t*)flashBuf;
- while (Address < endAddress)
- {
- status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, *pData);
- if (status == HAL_OK)
- {
- Address = Address + 4;
- pData++;
- }
- else
- {
- /* Error occurred while writing data in Flash memory.
- User can add here some code to deal with this error */
- retval = -2;
- break;
- }
- }
- }
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) *********/
- SetFlashWriteProtect();
- if(retval==0)
- {
- /* Check if the programmed data is OK
- MemoryProgramStatus = 0: data programmed correctly
- MemoryProgramStatus != 0: number of words not programmed correctly ******/
- Address = FLASH_USER_START_ADDR;
- pData = (uint32_t*)flashBuf;
- MemoryProgramStatus = 0;
- while (Address < endAddress)
- {
- data32 = *(__IO uint32_t*)Address;
- if (data32 != *pData)
- {
- MemoryProgramStatus++;
- }
- Address = Address + 4;
- pData++;
- }
- /* Check if there is an issue to program data */
- if (MemoryProgramStatus == 0)
- {
- retval = 0;
- }
- else
- {
- retval = -3;
- }
- }
- return retval;
- }
- #endif
- int EraseFlashProgram(uint32_t startAddress, uint32_t length)
- {
- uint32_t FirstSector = 0, NbOfSectors = 0;
- uint32_t SectorError = 0,endAddress=0;
- FLASH_EraseInitTypeDef EraseInitStruct;
- int retval=0;
- HAL_StatusTypeDef status;
- /* Unlock the Flash to enable the flash control register access *************/
- HAL_FLASH_Unlock();
- /* Get the 1st sector to erase */
- FirstSector = GetSector(startAddress);
- /* Get the number of sector to erase from 1st sector*/
- endAddress = startAddress + length;
- NbOfSectors = GetSector(endAddress) - FirstSector + 1;
- /* Fill EraseInit structure*/
- EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
- EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
- EraseInitStruct.Sector = FirstSector;
- EraseInitStruct.NbSectors = NbOfSectors;
- status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
- if(HAL_OK != status)
- {
- /*
- Error occurred while sector erase.
- User can add here some code to deal with this error.
- SectorError will contain the faulty sector and then to know the code error on this sector,
- user can call function 'HAL_FLASH_GetError()'
- */
- retval = -1;
- }
- else
- {
- retval = 1;
- }
- return retval;
- }
- int WriteData2FlashProgram(uint32_t startAddress, const uint8_t* data, uint32_t length)
- {
- int retval = 1;
- uint32_t endAddress = startAddress + length, curAddress = startAddress;
- uint32_t* pData = (uint32_t*)data;
- /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
- you have to make sure that these data are rewritten before they are accessed during code
- execution. If this cannot be done safely, it is recommended to flush the caches by setting the
- DCRST and ICRST bits in the FLASH_CR register. */
- __HAL_FLASH_DATA_CACHE_DISABLE();
- __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
- __HAL_FLASH_DATA_CACHE_RESET();
- __HAL_FLASH_INSTRUCTION_CACHE_RESET();
- __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
- __HAL_FLASH_DATA_CACHE_ENABLE();
- /* Program the user Flash area word by word ***********/
- while (curAddress < endAddress)
- {
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, curAddress, *pData) == HAL_OK)
- {
- curAddress += sizeof(uint32_t);
- pData++;
- }
- else
- {
- /* Error occurred while writing data in Flash memory.
- User can add here some code to deal with this error */
- retval = -2;
- }
- }
- return retval;;
- }
- int FinishFlashProgram(uint32_t startAddress, uint32_t length)
- {
- int retval = 1;
- /* Lock the Flash to disable the flash control register access (recommended
- to protect the FLASH memory against possible unwanted operation) *********/
- HAL_FLASH_Lock();
- return retval;
- }
- /**
- * @brief Gets the sector of a given address
- * @param None
- * @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 Gets sector Size
- * @param None
- * @retval The size of a given sector
- */
- static uint32_t GetSectorSize(uint32_t Sector)
- {
- uint32_t sectorsize = 0x00;
- if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3))
- {
- sectorsize = 16 * 1024;
- }
- else if(Sector == FLASH_SECTOR_4)
- {
- sectorsize = 64 * 1024;
- }
- else
- {
- sectorsize = 128 * 1024;
- }
- return sectorsize;
- }
- void SetFlashReadProtect(void)
- {
- FLASH_OBProgramInitTypeDef OBInit={0};
- HAL_FLASHEx_OBGetConfig(&OBInit);
- if(OB_RDP_LEVEL_0 == OBInit.RDPLevel)
- {
- OBInit.OptionType = OPTIONBYTE_RDP;
- OBInit.RDPLevel = OB_RDP_LEVEL_1;
- /* Allow Access to option bytes sector */
- HAL_FLASH_OB_Unlock();
- /* Allow Access to Flash control registers and user Flash */
- HAL_FLASH_Unlock();
- HAL_FLASHEx_OBProgram(&OBInit);
- /* Prevent Access to option bytes sector */
- HAL_FLASH_OB_Lock();
- /* Disable the Flash option control register access (recommended to protect
- the option Bytes against possible unwanted operations) */
- HAL_FLASH_Lock();
- }
- }
- void SetFlashWriteProtect(void)
- {
- FLASH_OBProgramInitTypeDef OBInit={0};
- HAL_FLASHEx_OBGetConfig(&OBInit);
- if(OB_WRPSTATE_DISABLE == OBInit.WRPState || OB_WRP_SECTOR_All != OBInit.WRPSector)
- {
- OBInit.OptionType = OPTIONBYTE_WRP;
- OBInit.WRPState = OB_WRPSTATE_ENABLE;
- OBInit.WRPSector = OB_WRP_SECTOR_All;
- OBInit.Banks = FLASH_BANK_1;
- /* Allow Access to option bytes sector */
- HAL_FLASH_OB_Unlock();
- /* Allow Access to Flash control registers and user Flash */
- HAL_FLASH_Unlock();
- HAL_StatusTypeDef status = HAL_FLASHEx_OBProgram(&OBInit);
- /* Prevent Access to option bytes sector */
- HAL_FLASH_OB_Lock();
- /* Disable the Flash option control register access (recommended to protect
- the option Bytes against possible unwanted operations) */
- HAL_FLASH_Lock();
- if(HAL_OK != status)
- {
- return;
- }
- }
- }
- void ClearFlashWriteProtect(void)
- {
- FLASH_OBProgramInitTypeDef OBInit={0};
- HAL_FLASHEx_OBGetConfig(&OBInit);
- //if(OB_WRPSTATE_ENABLE == OBInit.WRPState)
- {
- OBInit.OptionType = OPTIONBYTE_WRP;
- OBInit.WRPState = OB_WRPSTATE_DISABLE;
- OBInit.WRPSector = OB_WRP_SECTOR_All;
- OBInit.Banks = FLASH_BANK_1;
- /* Allow Access to option bytes sector */
- HAL_FLASH_OB_Unlock();
- /* Allow Access to Flash control registers and user Flash */
- HAL_FLASH_Unlock();
- HAL_StatusTypeDef status = HAL_FLASHEx_OBProgram(&OBInit);
- /* Prevent Access to option bytes sector */
- HAL_FLASH_OB_Lock();
- /* Disable the Flash option control register access (recommended to protect
- the option Bytes against possible unwanted operations) */
- HAL_FLASH_Lock();
- if(HAL_OK != status)
- {
- return;
- }
- }
- }
- void SetBORLevel(void)
- {
- FLASH_OBProgramInitTypeDef OBInit={0};
- HAL_FLASHEx_OBGetConfig(&OBInit);
- if(OB_BOR_LEVEL3 != OBInit.BORLevel)
- {
- OBInit.OptionType = OPTIONBYTE_BOR;
- OBInit.BORLevel = OB_BOR_LEVEL3;
- /* Allow Access to option bytes sector */
- HAL_FLASH_OB_Unlock();
- /* Allow Access to Flash control registers and user Flash */
- HAL_FLASH_Unlock();
- HAL_FLASHEx_OBProgram(&OBInit);
- /* Prevent Access to option bytes sector */
- HAL_FLASH_OB_Lock();
- /* Disable the Flash option control register access (recommended to protect
- the option Bytes against possible unwanted operations) */
- HAL_FLASH_Lock();
- }
- }
- /*********************************END OF FILE**********************************/
|