void LDWordReadI2C(unsigned char SlaveAddress, unsigned char reg, unsigned char *data1, unsigned char *data2){ StartI2C2(); //Send the Start Bit IdleI2C2(); //Wait to complete MasterWriteI2C2(SlaveAddress); //transmit write command IdleI2C2(); //Wait to complete MasterWriteI2C2(reg); IdleI2C2(); StopI2C2(); IdleI2C2(); StartI2C2(); //Send the Start Bit IdleI2C2(); //Wait to complete MasterWriteI2C2(SlaveAddress|0x01); //transmit read command IdleI2C2(); //Wait to complete unsigned char data[2]; MastergetsI2C2(2, data, 30); // "MCHP I2C" *data1=data[0]; *data2=data[1]; // if (status!=0) // while(1); StopI2C2(); //Send the Stop condition IdleI2C2(); //Wait to complete }
signed char EEAckPolling2( unsigned char control ) { IdleI2C2(); // ensure module is idle StartI2C2(); // initiate START condition while ( SSP2CON2bits.SEN ); // wait until start condition is over #if defined (I2C_V3) || defined (I2C_V6) if ( PIR3bits.BCL2IF ) // test for bus collision #elif defined (I2C_V6_1) if ( PIR2bits.BCL2IF ) // test for bus collision #endif { return ( -1 ); // return with Bus Collision error } else { if ( WriteI2C2( control ) == -1) // write byte - R/W bit should be 0 { StopI2C2(); return ( -3 ); // set error for write collision } while ( SSP2CON2bits.ACKSTAT ) // test for ACK condition received { RestartI2C2(); // initiate Restart condition while ( SSP2CON2bits.RSEN ); // wait until re-start condition is over #if defined (I2C_V3) || defined (I2C_V6) if ( PIR3bits.BCL2IF ) // test for bus collision #elif defined (I2C_V6_1) if ( PIR2bits.BCL2IF ) // test for bus collision #endif { return ( -1 ); // return with Bus Collision error } if ( WriteI2C2( control ) == -1) // write byte - R/W bit should be 0 { StopI2C2(); return ( -3 ); // set error for write collision } } } StopI2C2(); // send STOP condition while ( SSP2CON2bits.PEN ); // wait until stop condition is over #if defined (I2C_V3) || defined (I2C_V6) if ( PIR3bits.BCL2IF ) // test for bus collision #elif defined (I2C_V6_1) if ( PIR2bits.BCL2IF ) // test for bus collision #endif { return ( -1 ); // return with Bus Collision error } return ( 0 ); // return with no error }
int RcvIMUData(unsigned int reg_addr) { // //see page 92 of https://www.adafruit.com/datasheets/BST_BNO055_DS000_12.pdf rcv = 0; StartI2C2(); //Send line start condition IdleI2C2(); //Wait to complete MasterWriteI2C2(0x50); //Write slave addr WRITE (OR 0) IdleI2C2(); MasterWriteI2C2(reg_addr); //BNO055_QUATERNION_DATA_W_LSB_ADDR IdleI2C2(); RestartI2C2(); IdleI2C2(); MasterWriteI2C2(0x51); //Write the slave address, READ (OR 1) IdleI2C2(); rcv |= MasterReadI2C2(); //Read in LSB IdleI2C2(); AckI2C2(); IdleI2C2(); rcv |= MasterReadI2C2()<<8; //Read in MSB NotAckI2C2(); IdleI2C2(); StopI2C2(); //Send line stop condition IdleI2C2(); return rcv; }
/** * Reads temperature from IR sensor of an object in front of sensor * @return A hex value from 0x27AD (-70 ?C) to 0x7fff (382.19?C) */ int RcvIRTemp(void){ rcv = 0; StartI2C2(); //Send line start condition IdleI2C2(); //Wait to complete MasterWriteI2C2(0xb4); //Write slave addr WRITE (OR 0) IdleI2C2(); MasterWriteI2C2(0x07); //0x07 = read RAM for TObj1 temperature IdleI2C2(); RestartI2C2(); IdleI2C2(); MasterWriteI2C2(0xb5); //Write the slave address, READ (OR 1) IdleI2C2(); rcv |= MasterReadI2C2(); //Read in LSB IdleI2C2(); AckI2C2(); //Acknowledge LSB IdleI2C2(); rcv |= MasterReadI2C2()<<8; //Read in MSB AckI2C2(); //Acknowledge MSB IdleI2C2(); MasterReadI2C2(); //Read in PEC AckI2C2(); //Acknowledge MSB IdleI2C2(); StopI2C2(); //Send line stop condition IdleI2C2(); return rcv; //Return read value }
S8 I2C2_WRITE_String(U8 DevAdd, U8 RegAdd, U8 *RegValue, U8 len) { char ComRes; DevAdd = (DevAdd<<1)|M_I2C_Write; StartI2C2(); // Send the start bit IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement ComRes=MasterWriteI2C2(DevAdd); // Adress with write mode IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement ComRes=MasterWriteI2C2(RegAdd); // Write the chip ID register loaction for read IdleI2C2(); // Send the start bit while(I2C2STATbits.ACKSTAT); //wait for acknowledgement while(len--) { ComRes=MasterWriteI2C2(*RegValue); // Write the chip ID register loaction for read IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement RegValue++; } StopI2C2(); // Stop the I2C communication IdleI2C2(); // Wait to complete return ComRes; }
char I2C2_READ_String(U8 DevAdd, U8 RegAdd, U8 *RegValue, U8 len) { int DataWait = len*100; char ComRes,DevAddr; DevAddr = (DevAdd<<1)|M_I2C_Write; StartI2C2(); // Send the start bit IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement ComRes=MasterWriteI2C2(DevAddr); // Adress with write mode IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement ComRes=MasterWriteI2C2(RegAdd); // Write the chip ID register loaction for read IdleI2C2(); // Send the start bit while(I2C2STATbits.ACKSTAT); //wait for acknowledgement RestartI2C2(); // Send the start bit IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement DevAddr = (DevAdd<<1)|M_I2C_Read; MasterWriteI2C2(DevAddr); // Adress with write mode IdleI2C2(); // Wait to complete while(I2C2STATbits.ACKSTAT); //wait for acknowledgement MastergetsI2C2(len, RegValue, DataWait); // Read the Register value IdleI2C2(); // Wait to complete NotAckI2C2(); // Not Acknowledge I2C IdleI2C2(); // Wait to complete StopI2C2(); // Stop I2C communication IdleI2C2(); // Wait to complete; return ComRes; }
/***************************************************** * RcvData(unsigned int address) * * * * Gets a byte of data from I2C slave device at * * ADDRESS. * * * * Returns: Received data * ****************************************************/ int RcvData(unsigned int address) { StartI2C2(); //Send line start condition IdleI2C2(); //Wait to complete MasterWriteI2C2((address << 1) | 1); //Write out slave address OR 1 (read command) IdleI2C2(); //Wait to complete rcv = MasterReadI2C2(); //Read in a value IdleI2C2(); AckI2C2(); IdleI2C2(); StopI2C2(); //Send line stop condition IdleI2C2(); //Wait co complete return rcv; //Return read value }
void LDWordWriteI2C(unsigned char SlaveAddress, unsigned char reg, unsigned char data1, unsigned char data2){ StartI2C2(); //Send the Start Bit IdleI2C2(); //Wait to complete MasterWriteI2C2(SlaveAddress); //transmit write command IdleI2C2(); //Wait to complete MasterWriteI2C2(reg); IdleI2C2(); MasterWriteI2C2(data1); IdleI2C2(); MasterWriteI2C2(data2); IdleI2C2(); StopI2C2(); IdleI2C2(); }
void sleepIRTemp(){ StartI2C2(); //Send line start condition IdleI2C2(); //Wait to complete MasterWriteI2C2(0xb4); //Write slave addr WRITE (OR 0) IdleI2C2(); MasterWriteI2C2(0xff); //sleep command IdleI2C2(); MasterReadI2C2(); //Read in PEC IdleI2C2(); AckI2C2(); //Acknowledge PEC IdleI2C2(); StopI2C2(); }
void SendIMUData (int reg_addr, int data){ StartI2C2(); //Send the Start Bit IdleI2C2(); //Wait to complete MasterWriteI2C2(0x50); //Sends the slave address over the I2C line. IdleI2C2(); //Wait to complete MasterWriteI2C2(reg_addr); //Sends data byte over I2C line IdleI2C2(); //Wait to complete MasterWriteI2C2(data); IdleI2C2(); //wait for ack StopI2C2(); //Send the Stop condition IdleI2C2(); //Wait to complete }
int RcvIRTemp(unsigned int address){ rcv = 0; StartI2C2(); //Send line start condition IdleI2C2(); //Wait to complete MasterWriteI2C2(0xb4); //Write slave addr WRITE (OR 0) IdleI2C2(); MasterWriteI2C2(0xf0); //command // //Command to read Tobj1 on ir sensor's ram: 000 = read ram; 0x07 = tobj1 IdleI2C2(); //Wait to complete // StopI2C2(); //restart // IdleI2C2(); // StartI2C2(); // IdleI2C2(); // // MasterWriteI2C2(0xb5); //Write the slave address, READ (OR 1) // IdleI2C2(); MasterReadI2C2(); //Read in LSB IdleI2C2(); AckI2C2(); //Acknowledge LSB IdleI2C2(); MasterReadI2C2(); //Read in MSB IdleI2C1(); AckI2C2(); //Acknowledge MSB IdleI2C2(); MasterReadI2C2(); //Read in PEC IdleI2C1(); AckI2C2(); //Acknowledge MSB IdleI2C2(); StopI2C2(); //Send line stop condition IdleI2C2(); //Wait co complete return rcv; //Return read value }
/***************************************************************************** * Function Name : gyroEndTx * Description : End I2C transmission * Parameters : None * Return Value : None *****************************************************************************/ static inline void gyroEndTx(void) { StopI2C2(); while(I2C2CONbits.PEN); }
/****************************************************************************** * Function: void Init_IOExpander(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: MACInit enables the Ethernet module, waits for the * to become ready, and programs all registers for future * TX/RX operations. * * Note: This function blocks for at least 1ms, waiting for the * hardware to stabilize. *****************************************************************************/ void Init_IOExpander(void) { while (Return_Val == Busy) { switch ( CMI ) { case INIT : // Clear MCLR pins of the IOexpanders IO_Expander_Enable = True; // Give the IO expander some time after de-reset Delay1KTCYx(10); // Use MSSP2 the pins of this module are connected to RD5 and RD6, // all calls to I2C lib must be nummerated with 2 : OpenI2C2 _ //---INITIALISE THE I2C MODULE FOR MASTER MODE WITH 100KHz --- OpenI2C2(MASTER,SLEW_ON); //400kHz Baud clock @41.667MHz = 0x19 // 100kHz Baud clock @41.667MHz = 0x67 // 1MHz Baud clock @41.667MHz = 0x09 // 1.7MHzBaud clock @41.667MHz = 0x05 SSP2ADD=0x09; //read any previous stored content in buffer to clear buffer full status EXPNDNQ data = SSP2BUF; //init Active_IOEXP with te number of total IOexpanders Active_IOEXP = 0; CMI = START; break; case START : switch ( CMI2 ) { case INIT : if ( (Active_IOEXP >= EXPNDNQ)) { Return_Val = Finished; CMI = INIT; CMI2 = INIT; Active_IOEXP = 0; break; } Active_REG = 0; Active_DATA = 0; CMI2 = IDLE; break; case IDLE : if ( Active_REG >= WRITE_REG ) { CMI2 = INIT; Active_IOEXP++; break; } CMI = IDLE; CMI2 = STARTI2C; break; case STARTI2C: StartI2C2(); CMI2 = WRITE1; break; case WRITE1 : CMI = ADDR; CMI2 = WRITE2; break; case WRITE2 : CMI = REG; CMI2 = WRITE3; break; case WRITE3 : CMI = DATAOUT; CMI2 = STOPI2C; break; case STOPI2C : Active_REG++; Active_DATA++; StopI2C2(); CMI2 = RSTRTI2C; break; case RSTRTI2C: RestartI2C2(); CMI2 = IDLE; break; default : break; } break; case IDLE : switch ( Return_Val_Routine = IdleI2C2() ) //check for bus idle condition in multi master communication { case Finished : CMI = START; break; case Busy : CMI = IDLE; break; default : CMI = IDLE; break; } break; case ADDR : switch ( Return_Val_Routine = WriteI2C2 (IOEXP[Active_IOEXP].GADDR) ) { case Finished : CMI = START; break; case Busy : CMI = ADDR; break; default : CMI = ADDR; break; } break; case REG : switch ( Return_Val_Routine = WriteI2C2 (GREG[Active_REG]) ) { case Finished : CMI = START; break; case Busy : CMI = REG; break; default : CMI = REG; break; } break; case DATAOUT : switch ( Return_Val_Routine = WriteI2C2 (IOEXP[Active_IOEXP].GDATA[Active_DATA]) ) { case Finished : CMI = START; break; case Busy : CMI = DATAOUT; break; default : CMI = DATAOUT; break; } break; default : break; } } }
/****************************************************************************** * Function: void IOExpander(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: MACInit enables the Ethernet module, waits for the * to become ready, and programs all registers for future * TX/RX operations. * * Note: This function blocks for at least 1ms, waiting for the * hardware to stabilize. *****************************************************************************/ void IOExpander(void) { switch ( CMR ) { case INIT : //init Active_IOEXP with te number of total IOexpanders Active_IOEXP = 0; CMR2 = INIT; CMR = NOPP; PORTK = 0x00; PORTL = 0x00; break; case START : switch ( CMR2 ) { case INIT : if ( (Active_IOEXP >= EXPNDNQ)) { CMR = NOPP; CMR2 = INIT; Active_IOEXP = 0; break; } Active_REG = 0x00; Active_DATA = 0x00; Active_PORT = 0x00; CMR2 = IDLE; break; case IDLE : if ( Active_PORT >= 2 ) { CMR2 = INIT; Active_IOEXP++; break; } CMR = IDLE; CMR2 = STARTI2C; break; case STARTI2C: StartI2C2(); CMR2 = WRITE1; break; case WRITE1 : if (IOEXP[Active_IOEXP].GDATA[Active_PORT]== 0xFF) { IOEXP[Active_IOEXP].GADDR &= READ; } else { IOEXP[Active_IOEXP].GADDR &= WRITE; } CMR = ADDR; CMR2 = WRITE2; break; case WRITE2 : if ( Active_PORT ) { Active_REG = 15; } else { Active_REG = 14; } CMR = REG; CMR2 = WRITE3; break; case WRITE3 : switch ( Active_PORT ) { case 0 : if ( IOEXP[Active_IOEXP].GDATA[Active_PORT]== 0xFF ) { Active_DATA = 14; CMR = DATAIN; CMR2 = STOPI2C; break; } else { Active_DATA = 14; CMR = DATAOUT; CMR2 = STOPI2C; break; } case 1 : if ( IOEXP[Active_IOEXP].GDATA[Active_PORT]== 0xFF ) { Active_DATA = 15; CMR = DATAIN; CMR2 = STOPI2C; break; } else { Active_DATA = 15; CMR = DATAOUT; CMR2 = STOPI2C; break; } default : break; } break; case STOPI2C: Active_PORT++; StopI2C2(); CMR2 = RSTRTI2C; break; case RSTRTI2C: RestartI2C2(); CMR2 = IDLE; break; default : break; } break; case IDLE : switch ( Return_Val_Routine = IdleI2C2() ) //check for bus idle condition in multi master communication { case Finished : CMR = START; break; case Busy : CMR = IDLE; break; default : CMR = IDLE; break; } break; case ADDR : switch ( Return_Val_Routine = WriteI2C2 (IOEXP[Active_IOEXP].GADDR) ) { case Finished : CMR = START; break; case Busy : CMR = ADDR; break; default : CMR = ADDR; break; } break; case REG : switch ( Return_Val_Routine = WriteI2C2 (GREG[Active_REG]) ) { case Finished : CMR = START; break; case Busy : CMR = REG; break; default : CMR = REG; break; } break; case DATAOUT: switch ( Return_Val_Routine = WriteI2C2 (IOEXP[Active_IOEXP].GDATA[Active_DATA]) ) { case Finished : CMR = START; break; case Busy : CMR = DATAOUT; break; default : CMR = DATAOUT; break; } break; case DATAIN : switch ( Return_Val_Routine2 = ReadI2C2 () ) { case Busy : CMR = DATAIN; break; default : IOEXP[Active_IOEXP].GDATA[Active_DATA] = Return_Val_Routine2; CMR = START; break; } break; case NOPP : if ( IOExpander_Updater == True ) { CMR = START; IOExpander_Updater = True; //Led5 = !Led5; PORTK = !PORTK; PORTL = !PORTL; break; } IOExpander_Updater = True; break; default : break; } }
void i2cEndTx(unsigned char channel){ if (channel == 1) { StopI2C1(); while(I2C1CONbits.PEN); } else { StopI2C2(); while(I2C2CONbits.PEN); } }
unsigned int EERandomRead2( unsigned char control, unsigned char address ) { IdleI2C2(); // ensure module is idle StartI2C2(); // initiate START condition while ( SSP2CON2bits.SEN ); // wait until start condition is over #if defined (I2C_V3) || defined (I2C_V6) if ( PIR3bits.BCL2IF ) // test for bus collision #elif defined (I2C_V6_1) if ( PIR2bits.BCL2IF ) // test for bus collision #endif { return ( -1 ); // return with Bus Collision error } else { if ( WriteI2C2( control ) ) // write 1 byte { StopI2C2(); return ( -3 ); // return with write collision error } //IdleI2C2(); // ensure module is idle if ( !SSP2CON2bits.ACKSTAT ) // test for ACK condition, if received { if ( WriteI2C2( address ) ) // WRITE word address for EEPROM { StopI2C2(); return ( -3 ); // return with write collision error } //IdleI2C2(); // ensure module is idle if ( !SSP2CON2bits.ACKSTAT ) // test for ACK condition, if received { RestartI2C2(); // generate I2C bus restart condition while ( SSP2CON2bits.RSEN );// wait until re-start condition is over #if defined (I2C_V3) || defined (I2C_V6) if ( PIR3bits.BCL2IF ) // test for bus collision #elif defined (I2C_V6_1) if ( PIR2bits.BCL2IF ) // test for bus collision #endif { return ( -1 ); // return with Bus Collision error } if ( WriteI2C2( control+1 ))// write 1 byte - R/W bit should be 1 { StopI2C2(); return ( -3 ); // return with write collision error } //IdleI2C2(); // ensure module is idle if ( !SSP2CON2bits.ACKSTAT )// test for ACK condition, if received { SSP2CON2bits.RCEN = 1; // enable master for 1 byte reception while ( SSP2CON2bits.RCEN ); // check that receive sequence is over NotAckI2C2(); // send ACK condition while ( SSP2CON2bits.ACKEN ); // wait until ACK sequence is over StopI2C2(); // send STOP condition while ( SSP2CON2bits.PEN ); // wait until stop condition is over #if defined (I2C_V3) || defined (I2C_V6) if ( PIR3bits.BCL2IF ) // test for bus collision #elif defined (I2C_V6_1) if ( PIR2bits.BCL2IF ) // test for bus collision #endif { return ( -1 ); // return with Bus Collision error } } else { StopI2C2(); return ( -2 ); // return with Not Ack error } } else { StopI2C2(); return ( -2 ); // return with Not Ack error } } else { StopI2C2(); return ( -2 ); // return with Not Ack error } } return ( (unsigned int) SSP2BUF ); // return with data }