void I2C_IRQHandler(void) { uint8_t StatValue; /* this handler deals with master read and master write only */ StatValue = I2C_I2CSTAT; switch ( StatValue ) { case 0x08: /* * A START condition has been transmitted. * We now send the slave address and initialize * the write buffer * (we always start with a write after START+SLA) */ WrIndex = 0; I2C_I2CDAT = I2CMasterBuffer[WrIndex++]; I2C_I2CCONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); I2CMasterState = I2CSTATE_PENDING; break; case 0x10: /* * A repeated START condition has been transmitted. * Now a second, read, transaction follows so we * initialize the read buffer. */ RdIndex = 0; /* Send SLA with R bit set, */ I2C_I2CDAT = I2CMasterBuffer[WrIndex++]; I2C_I2CCONCLR = (I2CONCLR_SIC | I2CONCLR_STAC); break; case 0x18: /* * SLA+W has been transmitted; ACK has been received. * We now start writing bytes. */ I2C_I2CDAT = I2CMasterBuffer[WrIndex++]; I2C_I2CCONCLR = I2CONCLR_SIC; break; case 0x20: /* * SLA+W has been transmitted; NOT ACK has been received. * Send a stop condition to terminate the transaction * and signal I2CEngine the transaction is aborted. */ I2C_I2CCONSET = I2CONSET_STO; I2C_I2CCONCLR = I2CONCLR_SIC; I2CMasterState = I2CSTATE_SLA_NACK; break; case 0x28: /* * Data in I2DAT has been transmitted; ACK has been received. * Continue sending more bytes as long as there are bytes to send * and after this check if a read transaction should follow. */ if ( WrIndex < I2CWriteLength ) { /* Keep writing as long as bytes avail */ I2C_I2CDAT = I2CMasterBuffer[WrIndex++]; } else { if ( I2CReadLength != 0 ) { /* Send a Repeated START to initialize a read transaction */ /* (handled in state 0x10) */ I2C_I2CCONSET = I2CONSET_STA;/* Set Repeated-start flag */ } else { I2CMasterState = I2CSTATE_ACK; I2C_I2CCONSET = I2CONSET_STO; /* Set Stop flag */ } } I2C_I2CCONCLR = I2CONCLR_SIC; break; case 0x30: /* * Data byte in I2DAT has been transmitted; NOT ACK has been received * Send a STOP condition to terminate the transaction and inform the * I2CEngine that the transaction failed. */ I2C_I2CCONSET = I2CONSET_STO; I2C_I2CCONCLR = I2CONCLR_SIC; I2CMasterState = I2CSTATE_NACK; break; case 0x38: /* * Arbitration loss in SLA+R/W or Data bytes. * This is a fatal condition, the transaction did not complete due * to external reasons (e.g. hardware system failure). * Inform the I2CEngine of this and cancel the transaction * (this is automatically done by the I2C hardware) */ I2CMasterState = I2CSTATE_ARB_LOSS; I2C_I2CCONCLR = I2CONCLR_SIC; break; case 0x40: /* * SLA+R has been transmitted; ACK has been received. * Initialize a read. * Since a NOT ACK is sent after reading the last byte, * we need to prepare a NOT ACK in case we only read 1 byte. */ if ( I2CReadLength == 1 ) { /* last (and only) byte: send a NACK after data is received */ I2C_I2CCONCLR = I2CONCLR_AAC; } else { /* more bytes to follow: send an ACK after data is received */ I2C_I2CCONSET = I2CONSET_AA; } I2C_I2CCONCLR = I2CONCLR_SIC; break; case 0x48: /* * SLA+R has been transmitted; NOT ACK has been received. * Send a stop condition to terminate the transaction * and signal I2CEngine the transaction is aborted. */ I2C_I2CCONSET = I2CONSET_STO; I2C_I2CCONCLR = I2CONCLR_SIC; I2CMasterState = I2CSTATE_SLA_NACK; break; case 0x50: /* * Data byte has been received; ACK has been returned. * Read the byte and check for more bytes to read. * Send a NOT ACK after the last byte is received */ I2CSlaveBuffer[RdIndex++] = I2C_I2CDAT; if ( RdIndex < (I2CReadLength-1) ) { /* lmore bytes to follow: send an ACK after data is received */ I2C_I2CCONSET = I2CONSET_AA; } else { /* last byte: send a NACK after data is received */ I2C_I2CCONCLR = I2CONCLR_AAC; } I2C_I2CCONCLR = I2CONCLR_SIC; break; case 0x58: /* * Data byte has been received; NOT ACK has been returned. * This is the last byte to read. * Generate a STOP condition and flag the I2CEngine that the * transaction is finished. */ I2CSlaveBuffer[RdIndex++] = I2C_I2CDAT; I2CMasterState = I2CSTATE_ACK; I2C_I2CCONSET = I2CONSET_STO;/* Set Stop flag */ I2C_I2CCONCLR = I2CONCLR_SIC;/* Clear SI flag */ break; /* Slave Mode */ // case 0x60:/* An own SLA_W has been received. */ //case 0x70: // RdIndex = 0; // I2C_I2CCONSET = I2CONSET_AA; /* assert ACK after SLV_W is received */ // I2C_I2CCONCLR = I2CONCLR_SIC; // I2CSlaveState = I2C_WR_STARTED; // break; // //case 0x80:/* data receive */ //case 0x90: // if ( I2CSlaveState == I2C_WR_STARTED ) // { // I2CRdBuffer[RdIndex++] = I2C_I2CDAT; // I2C_I2CCONSET = I2CONSET_AA; /* assert ACK after data is received */ // } // else // { // I2C_I2CCONCLR = I2CONCLR_AAC; /* assert NACK */ // } // // ToDo: Set a flag to indicate data is ready and process it somewhere // I2C_I2CCONCLR = I2CONCLR_SIC; // break; // //case 0xA8:/* An own SLA_R has been received. */ //case 0xB0: // // RdIndex = 0; // WrIndex = I2CRdBuffer[0]; /* The 1st byte is the index. */ // I2C_I2CDAT = I2CRdBuffer[WrIndex+1]; /* write the same data back to master */ // WrIndex++;/* Need to skip the index byte in RdBuffer */ // I2C_I2CCONSET = I2CONSET_AA; /* assert ACK after SLV_R is received */ // I2C_I2CCONCLR = I2CONCLR_SIC; // I2CSlaveState = I2C_RD_STARTED; // break; // //case 0xB8:/* Data byte has been transmitted */ //case 0xC8: // if ( I2CSlaveState == I2C_RD_STARTED ) // { // I2C_I2CDAT = I2CRdBuffer[WrIndex+1]; /* write the same data back to master */ // WrIndex++; /* Need to skip the index byte in RdBuffer */ // I2C_I2CCONSET = I2CONSET_AA; /* assert ACK */ // } // else // { // I2C_I2CCONCLR = I2CONCLR_AAC; /* assert NACK */ // } // I2C_I2CCONCLR = I2CONCLR_SIC; // break; // //case 0xC0:/* Data byte has been transmitted, NACK */ // I2C_I2CCONCLR = I2CONCLR_AAC;/* assert NACK */ // I2C_I2CCONCLR = I2CONCLR_SIC; // I2CSlaveState = DATA_NACK; // break; // //case 0xA0:/* Stop condition or repeated start has */ // I2C_I2CCONSET = I2CONSET_AA; /* been received, assert ACK. */ // I2C_I2CCONCLR = I2CONCLR_SIC; // I2CSlaveState = I2C_IDLE; // break; default: I2C_I2CCONCLR = I2CONCLR_SIC; // if (_I2cMode = I2CSLAVE) // { // I2C_I2CCONSET = I2CONSET_I2EN | I2CONSET_SI; // } break; } return; }