I2C函数之s3c24xx_i2c_message_start函数解析(三)

函数来源于Linux设备驱动开发详解.pdf。 

// 53-54: 定义一个名为 `s3c24xx_i2c_message_start` 的静态函数,它属于 `struct s3c24xx_i2c` 结构体。
static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c, struct i2c_msg *msg)

// 57: 计算I2C设备的地址,通过掩码操作获取消息地址的低7位。
unsigned int addr = (msg->addr & 0x78);

// 58-59: 声明两个无符号长整型变量 `stat` 和 `iiccon`,用于存储I2C状态和控制寄存器的值。
unsigned long stat;
unsigned long iiccon;

// 62-63: 读取I2C状态寄存器的当前值,存储到变量 `stat` 中。
stat = __raw_readl(i2c->regs + S3C2410_IICSCON);

// 检查I2C总线状态,根据不同的状态执行不同的操作:
// 64-65: 如果状态寄存器表明可以发送数据,并且消息标志表明是读操作,则设置地址为读模式。
if (stat & S3C2410_IICSTAT_TXRXEN && (msg->flags & I2C_M_RD))
{
    stat |= S3C2410_IICSTAT_MASTERRX;
    addr |= 0x01; // 设置读操作的标志位
}
// 68-70: 否则如果是写操作,则设置地址为写模式。
else
{
    stat &= ~S3C2410_IICSTAT_MASTERTX;
    addr &= ~0x01; // 清除读操作的标志位
}

// 72-73: 如果需要,启用I2C总线的ACK功能。
if (msg->flags & I2C_M_RECV_LEN)
{
    s3c2410_i2c_enable_ack(i2c);
}

// 74-75: 读取I2C控制寄存器的当前值。
iiccon = __raw_readl(i2c->regs + S3C2410_IICCON);

// 76-77: 写回状态寄存器,清除可能的旧状态。
__raw_writel(stat, i2c->regs + S3C2410_IICSCON);

// 78: 发送I2C设备地址。
__raw_writeb(addr, i2c->regs + S3C2440_IICDS);

// 79: 在发送新的开始位之前,延时一段时间。
udelay(1);

// 80: 写入控制寄存器,开始I2C传输。
__raw_writel(iiccon, i2c->regs + S3C2410_IICCON);

// 81-82: 如果I2C状态寄存器表明已经开始,则再次写入状态寄存器以确认开始。
if (stat & S3C2410_IICSTAT_START)
{
    __raw_writel(stat, i2c->regs + S3C2410_IICSCON);
}

这段代码主要处理I2C消息的开始阶段,包括设置I2C设备地址、配置读/写模式、可能的ACK使能,以及触发I2C传输的开始。代码使用了原始的寄存器读写操作(__raw_readl__raw_writel),这是Linux设备驱动中直接操作硬件寄存器的方法。此外,udelay 用于在发送新的开始位之前提供短暂的延时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值