⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2cflash.c

📁 AT91fr40162的FLASH读写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -