You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

241 lines
8.3 KiB

#include "stm32f4xx.h"
#include "flash_if.h"
/**
* @brief Gets the sector of a given address
* @param Address: Flash address
* @retval The sector of a given address
*/
static uint32_t get_sector(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;
#if !defined(STM32F429_439xx)
} else {/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
sector = FLASH_Sector_11;
}
#else
} else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11)) {
sector = FLASH_Sector_11;
} else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12)) {
sector = FLASH_Sector_12;
} else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13)) {
sector = FLASH_Sector_13;
} else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14)) {
sector = FLASH_Sector_14;
} else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15)) {
sector = FLASH_Sector_15;
} else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16)) {
sector = FLASH_Sector_16;
} else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17)) {
sector = FLASH_Sector_17;
} else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18)) {
sector = FLASH_Sector_18;
} else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19)) {
sector = FLASH_Sector_19;
} else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20)) {
sector = FLASH_Sector_20;
} else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21)) {
sector = FLASH_Sector_21;
} else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22)) {
sector = FLASH_Sector_22;
} else {
sector = FLASH_Sector_23;
}
#endif
return sector;
}
/**
* @brief Unlocks Flash for write access
* @param None
* @retval None
*/
void flash_if_init(void)
{
FLASH_Unlock();
/* Clear pending flags (if any) */
FLASH_ClearFlag(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
*/
int flash_if_erase(uint32_t start_address, uint32_t length)
{
uint32_t start, end, i = 0;
start = get_sector(start_address);
if (length > 0) {
end = get_sector(start_address + length);
} else {
#if !defined(STM32F429_439xx)
end = FLASH_Sector_11;
#else
end = FLASH_Sector_23;
#endif
}
for (i = start; i <= end; i += 8) {
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_EraseSector(i, VoltageRange_3) != FLASH_COMPLETE) {
/* 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 length: length of data buffer (unit is byte)
* @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
*/
int flash_if_write(uint32_t flash_address, const void *data ,uint32_t tot)
{
const uint8_t *ptr = data;
const uint32_t *ptr32;
uint32_t i, length, align;
align = flash_address % 4;
if (align > 0) {
while ((tot > 0) && (align > 0) && (flash_address <= (USER_FLASH_END_ADDRESS))) {
if (FLASH_ProgramByte(flash_address, *ptr) != FLASH_COMPLETE) {
return 1;
}
if (*(volatile uint8_t *)flash_address != *ptr) {
return 2;
}
++flash_address;
++ptr;
--align;
--tot;
}
}
ptr32 = (const uint32_t *)ptr;
length = tot / 4;
for (i = 0; (i < length) && (flash_address <= (USER_FLASH_END_ADDRESS-4)); i++) {
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
be done by word */
if (FLASH_ProgramWord(flash_address, ptr32[i]) == FLASH_COMPLETE) {
/* Check the written value */
if (*(volatile uint32_t*)flash_address != ptr32[i]) {
/* Flash content doesn't match SRAM content */
return (2);
}
/* Increment FLASH destination address */
flash_address += 4;
ptr += 4;
} else {
/* Error occurred while writing data in Flash memory */
return (1);
}
}
align = tot % 4;
while ((align > 0) && (flash_address <= USER_FLASH_END_ADDRESS)) {
if (FLASH_ProgramByte(flash_address, *ptr) == FLASH_COMPLETE) {
if (*(volatile uint8_t *)flash_address != *ptr) {
return (2);
}
} else {
return (1);
}
++ptr;
++flash_address;
--align;
}
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
*/
int flash_if_get_write_protection_status(uint32_t address)
{
uint32_t UserStartSector;
/* Get the sector where start the user flash area */
UserStartSector = get_sector(address);
/* Check if there are write protected sectors inside the user flash area */
if ((FLASH_OB_GetWRP() >> (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
*/
int flash_if_disable_write_protection(uint32_t address)
{
__IO uint32_t UserStartSector, UserWrpSectors = OB_WRP_Sector_1;
/* Get the sector where start the user flash area */
UserStartSector = get_sector(address);
/* Mark all sectors inside the user flash area as non protected */
UserWrpSectors = 0xFFF-((1 << (UserStartSector/8))-1);
/* Unlock the Option Bytes */
FLASH_OB_Unlock();
/* Disable the write protection for all sectors inside the user flash area */
FLASH_OB_WRPConfig(UserWrpSectors, DISABLE);
/* Start the Option Bytes programming process. */
if (FLASH_OB_Launch() != FLASH_COMPLETE) {
/* Error: Flash write unprotection failed */
return (2);
}
/* Write Protection successfully disabled */
return (1);
}