📄 twi_lib.lst
字号:
*****************************************************************************/
void I2C_decode_status (void)
{
switch (SSSTA)
{
// STATE 00h: Bus Error has occurred
// ACTION: Enter not addressed SLV mode and release bus
case 0x00 :
b_I2C_busy = FALSE;
I2C_Err = BusError;
break;
//STATE 08h: A start condition has been sent
//ACTION: SLR+R/W are transmitted, ACK bit received
case 0x08 :
I2C_CLEAR_START;
SSDAT = I2C_message.address<<1;
if ( I2C_message.rw == I2C_READ ) SSDAT++; // Add 1 for Read bit in AdrWord
I2C_SET_AA;
//from here to 0x18 transmit or 0x40 receive
C51 COMPILER V7.50 TWI_LIB 02/16/2009 09:59:54 PAGE 5
break;
//STATE 10h: A repeated start condition has been sent
//ACTION: SLR+R/W are transmitted, ACK bit received
case 0x10 :
I2C_CLEAR_START; // Reset STA bit in SSCON
SSDAT = I2C_message.address<<1;
if ( I2C_message.rw == I2C_READ ) SSDAT++; // Add 1 for Read bit in AdrWord
I2C_SET_AA; //wait on ACK bit
break;
//STATE 18h: SLR+W was transmitted, ACK bit received
//ACTION: Transmit data byte, ACK bit received
//PREVIOUS STATE: 0x08 or 0x10
case 0x18 : //master transmit, after sending
I2C_nb_transmited=0; //slave address, now load data
SSDAT = *(I2C_message.buf); //byte and send it
I2C_SET_AA; //wait on ACK bit
break;
//STATE 20h: SLR+W was transmitted, NOT ACK bit received
//ACTION: Transmit STOP
case 0x20 :
I2C_SET_STOP;
b_I2C_busy = FALSE;
I2C_Err = NoHostAdrAck;
break;
//STATE 28h: DATA was transmitted, ACK bit received
//ACTION: If last byte, send STOP, else send more data bytes
case 0x28 : //master transmit, after sending
//data byte, ACK received
I2C_nb_transmited++; // inc nb data transmit on message
I2C_message.buf++; // inc pointer ti data to be transmited
if ( I2C_nb_transmited < I2C_message.nbbytes ) //if there are still bytes to send
{
SSDAT = *(I2C_message.buf);
I2C_SET_AA; //wait on ACK bit
}
else
{ //run out of data, send stop,
I2C_SET_STOP;
I2C_Err = Tranfer_OK;
b_I2C_busy = FALSE; //transfer complete, clear b_I2C_busy
}
break;
//STATE 30h: DATA was transmitted, NOT ACK bit received
//ACTION: Transmit STOP
case 0x30 :
I2C_SET_STOP;
b_I2C_busy = FALSE;
I2C_Err = NoHostDataAck;
break;
//STATE 38h: Arbitration lost in SLA+W or DATA.
//ACTION: Release bus, enter not addressed SLV mode
// Wait for bus lines to be free
case 0x38 :
b_I2C_busy = FALSE;
I2C_Err = ArbitrationLost;
/*
C51 COMPILER V7.50 TWI_LIB 02/16/2009 09:59:54 PAGE 6
#ifdef USER_I2C_FCT_ARBITRATION_LOST_IN_SLA+W_OR_DATA
I2C_fct_arb_lostinSLAorDATA();
#endif
*/
break;
//MASTER RECEIVER MODE FOLLOWS
//STATE 40h: SLA+R transmitted, ACK received
//ACTION: Receive DATA, ACK to be returned
//PREVIOS STATE: 0x08 or 0x10
case 0x40 : //master receive, after sending
if ( I2C_message.nbbytes == 1 )
{
I2C_CLEAR_AA; // only one data to receive, noACK to be send after the fisrt incoming data
}
else
{
I2C_SET_AA; //wait on ACK bit
I2C_nb_transmited=0; //data byte to be received, NOT ACK bit to follow --> 0x58
}
break;
//STATE 48h: SLA+R transmitted, NOT ACK received
//ACTION: Transmit STOP
case 0x48 :
I2C_SET_STOP;
b_I2C_busy = FALSE;
I2C_Err = NoHostAdrAck;
break;
//STATE 50h: Data has been received, ACK returned
//ACTION: Read DATA. If expecting more continue else STOP
case 0x50 : //master receive, received data
//byte and ACK, copy it into
*(I2C_message.buf+I2C_nb_transmited) = SSDAT; //buffer
I2C_nb_transmited++;
if ( I2C_nb_transmited < I2C_message.nbbytes )
{
I2C_SET_AA; //get more bytes
}
else
{
I2C_CLEAR_AA; //only one more byte to come
}
break;
//STATE 58h: Data has been received, NOT ACK returned
//ACTION: Read DATA. Generate STOP
case 0x58 :
*(I2C_message.buf+I2C_nb_transmited) = SSDAT;
I2C_SET_STOP;
b_I2C_busy = FALSE;
I2C_Err = Tranfer_OK;
break;
//STATE 60h: Own SLA+W has been received,ACK returned
//ACTION: Read DATA. return ACK
case 0x60 :
I2C_SET_AA;
b_I2C_busy = TRUE;
I2C_RecPtr=0;
break;
C51 COMPILER V7.50 TWI_LIB 02/16/2009 09:59:54 PAGE 7
//STATE 68h: Arbitration lost in SLA and R/W as MASTER. Own SLA
// +W has been received. ACK returned
//ACTION: Read DATA. return ACK
// re-start MASTER,
case 0x68 :
I2C_SET_START;
break;
//STATE 70h: General call received, ACK returned
//ACTION: Receive DATA. return ACK
case 0x70 :
I2C_SET_AA;
b_I2C_busy = TRUE;
break;
//STATE 78h: Arbitration lost in SLA+R/W as MASTER. General call
// has arrived ack returned
//ACTION: Receive DATA. return ACK. Restart master
case 0x78 :
I2C_SET_START;
b_I2C_busy = TRUE;
break;
//STATE 80h: Previously addressed with own SLA. Data received
// and ACK returned
//ACTION: Read DATA.
case 0x80 :
I2C_slave_data[I2C_RecPtr] = SSDAT;
I2C_RecPtr ++;
if ( I2C_RecPtr < I2C_NB_SLAVE_DATA )
{
I2C_SET_AA; // ACK will be returned
}
else
{
I2C_CLEAR_AA; // it was last data not ACK will be returned ( buffer full )
}
break;
//STATE 88h: Previously addressed with own SLA. Data received
// and NOT ACK returned
//ACTION: Dont' Read DATA. Enter NOT addressed SLV mode
case 0x88 :
I2C_SET_AA; // ready to send another ACK if addresed as slave
break;
//STATE 90h: Previously addressed with general call. Data received
// and ACK returned
//ACTION: Read DATA.
case 0x90 :
I2C_slave_data[I2C_RecPtr] = SSDAT;
I2C_RecPtr = I2C_RecPtr + 1;
SSCON = 0xC1;
break;
//STATE 98h: Previously addressed with general call. Data arrved
// and NOT ACK returned
//ACTION: Dont Read DATA. Enter NOT addressed SLV mode
case 0x98 :
I2C_SET_AA;
break;
C51 COMPILER V7.50 TWI_LIB 02/16/2009 09:59:54 PAGE 8
//STATE A0h: A stop or repeated start has arrived, whilst still
// addressed as SLV/REC or SLV/TRX
//ACTION: Dont Read DATA. Enter NOT addressed SLV mode
case 0xA0 :
I2C_SET_AA;
b_I2C_busy = FALSE;
I2C_Err = Tranfer_OK;
break;
//STATE A8h: addressed with own SLA+R
//ACTION: Prepare first data to be transmited
case 0xA8 :
I2C_SET_AA;
b_I2C_busy = TRUE;
I2C_RecPtr=0;
SSDAT = I2C_slave_data[0]; //Prepare next data
break;
//STATE B8h: Previously addressed with own SLA. Data sent
// and ACK returned
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -