跳到主要内容

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);