char sendMessage(char devAddress, char address, char* data, char length, char rw) { char rData = 0; I2CIdle(); I2C2CONbits.SEN = 1; //Send Start condition I2CIdle(); //SET Slave Address & write (Address shifted one bit left and then the write(0) bit is added) I2C2TRN = devAddress << 1; //If reading, the read process is specified after the dummy bytes. if (rw == READ) //If in reading mode { rData = readMessage(devAddress, address); } else //Otherwise go into writing mode { writeMessage(address,data, length); } I2CIdle(); I2C2CONbits.PEN = 1; //Send Stop condition I2CIdle(); return rData; }
//================================================================== uint I2CMasterReadByte(byte* data, uint Flag) { I2CIdle(); // Wait for bus to be idle I2C_RCEN = 1; // Put module into READ mode while(I2C_RCEN); // Wait until byte is received if (I2C_I2COV) // Overflow? { I2C_I2COV = 0; // Reset overflow condition return I2CRC_OVFL; // return error... } while(!I2C_RBF); // Wait for byte to be ready in receive // register - Excessive check, but... (*data) = I2C_RCV_Reg; // return byte to caller //-------------------------------- if(Flag == 0) { // If last char, generate NACK sequence I2C_ACKDT = 1; I2C_ACKEN = 1; } else { // For other chars,generate ACK sequence I2C_ACKDT = 0; I2C_ACKEN = 1; } //-------------------------------- I2CIdle(); // Ensure module is idle // ACK/NACK transmitted //------------------------------------------------------------------ return I2CRC_OK; // Byte successfully transferred }
//================================================================== uint I2CMasterWriteByte(byte data) { I2CIdle(); // Wait for bus to be idle while(I2C_TBF); // Wait till transmit register is empty I2C_TRM_Reg = data; // Put data byte into transmit register if(I2C_IWCOL) // Check for write collision return I2CRC_WCOL; // Return error... while(I2C_TRSTAT); // Wait until write cycle is complete I2CIdle(); // Ensure module is idle if ( I2C_ACKSTAT ) // Test for ACK condition received return I2CRC_NACK; // NACK... //------------------------------------------------------------------ return I2CRC_OK; // Byte successfully transferred }
//================================================================== void I2CReStart(_I2C_CB* pCB) { I2CIdle(pCB); // Wait for bus to be Idle //----------------------------------------------------- I2CpCON(pCB)->RSEN = 1; // Initiate Repeated Start on SDA // and SCL pins }
void writeMessage(char address, char* data, char length) { I2CIdle(); I2C2TRN = address; //Then after it is free, write the address. // I2CIdle();//Check until transmition was completed //Write each byte of data int i = 0; for(i = 0; i < length; i++) { I2CIdle();//Check until transmition was completed I2C2TRN = (char)data[i]; } }
//================================================================== uint I2CMasterReadByte(_I2C_CB* pCB, byte* data, uint Flag) { I2CIdle(pCB); // Wait for bus to be Idle //----------------------------------------------------- I2C_CONBITS* pCON = I2CpCON(pCB); I2C_STATBITS* pSTAT = I2CpSTAT(pCB); //----------------------------------------------------- *(pCB->pI2C_STAT) = 0; // Reset Status byte //----------------------------------------------------- pCON->RCEN = 1; // Put module into READ mode while(pCON->RCEN); // Wait until byte is received if (pSTAT->I2COV) // Overflow? { pSTAT->I2COV = 0; // Reset overflow condition return I2CRC_OVFL; // return error... } if (pSTAT->BCL) // Bus collision? { pSTAT->BCL = 0; // Reset bus collision condition return I2CRC_BCOL; // return error... } while(!pSTAT->RBF); // Wait for byte to be ready in receive // register - Excessive check, but... (*data) = *(pCB->pI2C_RCV); // return byte to caller //-------------------------------- // Set Acknowledge (ACK or NACK) code //-------------------------------- if(Flag == 0) // If last char, generate NACK sequence pCON->ACKDT = 1; else // For other chars,generate ACK sequence pCON->ACKDT = 0; //-------------------------------- pCON->ACKEN = 1; // Initiate Acknowledge Sequence //-------------------------------- I2CIdle(pCB); // Ensure module is idle // ACK/NACK transmitted //------------------------------------------------------------------ return I2CRC_OK; // Byte successfully transferred }
//================================================================== uint I2CMasterWriteByte(_I2C_CB* pCB, byte data) { I2CIdle(pCB); // Wait for bus to be Idle //----------------------------------------------------- I2C_STATBITS* pSTAT = I2CpSTAT(pCB); //----------------------------------------------------- while(pSTAT->TBF); // Wait till transmit register // is empty (available) //----------------------------------------------------- *(pCB->pI2C_STAT) = 0; // Reset Status byte //----------------------------------------------------- *(pCB->pI2C_TRN) = data; // Put data byte into transmit register if(pSTAT->IWCOL) // Check for write collision return I2CRC_WCOL; // Return error... while(pSTAT->TRSTAT); // Wait until write cycle is complete //----------------------------------------------------- I2CIdle(pCB); // Ensure module is idle //----------------------------------------------------- if ( pSTAT->ACKSTAT ) // Test for ACK condition received return I2CRC_NACK; // NACK... //------------------------------------------------------------------ return I2CRC_OK; // Byte successfully transferred }
char checkDevicePresence(char devAddress, char reg){ char connected = 0; int count = 0; char data = 0; I2C2CONbits.SEN = 1; //Send Start condition I2CIdle(); //SET Slave Address & write (Address shifted one bit left and then the write(0) bit is added) I2C2TRN = devAddress << 1; //If reading, the read process is specified after the dummy bytes. I2CIdle(); I2C2TRN = reg; //Then after it is free, write the local address. I2CIdle(); //Wait until acknowledge is sent from the slave I2C2CONbits.RSEN = 1; //Resend the start condition I2CIdle(); //Wait until acknowledge is sent from the slave I2C2TRN = (devAddress << 1) + 1; //Shift and add the read bit(1) - Prep for restart I2CIdle(); //Wait until acknowledge is sent from the slave ///THE MESSAGE FROM THE SLAVE IS SENT HERE I2C2CONbits.RCEN = 1; //Enable receive mode I2CIdle(); //Wait until all 8 bits have been acquired while (I2C2STATbits.RBF != 1 && count < 0x0FFF)count++; data = I2C2RCV; //Send back a NACK I2C2CONbits.ACKDT = 1; //Send NACK I2C2CONbits.ACKEN = 1; //Start the acknowledge sequence I2CIdle(); //Wait until done if (data){ connected = 1; } else{ connected = 0; } I2C2CONbits.PEN = 1; while((I2C2CON & 0x1F ) || I2C2STATbits.TRSTAT == 1); return connected; }
char readMessage(char devAddress, char address) { I2CIdle(); I2C2TRN = address; //Then after it is free, write the local address. I2CIdle(); //Wait until acknowledge is sent from the slave I2C2CONbits.RSEN = 1; //Resend the start condition I2CIdle(); //Wait until acknowledge is sent from the slave I2C2TRN = (devAddress << 1) + 1; //Shift and add the read bit(1) - Prep for restart I2CIdle(); //Wait until acknowledge is sent from the slave ///THE MESSAGE FROM THE SLAVE IS SENT HERE I2C2CONbits.RCEN = 1; //Enable receive mode I2CIdle(); //Wait until all 8 bits have been acquired while (I2C2STATbits.RBF != 1); char data = I2C2RCV; //Send back a NACK I2C2CONbits.ACKDT = 1; //Send NACK I2C2CONbits.ACKEN = 1; //Start the acknowledge sequence I2CIdle(); //Wait until done return data; }
//================================================================== void I2CStop() { I2CIdle(); I2C_PEN = 1; // Initiate Stop on SDA and SCL pins }
//================================================================== void I2CReStart() { I2CIdle(); I2C_RSEN = 1; // Initiate Repeated Start on SDA and SCL pins }
//================================================================== void I2CStart() { I2CIdle(); I2C_SEN = 1; // Initiate Start on SDA and SCL pins }
//================================================================== void I2CStop(_I2C_CB* pCB) { I2CIdle(pCB); // Wait for bus to be Idle //----------------------------------------------------- I2CpCON(pCB)->PEN = 1; // Initiate Stop on SDA and SCL pins }