📄 twi_lib.c
字号:
//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;
//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
//ACTION: Write DATA.
case 0xB8 :
I2C_RecPtr ++;
if ( I2C_RecPtr < I2C_NB_SLAVE_DATA )
{
SSDAT = I2C_slave_data[I2C_RecPtr];
}
else
{
///////// FIX ME : adressed with as slave + R : but not enought data"
I2C_CLEAR_AA; // it was last data not ACK will be returned ( buffer full )
}
break;
//STATE C0h: Previously addressed with own SLA. Data sent
// and NACK returned
//ACTION: It was last data to be sent
case 0xC0 :
b_I2C_busy=FALSE;
I2C_Err = Tranfer_OK;
break;
//if we arrived here, unknown state has occurred.....
default :
I2C_SET_STOP;
b_I2C_busy = FALSE;
I2C_Err = UnknownError;
break;
}
}
/*F**************************************************************************
* NAME: I2C_Send_Message_polling
*----------------------------------------------------------------------------
* PARAMS:
* *slave_adr: The slave component address
* rw: Read or write operation flag ( read = 1 )
* nbbytes: number of bytes to be read or write
* *info: pointer to the data to be processed
* return: I2C error code state
*----------------------------------------------------------------------------
* PURPOSE:
* This function can be used to send an I2C message to a slave
* in polling mode.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
unsigned char I2C_Send_Message_polling (unsigned char slave_adr,bit rw, unsigned char nbbytes, unsigned char *info )
{
I2C_message.address = slave_adr;
I2C_message.rw = rw;
I2C_message.nbbytes = nbbytes;
I2C_message.buf = info;
I2C_CLEAR_STOP;
DISABLE_I2C_IT;
I2C_nb_transmited=0;
if ( ~b_I2C_busy )
{
b_I2C_busy =1;
I2C_Err = Tranfer_OK;
I2C_SET_START;
while( b_I2C_busy )
{
I2C_WAIT_EVENT;
I2C_decode_status();
I2C_CLEAR_SI;
}
I2C_SET_STOP;
return I2C_Err;
}
else
{
I2C_SET_STOP;
return I2C_NOT_FREE;
}
}
/*F**************************************************************************
* NAME: I2C_Send_Message_interrupt
*----------------------------------------------------------------------------
* PARAMS:
* *slave_adr: The slave component address
* rw: Read or write operation flag ( read = 1 )
* nbbytes: number of bytes to be read or write
* *info: pointer to the data to be processed
* return: I2C error code state
*----------------------------------------------------------------------------
* PURPOSE:
* This function can be used to send an I2C message to a slave
* in interrupt mode.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
unsigned char I2C_Send_Message_interrupt (unsigned char slave_adr,bit rw, unsigned char nbytes, unsigned char *info)
{
I2C_message.address = slave_adr;
I2C_message.rw = rw;
I2C_message.nbbytes = nbytes;
I2C_message.buf = info;
I2C_CLEAR_STOP;
I2C_nb_transmited=0;
if ( ~b_I2C_busy )
{
I2C_Err = Tranfer_OK;
b_I2C_busy =1;
ENABLE_I2C_IT;
I2C_SET_START;
}
else
{
I2C_SET_STOP;
return I2C_NOT_FREE;
}
}
/*F**************************************************************************
* NAME: I2C_slave_polling
*----------------------------------------------------------------------------
* PARAMS:
* return: I2C error code state
*----------------------------------------------------------------------------
* PURPOSE:
* This function can be called to be able to answer another master request
* in polling mode.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
unsigned char I2C_slave_polling (void)
{
I2C_WAIT_EVENT;
I2C_decode_status();
I2C_CLEAR_SI;
while( b_I2C_busy )
{
I2C_WAIT_EVENT;
I2C_decode_status();
I2C_CLEAR_SI;
}
return I2C_Err;
}
/*F**************************************************************************
* NAME: I2C_slave_interrupt
*----------------------------------------------------------------------------
* PARAMS:
* return: none
*----------------------------------------------------------------------------
* PURPOSE:
* This function can be called to be able to answer another master request
* in interrupt mode (stand alone mode).
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void I2C_slave_interrupt (void)
{
ENABLE_IT;
ENABLE_I2C_IT;
}
/*F**************************************************************************
* NAME: I2C_interrupt
*----------------------------------------------------------------------------
* PARAMS:
* return: none
*----------------------------------------------------------------------------
* PURPOSE:
* I2C interrupt routine service
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void I2C_interrupt() interrupt IRQ_I2C using 1
{
I2C_decode_status();
I2C_CLEAR_SI;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -