龙芯1B I2C读写操作的实现

龙芯1B i2c结构
ls1x_i2c结构
/*
    void __iomem *base:一个指向I2C控制器寄存器基地址的指针。
    u32 interrupt:表示I2C控制器的中断号。
    wait_queue_head_t queue:用于I2C传输的等待队列头。
    struct i2c_adapter adap:一个i2c_adapter结构体,用于表示I2C适配器的属性和方法。
    int irq:表示I2C控制器的IRQ号。
    u32 flags:用于存储一些I2C相关的标志。
*/
struct ls1x_i2c {
	void __iomem *base;
	u32 interrupt;
	wait_queue_head_t queue;
	struct i2c_adapter adap;
	int irq;
	u32 flags;
};

*
    void __iomem *base:一个指向I2C控制器寄存器基地址的指针;该地址获取的方式举例

在i2c probe中通过platform_get_resource函数来获取平台platform_device的num_resources成员来获取

龙芯1B I2C读取单字节实现
static unsigned char i2c_readb (struct ls1x_i2c *i2c, unsigned char reg)
{
	unsigned char data;
	//读取寄存器中的数据
	data = (*(volatile unsigned char *)(i2c->base + reg));

	return data;
}
龙芯1B I2C写入单字节实现 
static char i2c_writeb(struct ls1x_i2c *i2c, unsigned int reg, unsigned char  data)
{
	//给寄存器赋值
	(*(volatile unsigned char *)(i2c->base + reg)) = data;
}
龙芯1B读取多字节实现
static int ls1x_xfer_read(struct ls1x_i2c *i2c, unsigned char *buf, int len) 
{

	int x;

	for(x=0; x<len; x++) {

//send ACK last not send ACK
		if(x != (len -1)) 
			i2c_writeb(i2c, REG_I2C_CR,   I2C_C_READ);        //控制寄存器产生读信号
		else
			i2c_writeb(i2c, REG_I2C_CR, I2C_C_WACK |I2C_C_READ);//否则发产生ACK并且产生读信号

		while(i2c_readb(i2c, REG_I2C_SR) & I2C_S_RUN);//等待数据传输完毕

		buf[x] = i2c_readb(i2c,REG_I2C_TXR);//读取发送寄存器的内容

	}
	
	i2c_writeb(i2c,REG_I2C_CR, I2C_C_STOP);//控制寄存器发送停止信号
		
	return 0;
}
龙芯1B写多字节实现
static int ls1x_xfer_write(struct ls1x_i2c *i2c, unsigned char *buf, int len)
{

	int j;

	for(j=0; j< len; j++) {
			i2c_writeb(i2c, REG_I2C_TXR, buf[j]);//给寄存器赋值
			i2c_writeb(i2c, REG_I2C_CR, I2C_C_WRITE);//控制寄存器产生写信号
			while(i2c_readb(i2c, REG_I2C_SR) & I2C_S_RUN);//等待数据传输完毕
            //收到应答位
			if(i2c_readb(i2c, REG_I2C_SR) & I2C_S_RNOACK) {

			i2c_writeb(i2c, REG_I2C_CR, I2C_C_STOP);//产生停止信号
				return len;
			}
 
		}

	i2c_writeb(i2c, REG_I2C_CR, I2C_C_STOP);//产生停止信号

	return 0;

}
执行I2c总线的读写操作函数实现
static int ls1x_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
{
	int i, ret;
	struct ls1x_i2c *i2c = adap->algo_data;//从适配器的数据结构配i2c信息

	dev_dbg(&adap->dev, "ls1x_xfer: processing %d messages:\n", num);

/*set slave addr*/
	for(i=0;i<num;i++) {

		char flags;
		
		while(i2c_readb(i2c, REG_I2C_SR) & I2C_S_BUSY);//等待i2c总线空闲
		
		flags = (pmsg->flags & I2C_M_RD)?1:0;//msg 的flasgs为读取消息标志时
		i2c_writeb(i2c, REG_I2C_TXR, ((pmsg->addr << 1 ) | flags));//接收寄存器读取slave的地址信息
		i2c_writeb(i2c, REG_I2C_CR, (I2C_C_WRITE | I2C_C_START | I2C_C_WACK));//控制寄存器产生start信号,写信号,应答信号


		while(i2c_readb(i2c, REG_I2C_SR) & I2C_S_RUN);//等待传输完毕
        
        //读取状态寄存器接收ACK
		if (i2c_readb(i2c, REG_I2C_SR) & I2C_S_RNOACK) {
			printk(" slave addr no ack !!\n");
			i2c_writeb(i2c, REG_I2C_CR, I2C_C_STOP); //控制器产生停止信号
			return 0;
		}


 		if(flags )
			ret = ls1x_xfer_read(i2c, pmsg->buf, pmsg->len);//读取寄存器中的数据
  		else
			ret = ls1x_xfer_write(i2c, pmsg->buf, pmsg->len);//给寄存器赋值

	++pmsg;

	}

	return num;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值