/************************************************************************************************ * Include * ************************************************************************************************/ #include "drv_flash.h" #include "stm32f4xx.h" #include /************************************************************************************************ * Config * ************************************************************************************************/ /************************************************************************************************ * Data structs * ************************************************************************************************/ /************************************************************************************************ * implements * ************************************************************************************************/ uint16_t fmc_get_flash_sector(u32 addr) { if (addr < ADDR_FLASH_SECTOR_1) return FLASH_Sector_0; else if (addr < ADDR_FLASH_SECTOR_2) return FLASH_Sector_1; else if (addr < ADDR_FLASH_SECTOR_3) return FLASH_Sector_2; else if (addr < ADDR_FLASH_SECTOR_4) return FLASH_Sector_3; else if (addr < ADDR_FLASH_SECTOR_5) return FLASH_Sector_4; else if (addr < ADDR_FLASH_SECTOR_6) return FLASH_Sector_5; else if (addr < ADDR_FLASH_SECTOR_7) return FLASH_Sector_6; else if (addr < ADDR_FLASH_SECTOR_8) return FLASH_Sector_7; else if (addr < ADDR_FLASH_SECTOR_9) return FLASH_Sector_8; else if (addr < ADDR_FLASH_SECTOR_10) return FLASH_Sector_9; else if (addr < ADDR_FLASH_SECTOR_11) return FLASH_Sector_10; return FLASH_Sector_11; } // 解除写保护,清除fmc特定寄存器 void fmc_clear_flag_star(void) { FLASH_Unlock(); // 解锁 FLASH_DataCacheCmd(DISABLE); // FLASH擦除期间,必须禁止数据缓存 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR); } // 设置写保护,清除fmc特定寄存器 void fmc_clear_flag_end(void) { FLASH_DataCacheCmd(ENABLE); // FLASH擦除结束,开启数据缓存 FLASH_Lock(); // 上锁 } // 读取一字节, 读取无需考虑字节对齐 uint8_t fmc_read_byte(uint32_t read_addr) { return *(vu8 *)read_addr; } // 读取两字节, 读取需考虑字节对齐 uint16_t fmc_read_half_word(uint32_t read_addr) { return *(vu16 *)read_addr; } // 读取N字节, 读取必须需考虑字节对齐 uint8_t fmc_read_n_half_word(uint32_t read_addr, uint16_t *buff, uint16_t count) { uint16_t i = 0; vu16 *addr = (vu16 *)read_addr; if (read_addr % 2 != 0) return 1; // 错误返回 for (i = 0; i < count; i++) { *buff++ = *addr++; } return 0; } // 读取1页, 地址必须对齐页首 uint8_t fmc_read_one_page(uint32_t read_addr, uint16_t *buff) { uint16_t i = 0; vu16 *addr = (vu16 *)read_addr; if (read_addr % FMC_PAGE_SIZE != 0) return 1; // 错误返回 for (i = 0; i < 1024; i++) { *buff++ = *addr++; } return 0; } // 擦出N页, 地址必须对齐页首 uint8_t fmc_erase_pages(uint32_t erase_addr, uint16_t len) { uint8_t status = 0; uint8_t i = 0, j = 0; for (i = 0; i < len; i++) { status = FLASH_EraseSector(fmc_get_flash_sector(erase_addr), VoltageRange_3); if (status != FLASH_COMPLETE) { return 1; } if ((erase_addr >= ADDR_FLASH_SECTOR_0) && (erase_addr < ADDR_FLASH_SECTOR_4)) { erase_addr += (i * FMC_PAGE_SIZE_16K); } else if ((erase_addr >= ADDR_FLASH_SECTOR_4) && (erase_addr < ADDR_FLASH_SECTOR_5)) { erase_addr += (i * FMC_PAGE_SIZE_64K); } else if ((erase_addr >= ADDR_FLASH_SECTOR_4) && (erase_addr < ADDR_FLASH_SECTOR_END)) { erase_addr += (i * FMC_PAGE_SIZE_128K); } else { return 0; } } return 0; // uint8_t status = 0; // status = FLASH_EraseSector(fmc_get_flash_sector(erase_addr), VoltageRange_3); // if (status != FLASH_COMPLETE) // { // return 1; // } // return 0; // uint16_t i = 0, j = 0; // uint32_t *addr = (uint32_t *)erase_addr; // if (erase_addr % FMC_PAGE_SIZE != 0) // return 1; // 错误返回 // for (i = 0; i < len; i++) // { // FLASH_EraseSector(fmc_get_flash_sector(erase_addr), VoltageRange_3); // for (j = 0; j < 512; j++) // { // if (*addr != 0xFFFFFFFF) // return 1; // else // addr++; // } // } // return 0; } // 只写入,写入前需擦除,地址必须两字节对齐 uint8_t fmc_write_n_half_word(uint32_t write_addr, uint16_t *buff, uint16_t len) { uint32_t end_addr = write_addr + len * 2; if (write_addr % 2 != 0) return 1; while (write_addr < end_addr) { FLASH_ProgramHalfWord(write_addr, *buff); // 写入数据 if (*(vu16 *)write_addr != *buff) { return 1; } write_addr += 2; buff++; } return 0; } uint16_t firmware_crc16_ccitt_false(uint16_t init_value, uint8_t *pbuff, uint32_t len) { uint16_t temp = 0; uint16_t crc = init_value; for (int i = 0; i < len; i++) { for (int j = 0; j < 8; j++) { temp = ((pbuff[i] << j) & 0x80) ^ ((crc & 0x8000) >> 8); crc <<= 1; if (temp != 0) { crc ^= 0x1021; } } } return crc; }