#include "flash.h" #include "gd32c10x.h" #include "gd32c10x_crc.h" #include "gd32c10x_fmc.h" #include "math.h" #include #include #include #include #include FlashEEPROM flashEEP = FlashEEPROM(); // FlashEEPROM类实现 FlashEEPROM::FlashEEPROM() { // 构造函数可以为空,或者做一些初始化工作 } /** * @brief 初始化Flash EEPROM模拟 * @param None * @retval None */ u8 FlashEEPROM::init() { rcu_periph_clock_enable(RCU_CRC); crc_deinit(); // 初始化CRC模块 return 0; // 正常不会返回这个,未预料的异常情况返回 } /** * @brief 格式化Flash EEPROM页面 * @param None * @retval FlashEepromStatus: 操作状态 */ FlashEepromStatus FlashEEPROM::format() { fmc_state_enum fmc_status; #if EEPDEBUG printf("擦除页面\r\n"); #endif fmc_unlock(); fmc_status = fmc_page_erase(EEPROM_START_ADDRESS); // 擦除第一页 if (fmc_status != FMC_READY) { fmc_lock(); return FLASH_EEPROM_ERASE_ERROR; } fmc_status = fmc_page_erase(EEPROM_DATA_PAGE2_ADDRESS); // 擦除第二页 if (fmc_status != FMC_READY) { fmc_lock(); return FLASH_EEPROM_ERASE_ERROR; } fmc_lock(); return FLASH_EEPROM_OK; } /** * @brief 保存CRC数据到Flash * @return FlashEepromStatus: 状态 */ FlashEepromStatus FlashEEPROM::writeCRC(u32 CRC_NUM) { static u32 next_address; // 遍历Flash页面寻找下一个可写入crc的位置 for (u32 address = EEPROM_DATA_START_ADDRESS - SIZE_U32; address > EEPROM_START_ADDRESS; address -= SIZE_U32) { // 安全读取Flash数据 volatile u32 *flash_ptr = (volatile u32 *)address; u32 data_word = *flash_ptr; // 找到空位置 if (data_word == 0xFFFFFFFF) { next_address = address; break; } // 更新下一个可能的写入位置(如果需要格式化) next_address = address - SIZE_U32; } // 如果当前CRC与现在的crc值不同,则写入 if (*((u32 *)next_address) != CRC_NUM) { // 如果有足够空间,直接写入crc值 if (next_address > EEPROM_START_ADDRESS) { fmc_unlock(); fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR); fmc_state_enum fmc_status = fmc_word_program(next_address, CRC_NUM); fmc_lock(); #if EEPDEBUG printf("CRC cmp1,0x%X_0x%x \r\n", CRC_NUM, *((u32 *)next_address)); #endif // 检查写入是否成功 if (fmc_status != FMC_READY) { EEPROMStatus = fmc_status; return FLASH_EEPROM_WRITE_ERROR; } } } // 重新读取CRC校验 if (CRC_NUM == *((u32 *)next_address)) { EEPROMStatus = FLASH_EEPROM_OK; // 设置EEPROM状态 return FLASH_EEPROM_OK; } else { EEPROMStatus = FLASH_EEPROM_CRC_ERROR; // 设置EEPROM错误状态 return FLASH_EEPROM_CRC_ERROR; } }