void __ISR(_I2C_1_VECTOR, ipl3) _SlaveI2CHandler(void) { unsigned char temp; static unsigned int dIndex; // check for MASTER and Bus events and respond accordingly if (IFS1bits.I2C1MIF) { mI2C1MClearIntFlag(); return; } if (IFS1bits.I2C1BIF) {//bus collision, reset I2C state machine I2Cstate = 0; mI2C1BClearIntFlag(); return; } // handle the incoming message if ((I2C1STATbits.R_W == 0) && (I2C1STATbits.D_A == 0)) { // reset any state variables needed by a message sequence // perform a dummy read temp = SlaveReadI2C1(); I2C1CONbits.SCLREL = 1; // release the clock I2Cstate = 0; } else if ((I2C1STATbits.R_W == 0) && (I2C1STATbits.D_A == 1)) {//data received, input to slave WDTCount = 0; WriteTimer1(0); // writing data to our module I2CDataIn = SlaveReadI2C1(); I2C1CONbits.SCLREL = 1; // release clock stretch bit if (I2Cstate == 0 && I2CDataIn != ADDR_CLR_I2C_STATE) { I2Cstate = 1; I2C_request = I2CDataIn; } else if (I2Cstate == 1) { switch (I2C_request) { case ADDR_M3_PWM: M3_Dir = I2CDataIn >> 7 & 0x01;//take top bit if (((Status2 & M3_CUR) && (config1 & CUR_SENSE_EN)) || (config1 & MOTOR_HALT)) { M3_PWM = 0; } else { if (I2CDataIn & 0x80) { mPORTBClearBits(BIT_13); M3_PWM = (((int) ((~I2CDataIn) + 1)) << 4); } else { mPORTBSetBits(BIT_13); M3_PWM = ((int) I2CDataIn) << 4; } } SetDCOC4PWM(M3_PWM); break; case ADDR_M4_PWM: M4_Dir = I2CDataIn >> 7 & 0x01;//take top bit if (((Status2 & M4_CUR) && (config1 & CUR_SENSE_EN)) || (config1 & MOTOR_HALT)) { M4_PWM = 0; } else { if (I2CDataIn & 0x80) { mPORTBClearBits(BIT_14); M4_PWM = (((int) ((~I2CDataIn) + 1)) << 4); } else { mPORTBSetBits(BIT_14); M4_PWM = ((int) I2CDataIn) << 4; } } SetDCOC5PWM(M4_PWM); break; case ADDR_M5_PWM: M5_Dir = I2CDataIn >> 7 & 0x01;//take top bit if (((Status2 & M5_CUR) && (config1 & CUR_SENSE_EN)) || (config1 & MOTOR_HALT)) { M5_PWM = 0; } else { if (I2CDataIn & 0x80) { mPORTBClearBits(BIT_15); M5_PWM = (((int) ((~I2CDataIn) + 1)) << 4); } else { mPORTBSetBits(BIT_15); M5_PWM = ((int) I2CDataIn) << 4; } } SetDCOC3PWM(M5_PWM); break; case ADDR_M6_PWM: M6_Dir = I2CDataIn >> 7 & 0x01;//take top bit if (((Status2 & M6_CUR) && (config1 & CUR_SENSE_EN)) || (config1 & MOTOR_HALT)) { M6_PWM = 0; } else { if (I2CDataIn & 0x80) { mPORTBClearBits(BIT_11); M6_PWM = (((int) ((~I2CDataIn) + 1)) << 4); } else { mPORTBSetBits(BIT_11); M6_PWM = ((int) I2CDataIn) << 4; } } SetDCOC2PWM(M6_PWM); break; case ADDR_M7_PWM: M7_Dir = I2CDataIn >> 7 & 0x01;//take top bit if (((Status2 & M7_CUR) && (config1 & CUR_SENSE_EN)) || (config1 & MOTOR_HALT)) { M7_PWM = 0; } else { if (I2CDataIn & 0x80) { mPORTBClearBits(BIT_7); M7_PWM = (((int) ((~I2CDataIn) + 1)) << 4); } else { mPORTBSetBits(BIT_7); M7_PWM = ((int) I2CDataIn) << 4; } } SetDCOC1PWM(M7_PWM); break; case ADDR_Config1: config1 = I2CDataIn; if (config1 & MOTOR_HALT) { SetDCOC1PWM(0); SetDCOC2PWM(0); SetDCOC3PWM(0); SetDCOC4PWM(0); SetDCOC5PWM(0); } else { SetDCOC1PWM(M7_PWM); SetDCOC2PWM(M6_PWM); SetDCOC3PWM(M5_PWM); SetDCOC4PWM(M3_PWM); SetDCOC5PWM(M4_PWM); } break; default: break; } I2Cstate = 0; } } else if ((I2C1STATbits.R_W == 1) && (I2C1STATbits.D_A == 0)) {
/** * Function Name: SI2C1Interrupt * Description : This is the ISR for I2C1 Slave interrupt. */ void __ISR(_I2C_1_VECTOR, ipl3) _SlaveI2CHandler(void) { // TODO : Find the right i2cBusConnection I2cBusConnection* i2cBusConnection = NULL; // last byte received is address and not data char isData = I2C1STATbits.D_A; char read = I2C1STATbits.R_W; char isStart = I2C1STATbits.S; char isSclRelease = I2C1CONbits.SCLREL; char readBufferFull = I2C1STATbits.RBF; // check for MASTER and Bus events and respond accordingly if (IFS0bits.I2C1MIF == 1) { mI2C1MClearIntFlag(); return; } if (IFS0bits.I2C1BIF == 1) { mI2C1BClearIntFlag(); return; } StreamLink* i2cStreamLink = getI2cStreamLink(); // handle the incoming message // Master want to write and send the address if (isStart && !read && !isData && readBufferFull) { // R/W bit = 0 --> indicates data transfer is input to slave // D/A bit = 0 --> indicates last byte was address // reset any state variables needed by a message sequence // perform a dummy read of the address portableSlaveReadI2C(i2cBusConnection); // release the clock to restart I2C portableSlaveClockRelease(i2cBusConnection); } // Master WRITE (InputStream) else if (isStart && !read && isData && readBufferFull) { // R/W bit = 0 --> indicates data transfer is input to slave // D/A bit = 1 --> indicates last byte was data int data = portableSlaveReadI2C(i2cBusConnection); Buffer* i2cSlaveInputBuffer = i2cStreamLink->inputBuffer; OutputStream* outputStream = getOutputStream(i2cSlaveInputBuffer); // Read data from the Master append(outputStream, data); // for debug support appendI2cDebugInputChar(data); // release the clock to restart I2C portableSlaveClockRelease(i2cBusConnection); } // Master send the address and want to read else if (isStart && read && !isData) { // R/W bit = 1 --> indicates data transfer is output from slave // D/A bit = 0 --> indicates last byte was address portableSlaveReadI2C(i2cBusConnection); Buffer* i2cSlaveOutputBuffer = i2cStreamLink->outputBuffer; // Get an inputStream to read the buffer to send to the master InputStream* i2cInputStream = getInputStream(i2cSlaveOutputBuffer); // There is available data if (i2cInputStream->availableData(i2cInputStream)) { char c = i2cInputStream->readChar(i2cInputStream); // for debug support appendI2cDebugOutputChar(c); portableSlaveWriteI2C(i2cBusConnection, c); } else { portableSlaveWriteI2C(i2cBusConnection, I2C_SLAVE_NO_DATA_IN_READ_BUFFER); } } // Master want to read else if (isStart && read && isData && !isSclRelease) { // R/W bit = 1 --> indicates data transfer is output from slave // D/A bit = 1 --> indicates last byte was data Buffer* i2cSlaveOutputBuffer = i2cStreamLink->outputBuffer; // Get an inputStream to read the buffer to send to the master InputStream* i2cInputStream = getInputStream(i2cSlaveOutputBuffer); // There is available data if (i2cInputStream->availableData(i2cInputStream)) { char c = i2cInputStream->readChar(i2cInputStream); // for debug support appendI2cDebugInputChar(c); // we send it to the master portableSlaveWriteI2C(i2cBusConnection, c); } else { // There is no data, we send it to the master portableSlaveWriteI2C(i2cBusConnection, I2C_SLAVE_NO_DATA_IN_READ_BUFFER); } } // finally clear the slave interrupt flag mI2C1SClearIntFlag(); }