📄 appi2c.c
字号:
//These codes contains the functions to operate the 24C64 EEPROM
//For the reason that the length of address domain is longer, the library
//functions of serial I2C EEPROM con not be used derectly
// The operation on EEPROM can't be done by multiple user simultanously, so a semephone is
// applied when write or read the EEPROMs
#include <p18cxxx.h>
#include <i2c.h>
#include "includes.h"
#include "ComStruct.h"
//#define INT24U unsigned short long
//#define INT8U unsigned char
//#define INT16U unsigned int
#define MEM_ROM rom
#define UNIQUEWORD 0x5A3E //The value of unique word to mark if the EEPROMs have been initialized
#define FILE_NO_ERR 0x00 //file operation execute OK
#define FILE_NO_SUCH_FILE 0x01 //there is not such a file
#define FILE_ILLEGAL_ADDRESS 0x02 //file address is illegal
#define MAXFILENUM 64
//#define FID_
#define CONTROL0 0b10100000 //control byte when write or read EEPROM0
#define CONTROL1 0b10100010 //control byte when write or read EEPROM1
extern OS_EVENT * rom EepromSem;
extern OS_EVENT *rom peventMCNM;
extern OS_EVENT *rom peventDVS;
INT8U putsI2CA( INT8U MEM_ROM *wrptr, INT16U length );
INT8U getsI2CA( INT8U MEM_ROM *rdptr, INT8U length );
INT8U EESequentialReadA(INT8U control,INT16U address,INT8U MEM_ROM *rdptr,INT8U length );
INT8U EEPageWriteA(INT8U control, INT16U address, INT8U MEM_ROM *wrptr, INT16U length );
//Public functions
typedef rom struct FileTableItem{
INT16U Start;
INT16U End;
}FILETABLEITEM;
typedef rom struct FileTable{
INT16U U_W; //unique word, mark if these EEPROMs have been initialized
INT32U SN; //serial number of the equipment, write before shipping
FILETABLEITEM FileIndex[MAXFILENUM]; //The File alocation table
INT8U ChkSum; //Check Sum of all the former parts
} FILETABLE;
#pragma romdata EXTRAM
FILETABLE FileSys;
INT8U FileSysInit(void){
INT8U i,Temp,err;
INT16U IdlePos; //point to the position of first idle bytes when create files
INT8U rom * ptrTemp;
OSSemPend (EepromSem,0,&err); //seize the semephone
Temp = EESequentialReadA(CONTROL0, 0, &FileSys, sizeof(FileSys));
OSSemPost(EepromSem);
if(Temp != 0) return(Temp);
if( FileSys.U_W != UNIQUEWORD){ //These file EEPROMs have not been initialized
FileSys.U_W = UNIQUEWORD;
FileSys.SN = 0;
for(i=0; i<MAXFILENUM;i++){
FileSys.FileIndex[i].Start = 0xffff;
FileSys.FileIndex[i].End = 0xffff;
}
//Create indexes of two necesary files here
IdlePos = sizeof(FileSys);
FileSys.FileIndex[TASK_MCNM_PRIO].Start = IdlePos;
IdlePos += GetMCNMFileLen();
FileSys.FileIndex[TASK_MCNM_PRIO].End = IdlePos - 1;
//
FileSys.FileIndex[TASK_DVS_PRIO].Start = IdlePos;
IdlePos += GetDVSFileLen();
FileSys.FileIndex[TASK_DVS_PRIO].End = IdlePos - 1;
//make chechsum and write
Temp = 0;
ptrTemp = (INT8U rom *)(&FileSys);
for(i=0;i<sizeof(FileSys);i++){
Temp ^= *ptrTemp++;
}
FileSys.ChkSum = Temp;
OSSemPend (EepromSem,0,&err); //seize the semephone
EEPageWriteA(CONTROL0, 2, &FileSys.SN, (sizeof(FileSys)-2)); //Write the file table
EEPageWriteA(CONTROL0, 0, &FileSys, 2); //Write the unique word
OSSemPost(EepromSem);
OSQPost(peventMCNM, (OS_EVENT *)MSG_FILE_NEWFILECREATE);//tell the tasks to write the contents
OSQPost(peventDVS, (OS_EVENT *)MSG_FILE_NEWFILECREATE);
}
else{ //The file system has been initilized
Temp = 0;
ptrTemp = (INT8U rom *)(&FileSys);
for(i=0;i<(sizeof(FileSys)-1);i++){
Temp ^= *ptrTemp++;
}
if(FileSys.ChkSum != Temp) ; //check sum error, make new files???
}
}
//FileHandle: handle of the file
//Position: start position of the data to be saved. it's the offset from the start address in the EEPROM
// of the file
//ptrData: start address of the data in the ram
//DataLen: length of the data to be saved
//For example, FileSave(HANDLEX, 2, 0x103000, 20)
// if HANDLEX relating with a file saved in EEPROM ranging from 0x2300 to 0x2400, then the function save 20
// bytes in the ram begining at 0x103000 into EEPROM address from 0x2302 to 0x230e
INT8U FileSave(INT8U FileID, INT16U Position, INT8U rom * ptrData, INT16U DataLen){
INT8U Temp,i,err;
INT16U PhyPos; //physical address in EEPROM
INT16U writetimes;
if(FileID != OSPrioCur) return (1); //return if it's not the owner of the file
if (FileSys.FileIndex[FileID].Start == 0xffff) return (1); //return if the file has not been create
PhyPos = FileSys.FileIndex[Temp].Start + Position; //calaulate the start address of EEPROM
if((PhyPos > FileSys.FileIndex[Temp].End) ||
((PhyPos+DataLen-1)> FileSys.FileIndex[Temp].End)){
return (1); //if the data to be saved is not in the legal range, return
}
else{ //exacute the write operation
OSSemPend (EepromSem,0,&err); //seize the semephone
if(err != OS_NO_ERR) return (0xff);
for(;;){
if(PhyPos < 0x2000){ //is there some bytes to be writen to EEPROM 0?
i = 32 - (PhyPos & 0x1f);
if (i > DataLen) i = DataLen; //calculate the length of a segment
err = EEPageWriteA(0b10100000, PhyPos, ptrData, i );
if (err != 0) return (err);
OSTimeDly(2); //wait at least 10 ms
ptrData = ptrData+i;
DataLen = DataLen-i;
PhyPos = PhyPos+i;
if(DataLen == 0){
OSSemPost (EepromSem); //finish writing
return(0);
}
}
else{
i = 32 - (PhyPos & 0x1f);
if (i > DataLen) i = DataLen; //calculate the length of a segment
err = EEPageWriteA(0b10100010, PhyPos-0x2000, ptrData, i );
if (err != 0) return (err);
OSTimeDly(2);
ptrData = ptrData+i;
DataLen = DataLen-i;
PhyPos = PhyPos+i;
if(DataLen == 0){
OSSemPost (EepromSem);
return(0);
}
}
}
}
}
INT8U FileRead(INT8U FileID, INT16U Position, INT8U rom * ptrData, INT16U DataLen){
INT8U Temp,i,err;
INT16U PhyPos;
INT16U rom1len,rom2len;
if (FileSys.FileIndex[FileID].Start == 0xffff) return (1); //return if the file has not been create
PhyPos = FileSys.FileIndex[Temp].Start + Position;
if((PhyPos > FileSys.FileIndex[Temp].End) ||
((PhyPos+DataLen-1)> FileSys.FileIndex[Temp].End)){
return (1);
}
if(err != OS_NO_ERR) return (0xff);
if(PhyPos >= 0x2000){ //located only in EEPROM 1
rom1len = 0;
rom2len = DataLen;
}
else if(DataLen > 0x2000 - PhyPos){ //located in EEPROM 0 and 1
rom1len = 0x2000 - PhyPos;
rom2len = DataLen - rom1len;
}
else{ //located only in EEPROM 0
rom1len = DataLen;
rom2len = 0;
}
OSSemPend (EepromSem,0,&err);
if(rom1len != 0){
EESequentialReadA(0b10100000, PhyPos, ptrData, rom1len);
ptrData = ptrData + rom1len;
PhyPos = PhyPos + rom1len;
}
if(rom2len != 0){
EESequentialReadA(0b10100010, PhyPos-0x2000, ptrData, rom2len);
}
OSSemPost (EepromSem);
return(0);
}
//Local functions
//1. Byte write function
/*INT8U EEByteWriteA( INT8U control, INT16U address, INT8U data ){
INT8U addressl,addressh;
addressl = (INT8U)address;
addressh = (INT8U)(address>>8);
IdleI2C(); // ensure module is idle
StartI2C(); // initiate START condition
while ( SSPCON2bits.SEN ); // wait until start condition is over
if ( PIR2bits.BCLIF ){ // test for bus collision
return ( -1 ); // return with Bus Collision error
}
else{ // start condition successful
if ( WriteI2C( control )){ // write byte - R/W bit should be 0
return ( -3 ); // set error for write collision
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -