|
|
@ -1,5 +1,12 @@ |
|
|
|
#include "zflash.h" |
|
|
|
|
|
|
|
#define ZFLASH_WRITE_DATA(start_address, data) \ |
|
|
|
if (!flash_writ_32(start_address, config->ip)) { \ |
|
|
|
FLASH->ACR |= 1 << 10; \ |
|
|
|
HAL_FLASH_Lock(); |
|
|
|
|
|
|
|
#define END() } |
|
|
|
|
|
|
|
static bool stmflash_address_legal(uint32_t start_addr, uint32_t end_addr) { |
|
|
|
if (start_addr < STM32_FLASH_BASE || start_addr % 4 || start_addr > (STM32_FLASH_BASE + STM32_FLASH_SIZE)) { |
|
|
|
return false; |
|
|
@ -10,6 +17,15 @@ static bool stmflash_address_legal(uint32_t start_addr, uint32_t end_addr) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
static bool flash_writ_32(uint32_t *start_address, uint32_t data) { |
|
|
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, *start_address, data) != HAL_OK) /* 写入数据 */ |
|
|
|
{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
*start_address += 4; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 从指定地址读取一个字 (32位数据) |
|
|
|
* @param faddr : 读取地址 (此地址必须为4倍数!!) |
|
|
@ -146,3 +162,64 @@ void stmflash_read(uint32_t raddr, uint32_t *pbuf, uint32_t length) { |
|
|
|
* @retval 读取到的数据 |
|
|
|
*/ |
|
|
|
void test_write(uint32_t waddr, uint32_t wdata) { stmflash_write(waddr, &wdata, 1); /* 写入一个字 */ } |
|
|
|
|
|
|
|
int8_t stmflash_write_config(uint32_t start_address, config_t *config, uint32_t length) { |
|
|
|
FLASH_EraseInitTypeDef flasheraseinit; |
|
|
|
HAL_StatusTypeDef FlashStatus = HAL_OK; |
|
|
|
|
|
|
|
uint32_t flash_write_start_address = 0; |
|
|
|
uint32_t flash_write_end_address = 0; |
|
|
|
uint32_t sectorerror = 0; |
|
|
|
|
|
|
|
flash_write_start_address = start_address; /* 写入的起始地址 */ |
|
|
|
flash_write_end_address = start_address + length * 4; /* 写入的结束地址 */ |
|
|
|
|
|
|
|
if (!stmflash_address_legal(flash_write_start_address, flash_write_end_address)) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
HAL_FLASH_Unlock(); /* 解锁 */ |
|
|
|
FLASH->ACR &= ~(1 << 10); /* FLASH擦除期间,必须禁止数据缓存!!! */ |
|
|
|
|
|
|
|
if (flash_write_start_address < 0X1FFF0000) /* 只有主存储区,才需要执行擦除操作!! */ |
|
|
|
{ |
|
|
|
while (flash_write_start_address < flash_write_end_address) /* 扫清一切障碍.(对非FFFFFFFF的地方,先擦除) */ |
|
|
|
{ |
|
|
|
if (stmflash_read_word(flash_write_start_address) != 0XFFFFFFFF) /* 有非0XFFFFFFFF的地方,要擦除这个扇区 */ |
|
|
|
{ |
|
|
|
flasheraseinit.TypeErase = FLASH_TYPEERASE_SECTORS; /* 擦除类型,扇区擦除 */ |
|
|
|
flasheraseinit.Sector = stmflash_get_flash_sector(flash_write_start_address); /* 要擦除的扇区 */ |
|
|
|
flasheraseinit.NbSectors = 1; /* 一次只擦除一个扇区 */ |
|
|
|
flasheraseinit.VoltageRange = FLASH_VOLTAGE_RANGE_3; /* 电压范围,VCC=2.7~3.6V之间!! */ |
|
|
|
|
|
|
|
if (HAL_FLASHEx_Erase(&flasheraseinit, §orerror) != HAL_OK) { |
|
|
|
break; /* 发生错误了 */ |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
flash_write_start_address += 4; |
|
|
|
} |
|
|
|
FLASH_WaitForLastOperation(FLASH_WAITETIME); /* 等待上次操作完成 */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
FlashStatus = FLASH_WaitForLastOperation(FLASH_WAITETIME); /* 等待上次操作完成 */ |
|
|
|
|
|
|
|
if (FlashStatus == HAL_OK) { |
|
|
|
ZFLASH_WRITE_DATA(&start_address, config->ip) { return -1; } |
|
|
|
END(); |
|
|
|
ZFLASH_WRITE_DATA(&start_address, config->gw) { return -2; } |
|
|
|
END(); |
|
|
|
ZFLASH_WRITE_DATA(&start_address, config->netmask) { return -3; } |
|
|
|
END(); |
|
|
|
ZFLASH_WRITE_DATA(&start_address, config->localport) { return -4; } |
|
|
|
END(); |
|
|
|
ZFLASH_WRITE_DATA(&start_address, config->obtaining_ip_mode) { return -5; } |
|
|
|
END(); |
|
|
|
} |
|
|
|
|
|
|
|
FLASH->ACR |= 1 << 10; /* FLASH擦除结束,开启数据fetch */ |
|
|
|
|
|
|
|
HAL_FLASH_Lock(); /* 上锁 */ |
|
|
|
return 0; |
|
|
|
} |