Uploaded by Ajay Mp

i2c

advertisement
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;
}
Download