I2C 总线适配器相关信息位于“libsylixos/SylixOS/system/device/i2c”下,其适配器创建函数原型如下:
#include <SylixOS.h>
INT API_I2cAdapterCreate (CPCHAR pcName,
PLW_I2C_FUNCS pi2cfunc,
ULONG ulTimeout,
INT iRetry)
函数 API_I2cAdapterCreate 原型分析:
- 此函数成功返回 ERROR_NONE,失败返回 PX_ERROR;
- 参数 pcName 是 I2C 适配器的名称,即 shell 命令 buss 显示的名称;
- 参数 pi2cfunc 是 I2C 总线传输函数的指针;
- 参数 ulTimeout 是操作超时时间;
- 参数 iRetry 是传输出错时的重试次数。
函数 API_I2cAdapterCreate使用结构体PLW_I2C_FUNCS 来向内核提供传输函数集合,其详细描述如下:
#include <SylixOS.h>
typedef struct lw_i2c_funcs {
INT (*I2CFUNC_pfuncMasterXfer)(PLW_I2C_ADAPTER pi2cadapter,
PLW_I2C_MESSAGE pi2cmsg,
INT iNum);
INT (*I2CFUNC_pfuncMasterCtl)(PLW_I2C_ADAPTER pi2cadapter,
INT iCmd,
LONG lArg);
} LW_I2C_FUNCS;
typedef LW_I2C_FUNCS *PLW_I2C_FUNCS;
- I2CFUNC_pfuncMasterXfer:I2C 传输函数,I2C 设备会直接调用此函数实现消息发
送。
第一个参数 pi2cadapter 为 I2C 总线适配器指针,
第二个参数 pi2cmsg 为 I2C 设备需要传输的消息结构体首地址指针,
第三个参数 iNum 为需要传输的消息个数,
通过以上三个参数即可知道 I2C 设备如何调用此函数实现消息传输; - I2CFUNC_pfuncMasterCtl:I2C 适配器控制函数,用来实现与硬件控制器相关的控
制。
第一个参数 pi2cadapter 为 I2C 总线适配器指针,
第二个参数 iCmd 为控制命令,
第三个参数 lArg 与 iCmd 相关。
注意:I2CFUNC_pfuncMasterCtl 函数是按照开发人员的需求实现,通常情况下不实现。
注册到内核的传输函数集合中要用到多种结构体,
PLW_I2C_ADAPTER 总线适配器结构体指针主要包含当前总线适配器节点信息,
PLW_I2C_DEVICE 总线设备结构体指针主要包含当前 I2C 设备的相关信息,
PLW_I2C_MESSAGE 消息请求结构体指针作用是指向需要发送的消息缓冲区,
提供以上三种结构体后控制器即可知道如何进行发送,各种结构体的详细描述如下:
首先介绍 I2C 总线适配器结构体,该结构体详细描述如下:
typedef struct lw_i2c_adapter {
LW_BUS_ADAPTER I2CADAPTER_pbusadapter; /* 总线节点 */
struct lw_i2c_funcs *I2CADAPTER_pi2cfunc; /* 总线适配器操作函数 */
LW_OBJECT_HANDLE I2CADAPTER_hBusLock; /* 总线操作锁 */
ULONG I2CADAPTER_ulTimeout; /* 操作超时时间 */
INT I2CADAPTER_iRetry; /* 重试次数 */
LW_LIST_LINE_HEADER I2CADAPTER_plineDevHeader; /* 设备链表 */
} LW_I2C_ADAPTER;
typedef LW_I2C_ADAPTER *PLW_I2C_ADAPTER;
- I2CADAPTER_pbusadapter:系统总线节点结构体;
- I2CADAPTER_pi2cfunc:指向总线适配器的操作函数,即 API_I2cAdapterCreate 函数注册到核心层的操作函数集指针;
- I2CADAPTER_hBusLock:I2C 总线锁,不需要手动处理;
- I2CADAPTER_ulTimeout:操作超时时间;
- I2CADAPTER_iRetry:传输出错时的重试次数;
- I2CADAPTER_plineDevHeader:指向此适配器下挂载的设备链表,不需要手动处理。
I2C 设备结构体的详细描述如下:
typedef struct lw_i2c_device {
UINT16 I2CDEV_usAddr; /* 设备地址 */
UINT16 I2CDEV_usFlag; /* 标志, 仅支持 10bit 地址选项*/
#define LW_I2C_CLIENT_TEN 0x10 /* 与 LW_I2C_M_TEN 相同 */
PLW_I2C_ADAPTER I2CDEV_pi2cadapter; /* 挂载的适配器 */
LW_LIST_LINE I2CDEV_lineManage; /* 设备挂载链 */
atomic_t I2CDEV_atomicUsageCnt; /* 设备使用计数 */
CHAR I2CDEV_cName[LW_CFG_OBJECT_NAME_SIZE]; /* 设备的名称 */
} LW_I2C_DEVICE;
typedef LW_I2C_DEVICE *PLW_I2C_DEVICE;
- I2CDEV_usAddr:设备地址;
- I2CDEV_usFlag:若从设备的地址为 10bit,则将该标志位值置为LW_I2C_CLIENT_TEN;否则置为 0;
- I2CDEV_pi2cadapter:设备挂载的 I2C 总线适配器;
- I2CDEV_lineManage:设备挂载的链表;
- I2CDEV_atomicUsageCnt:设备使用的计数;
- I2CDEV_cName:设备名称;
I2C 消息结构体是 I2C 主机和从机通信的消息格式,该结构体的详细描述如下:
typedef struct lw_i2c_message {
UINT16 I2CMSG_usAddr; /* 器件地址 */
UINT16 I2CMSG_usFlag; /* 传输控制参数 */
UINT16 I2CMSG_usLen; /* 长度(缓冲区大小) */
UINT8 *I2CMSG_pucBuffer; /* 缓冲区 */
} LW_I2C_MESSAGE;
typedef LW_I2C_MESSAGE *PLW_I2C_MESSAGE;
- I2CMSG_usAddr:器件地址;
- I2CMSG_usFlag:传输控制参数,其取值见表 12.1;
- I2CMSG_usLen:存放消息内容的缓存区大小;
- I2CMSG_pucBuffer:存放消息内容的缓存区。
表 12.1 I2C 传输控制参数取值
传输控制参数的值 | 含义 |
---|---|
LW_I2C_M_TEN | 使用 10bit 设备地址 |
LW_I2C_M_RD | 为读操作,否则为写 |
LW_I2C_M_NOSTART | 不发送 start 标志 |
LW_I2C_M_REV_DIR_ADDR | 读写标志位反转 |
LW_I2C_M_IGNORE_NAK | 忽略 ACK NACK |
LW_I2C_M_NO_RD_ACK | 读操作时不发送 ACK |