4 posts / 0 new
Last post
jamesleo-konka
Offline
Last seen:3 years 10 months ago
加入:2017-01-22 02:42
I2C RESTART signal

Hi, DIalog,
我有一个外设,是这个时序:
Start
Send Device_addr(W)
Send Reg_addr
Restart
Send Device_addr(R)
Read data
....
停止

看了 demo_i2c.c 还是没搞清楚如何实现这个时序。
一般的I2C 时序是这样的:
Start
Send Device_addr(W/R)
Send Reg_addr
Write/Read data
....
停止

该如何利用I2C的库函数来实现? hw_i2c_set_restart_enabled (HW_I2C_ID id, bool enabled) 如何使用?
在芯片硬件设计中,RESTART是怎样触发的?

另外,一个I2C操作过程是如何启动的?(产生START信号开始)。 demo_i2c.c 里,FM75的例子,貌似只有一个 set_target_address, 这个函数可以启动 I2C吗? 即使可以,这次I2C完成之后,下次的操作也应该重复启动I2C才对。

谢谢

Keywords:
Device:
Qinjiny_Dialog
Offline
Last seen:1 day 3 hours ago
Staff
加入:2016-11-01 05:47
你好,

你好,

hw_i2c_set_restart_enabled 这个函数是把I2C_CON_REG里的I2C_RESTART_EN位设为1,目的在做为I2C主机的时候允许发送Restart信号,并且这个bit默认就是1,也就是允许的。

RESTART信号一般不需要手动设置,底层protocol根据slave反馈ACR的情况自行判断是发送RESTART继续进行I2C数据传输还是发送STOP结束。

建议看一下681 DATASheet的114页开始,对芯片的I2C功能和时序有很详细的说明。除了demo_i2c.c外,也可以看看demo_i2c_async.c和adapters里面的 ad_i2c.c

jamesleo-konka
Offline
Last seen:3 years 10 months ago
加入:2017-01-22 02:42
Qinjiny_Dialog, 您好

Qinjiny_Dialog, 您好
我看demo里的 peripheral_demo 工程,隐含了很多细节,包括启动 START、STOP信号等等
一般步骤:
1. set target address
2. resource require (I2C)

然后就是读写I2C,比如
static void fm75_read_reg(uint8_t reg, uint8_t *val, uint8_t len)
{
size_t rd_status = 0;
HW_I2C_ABORT_SOURCE abrt_src = HW_I2C_ABORT_NONE;

/*
* Before reading values from sensor registers we need to send one byte information to it
* to inform which sensor register will be read now.
*/
hw_i2c_write_byte(HW_I2C1, reg);
rd_status = hw_i2c_read_buffer_sync(HW_I2C1, val, len, &abrt_src, HW_I2C_F_NONE);
if ((rd_status < (size_t)len) || (abrt_src != HW_I2C_ABORT_NONE)) {
printf("fm75 read failure: %u" NEWLINE, abrt_src);
}
}

那我理解的话: hw_i2c_write_byte(HW_I2C1, reg); 这个语句会启动 START,并发送 Slave address(写),然后 发送 reg
接下来, hw_i2c_read_buffer_sync 这个函数,读,改变了I2C 的方向,会自动产生一个 RESTART, 并自动发送 Slave address(读),然后读取数据。。。读取完成之后,I2C controller自动产生 STOP。

几个关键的 START, RESTART, STOP 都是隐含而且自动完成的? 包括 Slave address 都是自动发送的? -- 没有看到发送 Slave address 的函数语句。
那我要求的时序,也可以用上面这段代码来实现了 ? 万能啊

Start ---|
Send Device_addr(W) --| ---- hw_i2c_write_byte(HW_I2C1, reg);
Send Reg_addr --|
Restart --- auto generated --|
Send Device_addr(R) --|--- hw_i2c_read_buffer_sync
Read data --|
....
停止--|

是这样吗? 如果这样,真是万能了

Qinjiny_Dialog
Offline
Last seen:1 day 3 hours ago
Staff
加入:2016-11-01 05:47
发生方向改变的话I2C模块是会发送restart命令的

发生方向改变的话I2C模块是会发送restart命令的,不过还是建议使用adapter里面的函数而不是直接调用底层驱动