I2C总线相关_5

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值