📄 i2cflash.c
字号:
#include "dtm_v3.h"
#include "dtm.h"
#include "externdef.h"
_BYTE FlashWriteBuf(_WORD wAddress,_WORD wLength,_BYTE cChip,_BYTE *cpBuf);
_BYTE FlashReadBuf(_WORD wAddress,_WORD wLength,_BYTE cChip,_BYTE *cpBuf);
_BYTE FlashInQueue(_BYTE *cpLogBuf);
_BYTE FlashOutQueue(_BYTE * cpLogBuf);
_BYTE FlashReadQueue(_WORD wIndex,_BYTE * cpLogBuf);
_BYTE FlashReadWriteQueuePoint(_BYTE *cpPointBuf,_BYTE cMode,_BYTE cType,_BYTE cChip);
_BYTE FlashRollBack(_BYTE cType,_WORD wCount);
_BYTE FlashCheckSpace(_WORD * wSpacs);
_BYTE FlashReadWriteDCB(_BYTE DCBNumber,struct StruDCB *spDCB,_BYTE cMode);
_BYTE FlashReadWriteSPB(struct StruSPB *spSPB,_BYTE cMode);
_BYTE FlashVerify(_BYTE *cpSourceBuf,_BYTE *cpTragetBuf,_WORD wLength);
_BYTE FlashReadWriteDAT(_BYTE *cpDATBuf,_BYTE cMode);
_BYTE FlashReadWriteKEYAREA(struct StruKEYAREA *spKEY,_BYTE cMode);
_BYTE FlashReadWriteCDTI(struct StruCDTI *spCDTI,_BYTE cMode);
_BYTE FlashReadWriteCSI(struct StruCSI *spCSI,_BYTE cMode);
_BYTE FlashReadWriteMB(_BYTE *cpMBBuf,_BYTE cIndex,_BYTE cMode);
/***************************************************************
* 函数: FlashWriteBuf
* 功能: 把BUF中的数据写入EEPROM
* 参数: wAddress: 拟写入数据在Flash的起始地址
* cLength: 拟写入数据的长度
* cpBuf: 拟写入FLASh中的数据
* cChip: 选择片0还是片1
***************************************************************/
_BYTE FlashWriteBuf(_WORD wAddress,_WORD wLength,_BYTE cChip,_BYTE *cpBuf)
{
_BYTE cRetCode;
AT91_I2C_LineOpen(&I2C_line, I2C_line.dwI2CSpeed,cChip,I2CFLASH);
cRetCode = I2CWriteBlock(wAddress,wLength,cChip,cpBuf,I2CFLASH);
AT91_I2C_LineClose(&I2C_line);
return(cRetCode);
}
/***************************************************************
* 函数: FlashReadBuf
* 功能: 把EEPROM的数据写到BUF中
* 参数: wAddress: 拟写入数据在Flash的起始地址
* cLength: 拟写入数据的长度
* cpBuf: 拟写入BUF中的数据
* cChip: 选择片0还是片1
***************************************************************/
_BYTE FlashReadBuf(_WORD wAddress,_WORD wLength,_BYTE cChip,_BYTE *cpBuf)
{
_BYTE cRetCode;
AT91_I2C_LineOpen(&I2C_line, I2C_line.dwI2CSpeed,cChip,I2CFLASH);
cRetCode = I2CReadBlock(wAddress,wLength,cChip,cpBuf,I2CFLASH);
AT91_I2C_LineClose(&I2C_line);
return(cRetCode);
}
//***********************************************************************************
//向Flash中写入一条日志信息,日志信息存放到cpLogBuf中,日志信息的长度由常量LENOFCOACHLOG指定
//函数的返回值为C_OK、C_FLASHERR。
//STARTOFQUEUEPTR+2,STARTOFQUEUEPTR+3为写地址
//***********************************************************************************
_BYTE FlashInQueue(_BYTE *cpLogBuf)
{
_WORD R_num,W_num,Address;
_BYTE cpTmpBuf[3],cRetCode,cChip;
_BYTE cCrcCode;
_BYTE cBuff[LENOFCOACHLOG];
cChip = 0;
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,OUTQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
R_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,INQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
W_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
if ((W_num+1)%MAXFLASHLOGITEM!=R_num) { // 队列未满
DelayMCK4(SPI_BASE_DELAY_TIME);
if ((W_num+1)%MAXFLASHLOGITEM > MAXFLASHLOGITEM_1){
cChip = 1;
Address= (W_num - MAXFLASHLOGITEM_1) * LENOFCOACHLOG;
Address+=FLASH2_LOGBUF_ADDRESS;
}
else{
cChip = 0;
Address=W_num * LENOFCOACHLOG;
Address+=FLASH1_LOGBUF_ADDRESS;
}
cCrcCode = Crc8 (LENOFCOACHLOG-1,cpLogBuf); //计算校验和
cpLogBuf[LENOFCOACHLOG-1] = cCrcCode;
//加密
cRetCode = FlashWriteBuf (Address,LENOFCOACHLOG,cChip,cpLogBuf);
if (cRetCode!=C_OK) return(cRetCode);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
cRetCode = FlashReadBuf (Address,LENOFCOACHLOG,cChip,cBuff);
if (cRetCode!=C_OK) return(cRetCode);
//比较
if ((cRetCode =FlashVerify(cpLogBuf,cBuff,LENOFCOACHLOG))!=C_OK)
return(cRetCode);
W_num = (W_num+1) % MAXFLASHLOGITEM;
cpTmpBuf[0] = (_BYTE)(W_num>>8);
cpTmpBuf[1] = (_BYTE)(W_num);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICWRITE,INQUEUE,0);
return(cRetCode);
}
else
return(C_FLASHFULL);
}
//***********************************************************************************
//从Flash中读取一条日志信息,存放到cpLogBuf中,日志信息的长度由常量LENOFCOACHLOG指定
//函数的返回值为C_OK、C_FLASHERR或C_END,C_END表示当前日志是最后一条日志信息。
//STARTOFQUEUEPTR,STARTOFQUEUEPTR+1为读地址
//***********************************************************************************
_BYTE FlashOutQueue(_BYTE * cpLogBuf) //从flash读一条日志
{
_WORD R_num,W_num,Address;
_BYTE cpTmpBuf[3],cRetCode,cChip;
_BYTE cCrcCode;
cChip=0;
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,OUTQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
R_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,INQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
W_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
if (R_num!=W_num) { // 队列不为空
if ((R_num+1)%MAXFLASHLOGITEM > MAXFLASHLOGITEM_1){
cChip = 1;
Address = (R_num - MAXFLASHLOGITEM_1) * LENOFCOACHLOG;
Address += FLASH2_LOGBUF_ADDRESS;
}
else{
cChip = 0;
Address = R_num * LENOFCOACHLOG;
Address += FLASH1_LOGBUF_ADDRESS;
}
cRetCode = FlashReadBuf (Address,LENOFCOACHLOG,cChip,cpLogBuf);
if (cRetCode!=C_OK) return(cRetCode);
//解密
cCrcCode = Crc8 (LENOFCOACHLOG-1,cpLogBuf); //计算校验
if(cCrcCode!=cpLogBuf[LENOFCOACHLOG-1]) return(C_FLASHCRCERR); //判断校验是否正确
R_num = (R_num + 1) % MAXFLASHLOGITEM;
cpTmpBuf[0] = (_BYTE)(R_num>>8);
cpTmpBuf[1] = (_BYTE)(R_num);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICWRITE,OUTQUEUE,0);
if (cRetCode!=C_OK) return(cRetCode);
if(R_num==W_num) return(C_END);
}
else
return(C_EMPTYQUEUE);
return(C_OK);
}
//***********************************************************************************
//函数名:_BYTE FlashReadQueue(_WORD wIndex,_WORD * cpLogBuf)
//功 能:按照指定的序号从Flash中读取一条日志信息,存放到cpLogBuf中,日志信息的长度由常量LENOFCOACHLOG指定(该长度包含校验位)
//参 数:cpLogBuf:存放读取的日志信息;
//wIndex:日志序号,从0开始编号;
//返回值:函数执行成功,返回值为C_OK,否则返回错误码(见错误码表);
//***********************************************************************************
_BYTE FlashReadQueue(_WORD wIndex,_BYTE * cpLogBuf)
{
_WORD Address;
_BYTE cChip;
_BYTE cCrcCode,cRetCode;
if ((wIndex+1)%MAXFLASHLOGITEM>MAXFLASHLOGITEM_1) {
cChip = 1;
Address = (wIndex - MAXFLASHLOGITEM_1) * LENOFCOACHLOG;
Address += FLASH2_LOGBUF_ADDRESS;
}
else {
cChip = 0;
Address = wIndex * LENOFCOACHLOG;
Address += FLASH1_LOGBUF_ADDRESS;
}
cRetCode = FlashReadBuf(Address,LENOFCOACHLOG,cChip,cpLogBuf);
if (cRetCode!=C_OK) return(cRetCode);
//解密
cCrcCode = Crc8(LENOFCOACHLOG-1,cpLogBuf); //计算校验
if(cCrcCode!=cpLogBuf[LENOFCOACHLOG-1]) return(C_FLASHCRCERR); //判断校验是否正确
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
return(C_OK);
}
//******************************************************************
//函数名:_BYTE FlashWriteQueuePoint(_BYTE *cpPointBuf,_BYTE cMode)
//功 能:读取FLASH中的循环队列指针,或写入循环队列指针
//参 数:
// cpPointBuf:读取循环队列指针或要写入循环队列指针信息
// cMode:操作方式,ICREAD:表示读,ICWRITE:表示写
// cChip: 读写哪一片FLASH上的指针
// cType: 读写那个指针(首指针或未指针),OUTQUEUE:表示首指针,INQUEUE表示尾指针
//返回值:函数执行成功,返回值为C_OK,否则返回错误码(见错误码表);
//******************************************************************
_BYTE FlashReadWriteQueuePoint(_BYTE *cpPointBuf,_BYTE cMode,_BYTE cType,_BYTE cChip)
{
_WORD wAdd,i;
_BYTE cpReadBackBuf[3],cRetCode;
if(cType==OUTQUEUE)
wAdd=FLASH1_QUEUE_ADDRESS;
else
wAdd=FLASH1_QUEUE_ADDRESS+3;
if(cMode==ICREAD) {
FlashReadBuf(wAdd,LENOFQUEUEPOINT/2,cChip,cpPointBuf);
if (cpPointBuf[2]==cpPointBuf[0]+cpPointBuf[1]) //判断校验是否正确
return(C_OK);
else
return(C_FLASHERR);
}
else {
cpPointBuf[2] = cpPointBuf[0]+cpPointBuf[1]; //计算累加和校验
cRetCode = FlashWriteBuf(wAdd,LENOFQUEUEPOINT/2,cChip,cpPointBuf);
if (cRetCode!=C_OK) return(cRetCode);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
// 回读
cRetCode = FlashReadBuf(wAdd,LENOFQUEUEPOINT/2,cChip,cpReadBackBuf);
if (cRetCode!=C_OK) return(cRetCode);
DelayMCK4(5000*SPI_BASE_DELAY_TIME);
for (i=0;i<3;i++)
if(cpReadBackBuf[i]!=cpPointBuf[i]) return(C_FLASHERR); //判断校验是否正确
return(C_OK);
}
}
//***********************************************************************************
//使Flash中指针回滚1次
//
//
//***********************************************************************************
_BYTE FlashRollBack(_BYTE cType,_WORD wCount)
{
_WORD R_num,W_num;
_BYTE cpTmpBuf[3],cRetCode;
_BYTE cChip=0;
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,OUTQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
R_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,INQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
W_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
if(cType==OUTQUEUE){
if(wCount > R_num)
R_num=MAXFLASHLOGITEM-(wCount - R_num);
else
R_num = (R_num - wCount);
cpTmpBuf[0] = (_BYTE)(R_num>>8);
cpTmpBuf[1] = (_BYTE)(R_num);
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICWRITE,OUTQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
}
else{
if(wCount > W_num)
W_num = MAXFLASHLOGITEM - (wCount - W_num);
else
W_num = (W_num - wCount);
cpTmpBuf[0] = (_BYTE)(W_num>>8);
cpTmpBuf[1] = (_BYTE)(W_num);
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICWRITE,INQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
}
return(C_OK);
}
//***********************************************************************************
//检查FLASH剩余空间
//***********************************************************************************
_BYTE FlashCheckSpace(_WORD * wSpacs)
{
_BYTE cpTmpBuf[3],cRetCode;
_WORD R_num,W_num ;
_BYTE cChip=0;
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,OUTQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
R_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
cRetCode = FlashReadWriteQueuePoint(cpTmpBuf,ICREAD,INQUEUE,cChip);
if (cRetCode!=C_OK) return(cRetCode);
W_num = cpTmpBuf[0] * 256 + cpTmpBuf[1];
if(R_num>=W_num)
*wSpacs= R_num - W_num;
else
*wSpacs=MAXFLASHLOGITEM - W_num + R_num;
return(C_OK);
}
//***************************************************************************************
//功 能:读取FLASH中的DCB表中的编号为DCBNumber的表项,或写入信息到FLASH中指定的DCB表项
//参 数:DCBNumber:要读写的DCB表项,取值为0-31
//cpDCBBuf:读取的DCB表项信息或要写入的DCB表项信息
//cMode:操作方式,0表示读,1表示写
// cChip:读写那一片存储器0或者1
//返回值:函数执行成功的返回值为C_OK
//函数执行失败的返回值为错误码(见错误码表)
//**************************************************************************************
_BYTE FlashReadWriteDCB(_BYTE DCBNumber,struct StruDCB *spDCB,_BYTE cMode)
{
_BYTE cRetCode,cChip;
_BYTE cCrcCode;
_BYTE cBuff[LENOFDCB];
_BYTE cpDCBBuf[LENOFDCB];
_WORD wAdd;
cChip=0;
wAdd=DCBNumber * LENOFDCB + FLASH1_DCBT_ADDRESS;
if (cMode==ICREAD){
cRetCode = FlashReadBuf(wAdd,LENOFDCB,cChip,cpDCBBuf);
if (cRetCode!=C_OK) return(cRetCode);
cCrcCode = Crc8(LENOFDCB-1,cpDCBBuf); //计算校验
if(cCrcCode!=cpDCBBuf[LENOFDCB-1]) return(C_FLASHCRCERR); //判断校验是否正确
UncompressDCB(cpDCBBuf,spDCB);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -