📄 i2c.c
字号:
}
//ACK check
scl_lo();//ECK clear
// *PTR(&P7CR_shadow) &= 0xf7;
// P7CR = *PTR(&P7CR_shadow); //edt input port
sda_hi();
for(i=0;i<4;i++);
scl_hi();//ECK set
waittml = 300; //300 ms
while((waittml!=0x00)&&(is_sda_hi()))
delay_us(1);
if(waittml==0x00)
{
servoflg.e2prom_err = 1;
bRes = FALSE;
}
for(i=0;i<4;i++);
scl_lo();//ECK clear
for(i=0;i<4;i++);
// *PTR(&P7CR_shadow) |= 0x08;
// P7CR = *PTR(&P7CR_shadow);
__EI();
return bRes; // Return FALSE if Error, TRUE otherwise
}
void ack_wr(void)
{
BYTE count,i;
BYTE data;
data = 0xa0;
// *PTR(&P7CR_shadow) |= 0x08;
// P7CR = *PTR(&P7CR_shadow);
sda_lo();//EDT clear
for(i=0;i<4;i++);
for(count=0;count<8;count++){
scl_lo();//ECK clear
for(i=0;i<4;i++);
if(data&0x80)
sda_hi();//EDT set
else
sda_lo();//EDT clear
for(i=0;i<4;i++);
scl_hi();//ECK set
for(i=0;i<4;i++);
data = data<<1;
}
scl_lo();//ECK clear
// *PTR(&P7CR_shadow) &= 0xf7;
// P7CR = *PTR(&P7CR_shadow); //edt input port
sda_hi(); // Switch to input mode for SDA
for(i=0;i<4;i++);
scl_hi();//ECK set
while(is_sda_hi())
{
for(i=0;i<4;i++);
scl_lo(); //ECK clear
for(i=0;i<4;i++);
scl_hi(); //ECK set
for(i=0;i<4;i++);
data = 0xa0;
// *PTR(&P7CR_shadow) |= 0x08;
// P7CR = *PTR(&P7CR_shadow);
sda_lo();//EDT clear
for(i=0;i<4;i++);
for(count=0;count<8;count++){
scl_lo();//ECK clear
for(i=0;i<4;i++);
if(data&0x80)
sda_hi();//EDT set
else
sda_lo();//EDT clear
for(i=0;i<4;i++);
scl_hi();//ECK set
for(i=0;i<4;i++);
data = data<<1;
}
scl_lo();//ECK clear
// *PTR(&P7CR_shadow) &= 0xf7;
//P7CR = *PTR(&P7CR_shadow); //edt input port
sda_hi(); // Switch to SDA input
for(i=0;i<4;i++);
scl_hi();//ECK set
}
for(i=0;i<4;i++);
scl_lo();//ECK clear
for(i=0;i<4;i++);
// *PTR(&P7CR_shadow) |= 0x08;
// P7CR = *PTR(&P7CR_shadow);
}
BYTE EEPROM_ByteRead(BYTE addr){
BYTE count,data,i;
semaphore_set(SEM_EEPROM); // ZRN SH0215:Avoid conflict between Core and Drive
__DI();
ack_wr(); //device address set
if(!is24_wr(addr))
rtouts("\nER Addr ERROR"); //sub address set
for(i=0;i<4;i++);
sda_hi();//EDT set
for(i=0;i<4;i++); //read mode
scl_hi();//ECK set
for(i=0;i<4;i++);
sda_lo();//EDT clear
for(i=0;i<4;i++);
if(!is24_wr(0xa1))
rtouts("\nER Read Mode ERROR"); //
// *PTR(&P7CR_shadow) &= 0xf7;
// P7CR = *PTR(&P7CR_shadow); //edt input port
sda_hi();
for(count=0;count<8;count++){
scl_lo();//ECK clear
for(i=0;i<4;i++);
if(is_sda_hi())
data |= 0x01;
else
data &= 0xfe;
if(count<7)
data = data<<1;
for(i=0;i<4;i++);
scl_hi();//ECK set
for(i=0;i<4;i++);
}
scl_lo();//ECK clear
for(i=0;i<4;i++);
scl_hi();//ECK set
for(i=0;i<4;i++);
scl_lo();//ECK clear
// *PTR(&P7CR_shadow) |= 0x08;
// P7CR = *PTR(&P7CR_shadow);
sda_lo();//EDT clear
for(i=0;i<4;i++);
scl_hi();//ECK set
for(i=0;i<4;i++);
sda_hi();//EDT set
__EI();
semaphore_clear(SEM_EEPROM); // ZRN SH0215:Avoid conflict between Core and Drive
return data;
}
#endif // MILLENO
#else//STANDARD_I2C_PROTOCOL
static BOOL wait_sda_lo(void)
{
int i = I2C_MAX_WAIT/5;
sda_set_input();
while(i && !is_sda_lo()) {
i--;
delay_us(5);
}
return i?TRUE:FALSE;
}
static BOOL wait_sda_hi(void)
{
int i = I2C_MAX_WAIT/5;
sda_set_input();
while(i && !is_sda_hi()) {
i--;
delay_us(5);
}
return i?TRUE:FALSE;
}
static BOOL wait_scl_hi(void)
{
int i = I2C_MAX_WAIT/5;
scl_set_input();
while(i && !is_scl_hi()) {
i--;
delay_us(5);
}
return i?TRUE:FALSE;
}
/* i2c_start --------------------------------------------------- i2c_start
|
| Provides a start bit for the I2C chip on beginning a command. As with
| each primal routine in this file, a delay is provided to guarantee that
| the maximum clocking rate of the I2C is not exceeded.
|
*/
static void i2c_start(void)
{
scl_hi();
delay_us(HOLDING_TIME*3);
sda_lo();
delay_us(HOLDING_TIME*3);
scl_lo();
delay_us(HOLDING_TIME*3);
}
/* i2c_stop ----------------------------------------------------- i2c_stop
|
| Provides a stop bit for the I2C chip on completing a command. As with
| each primal routine in this file, a delay is provided to guarantee that
| the maximum clocking rate of the I2C is not exceeded.
|
*/
static void i2c_stop(void)
{
sda_lo();
delay_us(HOLDING_TIME*3);
scl_hi();
delay_us(HOLDING_TIME*3);
sda_hi();
delay_us(HOLDING_TIME*3);
scl_lo();
delay_us(HOLDING_TIME*3);
}
/* i2c_clock --------------------------------------------------- i2c_clock
|
| Issues a clock to the I2C, and returns a sample of the SDA line during
| the clock high period (this allows the same clock routine to be used for
| both transmitting and receiving). The clock is cycled high immediately,
| assuming that the previous command has provided the appropriate delay.
*/
BOOL i2c_clock( void )
{
BYTE rel = 1;
scl_hi();
delay_us(HOLDING_TIME);
if (is_sda_lo()) rel = 0 ;
scl_lo();
delay_us(HOLDING_TIME);
return ( rel ) ;
}
/* i2c_ack ------------------------------------------------- i2c_ack
|
| Sends an acknowledge to the I2C bus. Used during continued reads.
*/
void i2c_ack( void )
{
sda_lo();
i2c_clock() ;
sda_hi();
}
/* i2c_putc ------------------------------------------------- i2c_putc
|
| transmits eight bits to the I2C, and solicits an ACK after. If the
| ACK is received, a TRUE is returned, otherwise FALSE is returned.
*/
static unsigned i2c_putc(unsigned char d)
{
BYTE i ;
// send the eight data bits
for ( i=0 ; i<8 ; i++ ) {
if ( d & 0x80 )
sda_hi();
else
sda_lo();
d = d << 1 ;
i2c_clock() ;
}
// solicit ACK.
sda_hi();
return ( !i2c_clock() ) ;
}
/* i2c_getc ----------------------------------------------------- i2c_getc
|
| receives eight bits from the I2C, returning the set as a byte. Does not
| issue ACK, since the calling routine may wish to terminate a sequential
| read operation. The calling routine is responsible for making sure that
| SDA is floating (set to 1 in 8051) before calling this routine.
*/
static unsigned char i2c_getc( void )
{
BYTE i,i2c_data = 0 ;
for ( i=0 ; i<8 ; i++ ) {
i2c_data *= 2 ;
if ( i2c_clock() ) i2c_data++ ;
}
return ( i2c_data ) ;
}
static BOOL i2c_select_device( unsigned char addr, unsigned char subaddr )
{
i2c_start() ;
if ( i2c_putc( addr ) )
return ( i2c_putc( subaddr ) ) ;
else
return ( FALSE ) ;
}
/*
* This function writes address, subaddr, and data on the I2C bus.
* The bits in the byte are
* sent in the order of the high bit first and the lowest bit last.
*/
BOOL i2c_write(unsigned char addr,
unsigned char subaddr,
unsigned char dat)
{
BYTE i ;
if ( i2c_select_device(addr,subaddr) && i2c_putc( dat ) ) {
i2c_stop() ;
usleep(5000); //delay 5 ms
} else return ( FALSE ) ;
return ( TRUE ) ;
}
BOOL i2c_write_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
{
BYTE retry = 10;
while ( count && retry ){
if ( i2c_write(addr, subaddr, *data) ){
subaddr++;
data++;
count--;
retry = 10;
}
else
retry--;
}
return ( retry );
}
BOOL i2c_read_string( unsigned char addr, unsigned char subaddr, int count, unsigned char *data )
{
BYTE i ;
// set up for reads starting at address 0
if ( i2c_select_device( addr, subaddr ) ) {
// send a second start
i2c_start() ;
if ( i2c_putc( addr | 1 ) ) {
for ( i=0 ; i<count ; i++ ) {
data[i] = ( i2c_getc() ) ;
if ( i != (count-1) )
i2c_ack() ;
else {
i2c_clock() ;
i2c_stop() ;
}
}
return ( TRUE ) ;
}
else {
i2c_stop() ;
return ( FALSE ) ;
}
}
else
i2c_stop() ;
return ( FALSE ) ;
}
#endif//STANDARD_I2C_PROTOCOL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -