文档介绍:文件编号TT-00-PPS-GGB-USP-UYY-0089
Ic总线协议合同协议书书
3
2条双向串行线,一条数据线SDA,一条时钟线SCL。
SDA传输数据是大端传输,每次传输8bit,即一rwritingtoslave
1Slavetransmit,masterreadingfromslave
MIF:,causingaprocessorinterruptrequest(providedI2CCR[MIEN]isset)
RXAK:若置1,表示收到了ACK
6
这个寄存器储存CPU将要传输的数据。
-Linux中I2C的实现内核代码中,通过I2C总线存取寄存器的函数都在文件drivers/i2c/busses/i2c-.
staticintmpc_xfer(structi2c_adapter*adap,structi2c_msg*msgs,intnum)
{
structi2c_msg*pmsg;
inti;
intret=0;
unsignedlongorig_jiffies=jiffies;
structmpc_i2c*i2c=i2c_get_adapdata(adap);
mpc_i2c_start(i2c);//设置I2CCR[MEN],使能I2Cmodule
7
/*Allowbusupto1stobecomenotbusy*/
//一直读I2CSR[MBB],等待I2C总线空闲下来
while(readb(i2c->base+MPC_I2C_SR)&CSR_MBB){
if(signal_pending(current)){
pr_debug("I2C:Interrupted\n");
writeccr(i2c,0);
return-EINTR;
}
if(time_after(jiffies,orig_jiffies+HZ)){
pr_debug("I2C:timeout\n");
if(readb(i2c->base+MPC_I2C_SR)==
(CSR_MCF|CSR_MBB|CSR_RXAK))
mpc_i2c_fixup(i2c);
return-EIO;
}
schedule();
}
for(i=0;ret>=0&&i<num;i++){
pmsg=&msgs[i];
pr_debug("Doing%s%dbytesto0x%02x-%dof%dmessages\n",
pmsg->flags&I2C_M_RD"read":"write",
pmsg->len,pmsg->addr,i+1,num);
//根据消息里的flag进行读操作或写操作
8
if(pmsg->flags&I2C_M_RD)
ret=mpc_read(i2c,pmsg->addr,pmsg->buf,pmsg->len,i);
else
ret=mpc_write(i2c,pmsg->addr,pmsg->buf,pmsg->len,i);
}
mpc_i2c_stop(i2c);//保证为I2CCSR[MSTA]为0,保证能触发STOP
return(ret<0)ret:num;
}
staticintmpc_write(structmpc_i2c*i2c,inttarget,
constu8*data,intlength,intrestart)
{
inti;
unsignedtimeout=i2c->;
u32flags=restartCCR_RSTA:0;
/*StartwithMEN*///以防万一,保证I2C模块使能起来
if(!restart)
writeccr(i2c,CCR_MEN);
/*Startasmaster*///写了I2CCR[CCR_MSTA],触发CPU发起START信号
writeccr(i2c,CCR_MIEN|CCR_MEN|CCR_MSTA|CCR_MTX|flags);
/*Writetargetbyte*///CPU发送一个字节,slaveI2Caddr和0(写操作bit)
writeb((target<<1),i2c->base+MPC_I2C_DR);
if(i2c_wait(i2c,timeout,1)<0)//等待slave发ACK
9
return-1;
for(i=0;i<leng