I2C总线相关

    xiaoxiao2021-03-25  12

    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

    转载请注明原文地址: https://ju.6miu.com/read-200218.html

    最新回复(0)