I2C
概述
I2C 总线(Inter-Integrated Circuit)是半双工串行总线,只需 SDA(serial data line,串行数据)和 SCL(serial clock line,串行时钟线)两根线即可在总线上完成器件之间的数据传输。
I2C master 产生时钟 SCL,启动总线开始数据传输。既可以发送数据,也可以从 I2C slave 读取数据。各 I2C 设备在总线上的连接示例如下图所示,接口电路为开漏输出。
I2C 设备在总线上的连接示例
发送到 SDA 线上的每个字节必须为 8 位。每次传输可以发送的字节数不限,首先传输的是数据的最高有效位(MSB),每个字节后必须跟一个响应位(ACK)。
I2C 完整的数据传输协议如下图所示。
I2C 完整的数据传输协议
I2C 主机写数据的流程如下:
主机在检测到总线为“空闲状态”(即 SDA、SCL 线均为高电平)时,向从机发送启动信号 S,开始通信。
主机发送一个命令字节。该字节由 7 位的待寻址的从机地址和 1 位读写控制位 R/W 组成(主机写数据时,R/W=0)。
指定从机收到命令字节后向主机反馈应答信号 ACK。
主机收到从机的应答信号后开始发送第一个字节的数据。
从机收到数据后返回一个应答信号 ACK。
主机收到应答信号后再发送下一个字节的数据。
主机发送最后一个数据字节并收到从机的反馈后,向从机发送停止信号 P 结束本次通信并释放总线。
说明
某些从机会把从机地址之后的第一个数据当作从机寄存器的起始地址。即,主机会从这个寄存器地址开始往后写待发送的数据。
如果 I2C master 需要继续在总线上通讯,则会产生 Restart 条件,并寻址另一个 slave。最后等待所有数据传输完成后,I2C master 再产生 Stop condition。
I2C 主机读数据的流程如下:
主机发送启动信号后,发送命令字节(主机读数据时,R/W=1)。
对应的从机收到地址后,返回一个应答信号并向主机发送数据。
主机收到数据后向从机发送 ACK 反馈。
从机收到应答信号后再向主机发送下一个字节。
主机完成接收数据后,向从机发送 NACK 信号,从机收到后停止发送数据。
主机再发送一个停止信号 P,释放总线结束通信。
功能特性
WQ7036 内部有两个 I2C master 控制器,均位于应用子系统。I2C master 遵循标准 I2C 协议。
I2C master 支持如下特性:
半双工传输模式。
100 kbps 标准模式、400 kbps 快速模式及其他模式。
16x8 bit Tx FIFO 和 16x8 bit Rx FIFO。
多从机 7 位寻址。
可配置的数据过滤器。
可配置字符字节序列(MSB、LSB)。
多数据传输。
工作模式
I2C master 模块既可以作为 Tx 发送数据,又可以作为 Rx 接收数据,I2C master 收发数据流程如下图所示。
I2C 收发流程
I2C master 作 Tx 时,数据传输流程如下:
APB 总线配置相关寄存器,将待发送数据写入 Tx FIFO。
I2C master 主控制器将从 Tx FIFO 中读取的数据根据 I2C 协议发送到 I2C 总线,同时产生时钟信号 SCL。
主控制器(I2C master main control)根据 Tx FIFO 的中断信息判断何时可以写 Tx FIFO。
根据 i2c_trans_done 信号来判断所有数据传输是否完成。
I2C master 作 Rx 时,数据传输流程如下:
APB 总线配置相关寄存器。
I2C master 主控制器接收 I2C 总线上的 SDA 数据,写入 Rx FIFO,同时主控制器会产生 SCL 时钟信号送到 I2C 总线上。
主控制器根据 Rx FIFO 的中断信息判断何时读取 Rx FIFO,将收到的数读到 APB 总线。
资源依赖
I2C
GPIO
IRQ
用法流程
初始化 i2c
wq_i2c_init()配置并打开 i2c
wq_i2c_open()poll 方式读写
wq_i2c_write_poll()wq_i2c_read_poll()wq_i2c_write_read_poll()中断方式读写
wq_i2c_write()wq_i2c_read()wq_i2c_write_read()关闭 i2c
wq_i2c_close()注销 i2c
wq_i2c_deinit()
参考示例
examples/i2c_demo
示例说明
本示例使用 WQ 开发板和 EEPROM AT24CXX,通过 i2c 建立通信连接。
I2C Demo 流程图
API 介绍
Defines
-
I2C_TRANS_MAX_WAIT_TIME
I2C transfer max wait time count.
Typedefs
-
typedef struct wq_i2c_gpio_cfg wq_i2c_gpio_cfg_t
I2C transfer gpio settings struct.
-
typedef void (*wq_i2c_callback)(uint16_t dev_addr, uint8_t buffer_length, uint8_t *buffer)
I2c transfer done callback func Invoke when the transfer is complete.
备注
buffer can't be free before this callback are invoke.
- Param dev_addr:
is the address of the device that completed the transfer
- Param buffer_length:
is the length of buffer that completed the transfer
- Param buffer:
is pointing to the buffer pointer that completed the transfer
-
typedef struct wq_i2c_config wq_i2c_config_t
Functions
-
WQ_RET wq_i2c_init(WQ_I2C_PORT port)
This function is to initialize i2c.
- 参数:
port -- is i2c port.
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_deinit(WQ_I2C_PORT port)
This function is to deinitialize i2c.
- 参数:
port -- is i2c port.
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_open(WQ_I2C_PORT port, const wq_i2c_gpio_cfg_t *gpio, const wq_i2c_config_t *cfg)
This function is to open i2c.
- 参数:
port -- is i2c port.
gpio -- is i2c gpio configuration.
cfg -- is i2c configuration.
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_close(WQ_I2C_PORT port)
This function is to close i2c.
- 参数:
port -- is i2c port.
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_write_poll(WQ_I2C_PORT port, uint16_t dev_addr, const uint8_t *buffer, uint32_t length)
This function is to transmit data by poll mode.
- 参数:
port -- is i2c port.
dev_addr -- device address.
buffer -- Pointer to store the data to be transmitted.
length -- transmit data length.(length range 1 to 255 bytes)
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_read_poll(WQ_I2C_PORT port, uint16_t dev_addr, uint8_t *buffer, uint32_t length)
This function is to receive data by poll mode.
- 参数:
port -- is i2c port.
dev_addr -- device address.
buffer -- Pointer to store the received data.
length -- receive data length.(length range 1 to 255 bytes)
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_write_read_poll(WQ_I2C_PORT port, uint16_t dev_addr, const uint8_t *write_buf, uint8_t write_length, uint8_t *read_buf, uint32_t read_length)
This function is to receive data by poll mode (have write device phase,include register address transmit)
- 参数:
port -- is i2c port.
dev_addr -- device address.
write_buf -- Pointer to store receive data register address.
write_length -- receive data register address width(width range 1 to 4 bytes).
read_buf -- Pointer to store the received data.
read_length -- receive data length.(length range 1 to 255 bytes)
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_write(WQ_I2C_PORT port, uint16_t dev_addr, uint8_t *buffer, uint32_t length, wq_i2c_callback cb)
This function is to transmit data by interrupt mode.
- 参数:
port -- is i2c port.
dev_addr -- device address.
buffer -- Pointer to store the data to be transmitted.
length -- transmit data length.(length range 1 to 255 bytes)
cb -- transmit data done callback function.
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_read(WQ_I2C_PORT port, uint16_t dev_addr, uint8_t *buffer, uint32_t length, wq_i2c_callback cb)
This function is to receive data by interrupt mode.
- 参数:
port -- is i2c port.
dev_addr -- device address.
buffer -- Pointer to store the received data.
length -- receive data length.(length range 1 to 255 bytes)
cb -- receive data done callback function.
- 返回:
WQ_RET RET_OK for success else error.
-
WQ_RET wq_i2c_write_read(WQ_I2C_PORT port, uint16_t dev_addr, uint8_t *write_buf, uint8_t write_length, uint8_t *read_buf, uint32_t read_length, wq_i2c_callback cb)
This function is to receive data by interrupt mode (have write device phase,include register address transmit)
- 参数:
port -- is i2c port.
dev_addr -- device address.
write_buf -- Pointer to store receive data register address.
write_length -- receive data register address width(width range 1 to 4 bytes).
read_buf -- Pointer to store the received data.
read_length -- receive data length.(length range 1 to 255 bytes)
cb -- receive data done callback function.
- 返回:
WQ_RET RET_OK for success else error.
-
struct wq_i2c_gpio_cfg
- #include <wq_i2c.h>
I2C transfer gpio settings struct.
-
struct wq_i2c_config