soundDrv_tlv320aic23.rar
static inline int rt_i2c_wait_rx_done(void)
{
int retries = I2C_RETRY;
do {
if (!retries--)
break;
} while(!(rt_i2c_r32(REG_STATUS_REG) & I2C_DATARDY));
//温湿度传感器sht20数据手册中HOLD_MASTER模式读写时序:
//In the hold master mode, the SHT2x pulls down the SCL line while measuring to force the master into a wait state.
//By releasing the SCL line the sensor indicates that internal processing is terminated and that transmission may be continued.
//当i2c适配器向sht20发送查询命令后sht20处于measurement将SLK拉低,i2c适配器的状态位为busy并一直等待数据:雷凌驱动中
//此处表示在retries=0x400的时间内对方释放SLK适配器的状态位由busy变成datardy(sht20的measurement时间较长以至于在retries=0x400
//的时间内仍没有释放SLK,此处在i2c适配器的状态位仍为busy时返回造成i2c适配器一直未发送停止位p,进而sht20一直占用总线。
return (retries < 0);
}
static int rt_i2c_handle_msg(struct i2c_adapter *a, struct i2c_msg* msg)
{
int i = 0, j = 0, pos = 0;
int nblock = msg->len / READ_BLOCK;
int rem = msg->len % READ_BLOCK;
if (msg->flags & I2C_M_TEN) {
printk("10 bits addr not supported\n");
return -EINVAL;
}
if (msg->flags & I2C_M_RD) {
for (i = 0; i < nblock; i++) {
rt_i2c_wait_idle();
rt_i2c_w32(READ_BLOCK - 1, REG_BYTECNT_REG);
rt_i2c_w32(READ_CMD, REG_STARTXFR_REG);
for (j = 0; j < READ_BLOCK; j++) {
if (rt_i2c_wait_rx_done())
return -1;
//在retries=0x400的时间内i2c适配器的状态位仍为busy(sht20未释放SLK):此处直接返回-1,i2c适配器未接收数据进而也不会发送停止位p.
msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG);
//i2c适配器接收来自sht20的数据,接收完毕后i2c适配器硬件电路会自动发送停止位p.
}
}
rt_i2c_wait_idle();
rt_i2c_w32(rem - 1, REG_BYTECNT_REG);
rt_i2c_w32(READ_CMD, REG_STARTXFR_REG);
for (i = 0; i < rem; i++) {
if (rt_i2c_wait_rx_done())
return -1;
msg->buf[pos++] = rt_i2c_r32(REG_DATAIN_REG);
}
} else {
rt_i2c_wait_idle();
rt_i2c_w32(msg->len - 1, REG_BYTECNT_REG);
for (i = 0; i < msg->len; i++) {
rt_i2c_w32(msg->buf[i], REG_DATAOUT_REG);
rt_i2c_w32(WRITE_CMD, REG_STARTXFR_REG);
if (rt_i2c_wait_tx_done())
return -1;
}
}
return 0;
}
阅读(2273) | 评论(0) | 转发(0) |