您的位置:首页 > 其它

I2C总线相关_5

2017-03-28 22:24 721 查看
static const struct i2c_algorithm hi_i2c_algo = {
.master_xfer    = hi_i2c_xfer,
.functionality  = hi_i2c_func,
};
//这个结构体是驱动端的.通过adapter?适配到device端
//也就是说在总线上创建一个device,最终会调用到这个结构体里面的函数


static int hi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
int num)
{
struct hi_i2c *pinfo;
int errorcode;

pinfo = (struct hi_i2c *)i2c_get_adapdata(adap);

pinfo->msgs = msgs;
pinfo->msg_num = num;
pinfo->msg_index = 0;

if (msgs->flags & I2C_M_RD)
errorcode = hi_i2c_read(pinfo);
else
errorcode = hi_i2c_write(pinfo);

return errorcode;
}
//这个函数是用来被调用的.在i2c-core.c里面调用的就是这类xfer函数.而这个函数只是对应某个驱动的函数


int hi_i2c_write(struct hi_i2c *pinfo)
{
unsigned int reg_val;
unsigned int temp_reg;
unsigned int temp_data;
unsigned int temp_auto_reg;
struct i2c_msg *msgs = pinfo->msgs;

if (hi_i2c_set_dev_addr_and_mode(pinfo, I2C_MODE_AUTO) < 0)
return -1;

temp_auto_reg = HI_I2C_WRITE;

if (msgs->flags & I2C_M_16BIT_REG) {
/* 16bit reg addr */
temp_auto_reg |= I2C_AUTO_ADDR;

/* switch high byte and low byte */
temp_reg = msgs->buf[pinfo->msg_index] << 8;

pinfo->msg_index++;

temp_reg |= msgs->buf[pinfo->msg_index];

pinfo->msg_index++;
} else {
temp_reg = msgs->buf[pinfo->msg_index];
pinfo->msg_index++;
}

if (msgs->flags & I2C_M_16BIT_DATA) {
/* 16bit data */
temp_auto_reg |= I2C_AUTO_DATA;

/* switch high byte and low byte */
temp_data =  msgs->buf[pinfo->msg_index] << 8;

pinfo->msg_index++;

temp_data |= msgs->buf[pinfo->msg_index];

pinfo->msg_index++;
} else {
temp_data = msgs->buf[pinfo->msg_index];
pinfo->msg_index++;
}

writel(temp_auto_reg, pinfo->regbase + I2C_AUTO_REG);
hi_msg("temp_auto_reg: 0x%x\n", temp_auto_reg);

/* set write reg&data */
reg_val = (temp_reg << REG_SHIFT) | temp_data;

/* wait until tx fifo not full */
if (hi_i2c_wait_txfifo_notfull(pinfo) < 0)
return -1;

hi_msg("reg_val = %x\n", reg_val);

writel(reg_val, pinfo->regbase + I2C_TX_RX_REG);

hi_msg("dev_addr =%x, reg_addr = %x, Data = %x\n",
pinfo->msgs->addr, pinfo->msgs->buf[0], pinfo->msgs->buf[1]);

return pinfo->msg_index;
}
//这个函数按说就是最底层的函数,实现了写会话的时序(虽然是调用其他函数实现的).


//以下的分析就针对hi_i2c_write函数,因为调用这个函数出问题了.
hi_i2c_set_dev_addr_and_mode
hi_i2c_wait_idle//等待tx rx 缓冲器都空了,且读取初始化寄存器
//写一些寄存器
//设置模式
//使能I2C
//设置I2C_AUTO_REG
hi_i2c_wait_txfifo_notfull/* wait until tx fifo is not full */
//设置I2C_TX_RX_REG


/*
上面是一次写的过程.
问题是第一次写正常,第二次写
hi_i2c_wait_txfifo_notfull 返回失败
并打印了
hi_i2c_wait_txfifo_notfull->262:
transmit error, int_raw_satatus: 0x750!

hi_i2c_wait_txfifo_notfull->264:
tx_abrt_cause is 1.

*/


目前还没找到I2C的fifo缓冲的资料

http://blog.csdn.net/ljzcom/article/details/9342859

http://www.cnblogs.com/BitArt/archive/2013/05/27/3101037.html

http://blog.csdn.net/goodwillyang/article/details/46272207
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: