I2C驅(qū)動(dòng)包括兩層:硬件訪問層(HAL)和RT-Thread的適配層。
硬件訪問層提供用于訪問 I2C 外設(shè)寄存器的基本 API。 有關(guān)詳細(xì)信息,請(qǐng)參閱 I2C HAL 的 API 文檔。
適配層提供對(duì) RT-Thread 驅(qū)動(dòng)框架的支持。 用戶可以使用 RT-Thread POSIX 驅(qū)動(dòng)程序接口進(jìn)行 I2C 編程。 請(qǐng)參閱 RT-Thread 驅(qū)動(dòng)程序的 API 文檔。
主要功能包括:
- 多實(shí)例支持
- I2C 工作在主模式
- 支持 I2C 工作在速度模式 100Kbps/400Kbps/1Mbps
- 支持地址模式10bit/7bit
- 支持基于中斷的 RX 和 TX
- RX 和 TX 均支持 DMA
驅(qū)動(dòng)配置
I2C 驅(qū)動(dòng)程序可以使用多個(gè) I2C 外設(shè)實(shí)例。 可以使用 menuconfig 工具為每個(gè)項(xiàng)目選擇外設(shè)和 DMA 支持配置的實(shí)例,通常保存在 C 頭文件中。 默認(rèn)情況下,配置保存為 rtconfig.h。
以下示例顯示在一個(gè)項(xiàng)目頭文件中定義的標(biāo)志,該項(xiàng)目使用具有 DMA 支持的 i2c1/i2c2/i2c3 實(shí)例:
#define RT_USING_I2C
#define BSP_USING_I2C1
#define BSP_USING_I2C2
#define BSP_USING_I2C3
#define BSP_I2C1_USING_DMA
#define BSP_I2C2_USING_DMA
#define BSP_I2C3_USING_DMA
配置完成后,用戶需要在所有需要訪問驅(qū)動(dòng)程序的源代碼中包含頭文件。
使用 I2C 驅(qū)動(dòng)程序
適配器層注冊(cè) RT-Thread 請(qǐng)求的硬件支持功能,并使用 HAL 實(shí)現(xiàn)這些功能。 對(duì)于 I2C HAL 公開的 API,請(qǐng)參閱 I2C 以了解詳細(xì)信息。 對(duì)于使用 RT-Thread 的用戶,可以使用以下代碼作為示例:
struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name);
bus_name: i2c1 / i2c2 / i2c3
rt_err_t rt_i2c_open(struct rt_i2c_bus_device *dev, rt_uint16_t oflag);
oflag: dma mode: RT_DEVICE_FLAG_RDWR|RT_DEVICE_FLAG_DMA_RX|RT_DEVICE_FLAG_DMA_TX
int mode: RT_DEVICE_FLAG_RDWR|RT_DEVICE_FLAG_INT_RX|RT_DEVICE_FLAG_INT_TX
normal mode: RT_DEVICE_FLAG_RDWR
rt_err_t i2c_bus_configure(struct rt_i2c_bus_device *bus, struct rt_i2c_configuration *configuration);
configuration: use struct rt_i2c_configuration as following:
struct rt_i2c_configuration
{
rt_uint16_t mode;
rt_uint16_t addr;
rt_uint32_t timeout;
rt_uint32_t max_hz;
};
rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msgs[],
rt_uint32_t num)
msgs: use struct rt_i2c_msg as following:
struct rt_i2c_msg
{
rt_uint16_t addr;
rt_uint16_t mem_addr;
rt_uint16_t mem_addr_size;
rt_uint16_t flags;
rt_uint8_t *buf;
};
void i2c_trans_test()
{
struct rt_i2c_bus_device *i2c_bus = RT_NULL;
struct rt_i2c_msg msgs;
struct rt_i2c_configuration cfg = {0};
rt_uint8_t *rd_buff;
rt_err_t ret;
i2c_bus = rt_i2c_bus_device_find("i2c1");
if (RT_NULL == i2c_bus)
{
return;
}
ret = rt_device_open(&(i2c_bus->parent), RT_DEVICE_FLAG_RDWR);
if (RT_EOK != ret)
{
return;
}
cfg.timeout = 5000;
cfg.max_hz = 400000;
if (rt_i2c_configure(i2c_bus, &cfg) !=
HAL_OK)
{
rt_device_close(&(i2c_bus->parent));
return;
}
rd_buff = rt_malloc(100);
if (RT_NULL == rd_buff)
{
rt_device_close(&(i2c_bus->parent));
return;
}
for (int m = 0; m < rw_len; m++)
{
rd_buff[m] = m;
}
msgs.addr = 0xe;
msgs.flags = RT_I2C_WR;
msgs.buf = rd_buff;
msgs.len = 100;
rt_i2c_transfer(i2c_bus, &msgs, 1);
msgs.flags = RT_I2C_RD;
rt_i2c_transfer(i2c_bus, &msgs, 1);
rt_device_close(&(i2c_bus->parent));
}
- Note
- DMA 支持是通過 menuconfig 工具配置的,要使用 DMA,開發(fā)者需要在打開設(shè)備時(shí)設(shè)置相應(yīng)的標(biāo)志。