#include "spiFlashFat.h" #include "spiFlash.h" #define SFILE_VALID_MARK 0x20115028 #define INVALID_FID 0xff #define SERR_SUCC 0 #define SERR_INIT_FAIL 1 #define SERR_ERACE_FAIL 2 #define SERR_WRITE_FAIL 3 #define SERR_READ_FAIL 4 #define SERR_FILE_FULL 5 #define SERR_SIZE_FULL 6 static unsigned char spiFatErr=0; unsigned char spi_flash_get_err(void){return spiFatErr;} /*SPI FLASH 使用地址划分*/ /*第一块,用于系统参数保存使用,自带备份,每个文件暂时2个sector*/ /*第一块,用于应用创建使用*/ #define MAX_SFILE_NUM 5 //1区最多可以创建多少个系统参数文件 #define SFILE_BLOCK_1_START_ADDR 0 //1区起始地址 #define SFILE_BLOCK_1_SIZE_BYTE (2*MAX_SFILE_NUM*SECTOR_SIZE_BYTE) //1区总大小 /*第二块,用于文件暂时存储,不带备份,异常掉电可能丢失*/ #define SFILE_BLOCK_2_START_ADDR (SFILE_BLOCK_1_START_ADDR+SFILE_BLOCK_1_SIZE_BYTE)//2区起始地址 #define SFILE_BLOCK_2_SIZE_BYTE (SECTOR_SIZE_BYTE+SECTOR_SIZE_BYTE*128)//2区总大小 //检测是否超出存储范围 #define SFILE_USER_MAX (SFILE_BLOCK_1_SIZE_BYTE+SFILE_BLOCK_2_SIZE_BYTE) #if(SFILE_USER_MAX>SPI_FLASH_MAX_SIZE) #error "USER FLASH SIZE OVERFLOW" #endif /***********************************第一块文件系统实现*************************************/ #pragma pack(push) #pragma pack(1) typedef struct{//放在sector最后 unsigned short crc16; unsigned int mark; }SFILE_INFO_DEF; #pragma pack(pop) #define SFILE_VALID_SIZE (SECTOR_SIZE_BYTE-sizeof(SFILE_INFO_DEF)) //每个系统文件最多能存的用户有效数据 /*格式化文件*/ bool spi_flash_file_format(unsigned char fid){ char i; SPI_PWR_LOCK; if(fid>=MAX_SFILE_NUM || spiFlashInit()==false){ spiFatErr=SERR_INIT_FAIL;SPI_PWR_RELEAS; return INVALID_FID; } for(i=0;i<2;i++){ if(false==spiFlashSectorErace(SFILE_BLOCK_1_START_ADDR+(fid*2+i)*SECTOR_SIZE_BYTE)){ spiFatErr=SERR_ERACE_FAIL;SPI_PWR_RELEAS; return false; } } SPI_PWR_RELEAS; return true; } /*格式化区域所有文件*/ bool spi_flash_files_format(void){ char i; SPI_PWR_LOCK; for(i=0;iSFILE_VALID_SIZE) len=SFILE_VALID_SIZE; if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE+addr, ptr, len)){ spiFatErr=SERR_READ_FAIL; return false; } return true; } /*文件写数据*/ bool spi_flash_file_write(unsigned char fid, unsigned int addr, unsigned char *ptr, unsigned int size){ unsigned char tmp[SECTOR_SIZE_BYTE]; unsigned int len=size; SFILE_INFO_DEF *info=tmp+SFILE_VALID_SIZE; //先写备份区,再写使用区 //1,先读使用区数据 if(false==spiFlashDataRead(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){ spiFatErr=SERR_READ_FAIL; return false; } //2,修改缓存数据 if(len>SFILE_VALID_SIZE) len=SFILE_VALID_SIZE; memcpy(tmp+addr, ptr, len); info->mark=SFILE_VALID_MARK; info->crc16=make_crc16(tmp, SFILE_VALID_SIZE); info->crc16 += make_crc16(tmp+SECTOR_SIZE_BYTE-4); SPI_PWR_LOCK; //3,写到备份区 if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE+SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){ spiFatErr=SERR_WRITE_FAIL; SPI_PWR_RELEAS; return false; } //4,写到使用区 if(false==spiFlashDataWrite(SFILE_BLOCK_1_START_ADDR+2*fid*SECTOR_SIZE_BYTE, tmp, SECTOR_SIZE_BYTE)){ spiFatErr=SERR_WRITE_FAIL; SPI_PWR_RELEAS; return false; } SPI_PWR_RELEAS; return true; } /*检测是否需要恢复,不会出现两个sector都异常*/ static bool spi_flash_file_check(void){ unsigned char i; unsigned char tmp[SECTOR_SIZE_BYTE]; SFILE_INFO_DEF info1,info2; unsigned short crc16_1,crc16_2; if(spiFlashInit()==false){ spiFatErr=SERR_INIT_FAIL; return false; } for(i=0;imark=SFILE_VALID_MARK; if(fid==0) info->startAddr=SECTOR_SIZE_BYTE;//第一个文件放在列表sector的下sector开始 else info->startAddr=sFat.files[fid-1].startAddr+sFat.files[fid-1].size; info->size=sectorNum*SECTOR_SIZE_BYTE; if(info->sizecrc16=make_crc16((unsigned char *)info,sizeof(SFAT_INFO_DEF)-2); //更新剩余 sFat.validSize -= info->size; sFat.validFiles++; sFat.crc16=make_crc16((unsigned char *)&sFat, sizeof(SFAT_LIST_DEF)-2); //保存 if(spiFlashDataWrite(SFILE_BLOCK_2_START_ADDR, (unsigned char *)&sFat, sizeof(SFAT_LIST_DEF))){//恢复 spiFatErr=SERR_WRITE_FAIL; return INVALID_FID; } return fid; } //////////////////////////////////////////////////////////////////////////////////////////// /*spi文件系统初始化,读写前先调用*/ void spiFlashInitApiInit(void){ spi_flash_file_check();//检测是否需要备份的恢复 }