I2C 驱动
结构体
I2C 描述结构体
typedef struct {
uint32_t base;
uint8_t id;
uint32_t speed;
gpio_mux_t gpio_scl;
gpio_mux_t gpio_sda;
bool status;
} sunxi_i2c_t;
I2C 总线枚举
enum {
SUNXI_I2C0 = 0,
SUNXI_I2C1,
SUNXI_I2C2,
SUNXI_I2C3,
SUNXI_I2C4,
SUNXI_I2C5,
SUNXI_R_I2C0,
SUNXI_R_I2C1,
SUNXI_I2C_BUS_MAX,
};
I2C 外设寄存器结构体
struct sunxi_twi_reg {
volatile uint32_t addr; /* slave address */
volatile uint32_t xaddr; /* extend address */
volatile uint32_t data; /* data */
volatile uint32_t ctl; /* control */
volatile uint32_t status; /* status */
volatile uint32_t clk; /* clock */
volatile uint32_t srst; /* soft reset */
volatile uint32_t eft; /* enhanced future */
volatile uint32_t lcr; /* line control */
volatile uint32_t dvfs; /* dvfs control */
};
接口 API
sunxi_i2c_init
void sunxi_i2c_init(sunxi_i2c_t *i2c_dev);
初始化sunxi_i2c控制器设备结构。
sunxi_i2c_write
int sunxi_i2c_write(sunxi_i2c_t *i2c_dev, uint8_t addr, uint32_t reg, uint8_t data);
向设备写入数据。
i2c_dev
:指向sunxi_i2c控制器设备结构的指针。addr
:设备地址。reg
:要在设备中读取/写入的寄存器。data
:要写入/读取的数据。- 返回值:状态的数量。
sunxi_i2c_read
int sunxi_i2c_read(sunxi_i2c_t *i2c_dev, uint8_t addr, uint32_t reg, uint8_t *data);
从设备读取数据。
i2c_dev
:指向sunxi_i2c控制器设备结构的指针。addr
:设备地址。reg
:要从设备中读取的寄存器。data
:用于存储读取数据的缓冲区。- 返回值:状态的数量。
I2C 接口状态返回值
代码 | 状态 |
---|---|
00h | 总线错误 |
08h | 发送起始条件 |
10h | 重复发送起始条件 |
18h | 地址+写位发送,收到ACK |
20h | 地址+写位发送,未收到ACK |
28h | 主模式下发送数据字节,收到ACK |
30h | 主模式下发送数据字节,未收到ACK |
38h | 地址或数据字节仲裁丢失 |
40h | 地址+读位发送,收到ACK |
48h | 地址+读位发送,未收到ACK |
50h | 主模式下接收数据字节,发送ACK |
58h | 主模式下接收数据字节,未发送ACK |
60h | 收到从机地址+写位,发送ACK |
68h | 作为主机地址仲裁丢失,收到从机地址+写位,发送ACK |
70h | 收到广播地址,发送ACK |
78h | 作为主机地址仲裁丢失,收到广播地址,发送ACK |
80h | 在收到从机地址后接收数据字节,发送ACK |
88h | 在收到从机地址后接收数据字节,未发送ACK |
90h | 在收到广播地址后接收数据字节,发送ACK |
98h | 在收到广播地址后接收数据字节,未发送ACK |
A0h | 在从机模式下接收到停止或重复开始条件 |
A8h | 收到从机地址+读位,发送ACK |
B0h | 作为主机地址仲裁丢失,收到从机地址+读位,发送ACK |
B8h | 在从机模式下发送数据字节,收到ACK |
C0h | 在从机模式下发送数据字节,未收到ACK |
C8h | 在从机模式下发送最后一个字节,收到ACK |
D0h | 发送第二个地址字节+写位,收到ACK |
D8h | 发送第二个地址字节+写位,未收到ACK |
F8h | 无相关状态信息或无中断 |
示例
申明 I2C,并且发送数据
sunxi_i2c_t i2c_0 = {
.base = 0x02502000,
.id = 0,
.speed = 4000000,
.gpio_scl = {GPIO_PIN(GPIO_PORTE, 4), GPIO_PERIPH_MUX8},
.gpio_sda = {GPIO_PIN(GPIO_PORTE, 5), GPIO_PERIPH_MUX8},
};
sunxi_i2c_init(&i2c_0);
ret = sunxi_i2c_write(&i2c_0, 0x32, 0x11, 0x11);