📄 drvi2c.c
字号:
#include "includes.h"
#include "fi2c.h"
#include "device.h"
#include "hardware.h"
INT16U i2c_init(void);
INT16U i2c_open(void);
INT16U i2c_write( INT8U rom *wrptr, INT16U length );
INT16U i2c_read( INT8U rom *rdptr, INT16U length );
INT16U i2c_ioctl(INT8U cmd, INT24U arg);
#pragma romdata CCODE
DEV_HEADER DEV_I2C = {
DEV_ID_I2C, /*device ID */
{'i','2','c'}, /*device name*/
DEVP_CHAR, /*device Type*/
i2c_init, /*device init function*/
FNull_1, /*device clear function*/
i2c_open, /*device open function*/
FNull_1, /*device close function*/
i2c_ioctl, /*device ioctl function*/
i2c_write, /*device write function*/
i2c_read /*device read function*/
};
#pragma code MYCODE
INT16U i2c_init(void){
//set basic parameters of the i2c interface
//currently do nothing
}
INT16U i2c_open(void){
SSPSTATbits.SMP = 0;
SSPCON1 = 0x08; //select I2C master mode
SSPCON1bits.SSPEN = 1; //enable I2C
PIR2bits.BCLIF = 0;
SSPADD = 10;
WP = 0; //Enable write to eeprom
}
INT16U i2c_write( INT8U rom *wrptr, INT16U length ){
while (length) {
if ( SSPCON1bits.SSPM3 ){ // if Master transmitter then execute the following
if ( putcI2C ( *wrptr ) ){ // write 1 byte
return ( 0xff ); // return with write collision error
}
IdleI2C(); // test for idle condition
length--;
if ( SSPCON2bits.ACKSTAT ){ // test received ack bit state
return ( 0xfe ); // bus device responded with NOT ACK
} // terminate putsI2C() function
}
else{ // else Slave transmitter
PIR1bits.SSPIF = 0; // reset SSPIF bit
SSPBUF = *wrptr; // load SSPBUF with new data
SSPCON1bits.CKP = 1; // release clock line
while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received
if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) ){ // if R/W=0 and BF=0, NOT ACK was received
return ( 0xfd ); // terminate PutsI2C() function
}
}
wrptr ++; // increment pointer
} // continue data writes until null character
return ( 0 );
}
INT16U i2c_read( INT8U rom *rdptr, INT16U length )
{
INT16U len;
len = length;
while ( length -- ){ // perform getcI2C() for 'length' number of bytes
*rdptr++ = getcI2C(); // save byte received
while ( SSPCON2bits.RCEN ); // check that receive sequence is over
if ( PIR2bits.BCLIF ) return ( 0 ); // test for bus collision
if ( length ){ // test if 'length' bytes have been read
SSPCON2bits.ACKDT = 0; // set acknowledge bit state for ACK
SSPCON2bits.ACKEN = 1; // initiate bus acknowledge sequence
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
}
}
return (len); // last byte received so don't send ACK
}
INT16U i2c_ioctl(INT8U cmd, INT24U arg){
switch(cmd){
case I2C_RESTART:
RestartI2C();
while ( SSPCON2bits.RSEN );
break;
case I2C_NOTACK:
NotAckI2C();
while ( SSPCON2bits.ACKEN );
break;
case I2C_STOP:
StopI2C();
while ( SSPCON2bits.PEN );
break;
case I2C_BUSSTT:
if(PIR2bits.BCLIF){
PIR2bits.BCLIF = 0;
return(1);
}
return(0);
break;
case I2C_START:
StartI2C();
while ( SSPCON2bits.SEN );
break;
case I2C_IDLE:
IdleI2C();
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -