#include #include "MyI2C.h" #include "delay.h" #define LED RB3 /**************************************************************************** * Function:InitI2C * * Purpose: Initialize 100 kHz I2C communication * ****************************************************************************/ void InitI2C(void) { SSPADD = 0x0A; // 100 kHz I2C bus SSPCON1 = 0x28; // Enable I2C bus StopI2C(); } /**************************************************************************** * Function:StopI2C * * Purpose: End communication with I2C slave * * Send stop signal on I2C bus * * Input: Nothing * * Output: Nothing * ****************************************************************************/ void StopI2C(void) { SSPIF = 0; // Clear interrupt flag PEN = 1; // Send Stop condition while (SSPIF == 0); // Wait until stop condition complete } /**************************************************************************** * Function:WaitForWrite EEProm * * Purpose: Wait for read write acces in EEProm * * Send start signal on I2C bus * * Send on I2C bus * * Receive acknowledge from I2C slave * * Input: char I2CADD: Address of I2C slave to start communication with * * RWStruct *IOStruct2 ptr for data struct with Progress flag * * Output: 0: No communication started (missing acknowledge) * * 1: Communication started (acknowledge) * ****************************************************************************/ char WaitForWrite(char I2CADD, char *Progress) { int BreakCount = 5000; do{ SSPIF = 0; // Clear interrupt flag RSEN = 1; // Initiate start condition while (SSPIF == 0) LED = LED^1; // Wait until Start condition complete SSPIF = 0; // Clear interrupt flag SSPBUF = I2CADD; // Send address of slave device while (SSPIF == 0) LED = LED^1; // Wait until address has been sent if(BreakCount-- == 0){ LED = 0; *Progress = 0; return 0; // Return 0 if device didn't acknowledge } }while(ACKSTAT == 1); LED = 0; *Progress = 0; return 1; // Return 1 if device acknowledged } /**************************************************************************** * Function:StartI2C * * Purpose: Initiate communication with I2C slave * * Send start signal on I2C bus * * Send on I2C bus * * Receive acknowledge from I2C slave * * Input: char I2CADD: Address of I2C slave to start communication with * * Output: 0: No communication started (missing acknowledge) * * 1: Communication started (acknowledge) * ****************************************************************************/ char StartI2C(char I2CADD) { SSPIF = 0; // Clear interrupt flag RSEN = 1; // Initiate start condition while (SSPIF == 0) LED = LED^1; // Wait until Start condition complete SSPIF = 0; // Clear interrupt flag SSPBUF = I2CADD; // Send address of slave device while (SSPIF == 0) LED = LED^1; // Wait until address has been sent LED = 0; if (ACKSTAT == 0) return 1; // Return 1 if device acknowledged else return 0; // Return 0 if device didn't acknowledge } /**************************************************************************** * Function:ReStartI2C * * Purpose: Initiate communication with I2C slave * * Send start signal on I2C bus * * Send on I2C bus * * Receive acknowledge from I2C slave * * Input: char I2CADD: Address of I2C slave to start communication with * * Output: 0: No communication started (missing acknowledge) * * 1: Communication started (acknowledge) * ****************************************************************************/ char ReStartI2C(char I2CADD) { SSPIF = 0; // Clear interrupt flag RSEN = 1; // Initiate start condition while (SSPIF == 0) LED = LED^1; // Wait until Start condition complete SSPIF = 0; // Clear interrupt flag SSPBUF = I2CADD; // Send address of slave device while (SSPIF == 0) LED = LED^1; // Wait until address has been sent LED = 0; if (ACKSTAT == 0) return 1; // Return 1 if device acknowledged else return 0; // Return 0 if device didn't acknowledge } /**************************************************************************** * Function:WriteI2CByte * * Purpose: Send 1 byte to I2C slave * * Input: 1 Data byte * * Output: 0: Communication did not succeed * * 1: Communication succeeded * ****************************************************************************/ char WriteI2CByte(char I2CByte) { SSPIF = 0; SSPBUF = I2CByte; // while(SSPIF == 0); Delay10us(1); if (ACKSTAT == 0) return 1; // Return 1 if device acknowledged else return 0; // Return 0 if device didn't acknowledge } /**************************************************************************** * Function:ReadI2CByte * * Purpose: Send 1 byte to I2C slave * * Input: 1 Data byte * * Output: 0: Communication did not succeed * * 1: Communication succeeded * ****************************************************************************/ char ReadI2CByte(char LastRead) { char ReadChar=0; SSPIF = 0; // Clear interrupt flag RCEN = 1; // Initiate read sequence while (SSPIF == 0); ReadChar = SSPBUF; // Store byte in buffer SSPIF = 0; if(LastRead == 1){ ACKDT = 1; // indicate we're done by no ack }else{ ACKDT = 0; // else acknowledge the byte } ACKEN = 1; // Start acknowledge sequence return ReadChar; } /**************************************************************************** * Function:WriteI2C * * Purpose: Send bytes to I2C slave * * Input: char I2CADD: Address of I2C slave to start communication with * * char I2CBYTES: Number of bytes to send * * char*I2CBUFFER: Buffer containing data to send * * Output: 0: Communication did not succeed * * 1: Communication succeeded * ****************************************************************************/ char WriteI2C(RWStruct *IOStruct) //char DevAddr, char NoBytes, char *WriteBuffer); { char Count = 0; char Res = 1; if(IOStruct->WrInProgress == 1){ Res = WaitForWrite(IOStruct->DevAddr & 0xfe, &IOStruct->WrInProgress); }else{ Res = StartI2C(IOStruct->DevAddr & 0xfe); } if(Res == 1){ if(!WriteI2CByte((char) IOStruct->RWAddress / 0x100)) Res = 0; else if(!WriteI2CByte((char) IOStruct->RWAddress % 0x100)) Res = 0; else{ for(Count = 0; Count < IOStruct->NoBytes; Count++){ if(WriteI2CByte(IOStruct->IOBuffer[Count]) == 0){ Res = 0; break; } } } }else{ Res = 0; } StopI2C(); IOStruct->WrInProgress = 1; return Res; } /**************************************************************************** * Function:ReadI2C * * Purpose: Reads bytes to I2C slave * * Input: char I2CADD: Address of I2C slave to start communication with * * char I2CBYTES: Number of bytes to send * * char*I2CBUFFER: Buffer containing data to send * * Output: 0: Communication did not succeed * * 1: Communication succeeded * ****************************************************************************/ char ReadI2C(RWStruct *IOStruct) //char DevAddr, char NoBytes, char *ReadBuffer); { char Count = 0; char Ptr = 0; char Res = 1; if(IOStruct->WrInProgress == 1){ Res = WaitForWrite(IOStruct->DevAddr & 0xfe, &IOStruct->WrInProgress); }else{ Res = StartI2C( IOStruct->DevAddr & 0xfe); } if(Res == 1){ if(!WriteI2CByte((char) IOStruct->RWAddress / 0x100)) Res = 0; else if(!WriteI2CByte((char) IOStruct->RWAddress % 0x100)) Res = 0; else if(!ReStartI2C(IOStruct->DevAddr | 0x1)) Res = 0; else { Count = IOStruct->NoBytes - 1; for(Ptr = 0; Ptr < Count; Ptr++){ IOStruct->IOBuffer[Ptr] = ReadI2CByte(0); } IOStruct->IOBuffer[Ptr] = ReadI2CByte(1); } StopI2C(); } return Res; }