I2C是我们常用的外设功能之一,CSK6 SDK I2C外设驱动采用标准的I2C总线协议,本节我们将通过示例演示如何使用 MCU 的虚拟 i2c 从机通信功能,通过其他 i2c 主设备向从设备的寄存器地址写数据和读数据,使用串口观察结果。
CSK6 芯片有两个 I2C 硬件外设。
CSK6 I2C驱动功能特性如下:
CSK6 做 I2C 从机时,暂不支持多字节读操作。
演示如何使用 MCU 的虚拟 i2c 从机通信功能,通过其他 i2c 主设备向从设备的寄存器地址写数据和读数据,使用串口观察结果。
{SDK}\.sdk\csk\samples\driver\i2c\i2c_slave_vdev
适用开发板:大模型开发套件
编译版型:csk6_duomotai_devkit
使用引脚:
GPIOA_10 与 GPIOA_11 在本开发套件上默认连接了 DVP 摄像头模组,为保证实验效果,建议运行本示例前拆下摄像头模组。
通常 I2C 通讯 SCL 和 SDA 之间都需要接上拉电阻(大小由速度和容性负载决定一般在3.3K-10K之间)以保证数据的稳定性,减少干扰,如下图示:
在 SDK 根目录(duomotai_ap
)下可通过执行以下指令进行对该示例工程的编译:
lisa zep build -b csk6_duomotai_devkit .sdk/csk/samples/driver/i2c/i2c_slave_vdev -p
使用 Type-C 数据线连接开发套件的 DAP_USB
接口,选中以下其中一种方式对固件进行烧录:
cskburn desktop
是一款聆思推出的桌面烧录工具,在下载并安装 cskburn desktop 烧录工具后,双击图标运行软件:
1.点击串口下拉框,选择连接开发套件后识别到的串口编号;
2.将编译输出的.bin
文件拖拽进烧录区域;
3.点击开始烧录,等待烧录完成。
若您已按照 《环境搭建》 教程完成开发环境的安装,可在编译完成后执行 lisa zep exec cskburn
指令完成烧录。
lisa zep exec cskburn -s \\.\COMxx -C 6 -b 1500000 0x000000 --verify-all .\build\zephyr\zephyr.bin
请将命令行中的的 COMx 替换为开发套件在 PC 上对应的串口号(可通过设备管理器查看)。例如:
COM3
。
lisa zep exec cskburn -s PORT -C 6 0x000000 --verify-all ./build/zephyr/zephyr.bin -b 1500000
请将命令行中的 PORT 替换为开发套件连接在 PC 上对应的串口号。例如:
/dev/ttyUSB0
。
连接 DAP_USB
并使用串口终端连接串口,在开发板复位时我们也可以看到这个示例的代码的日志输出信息:
当通过 I2C 主设备向开发板的 I2C 从机地址(0x32)读写数据时,可通过串口观察到读写的状态与数据。
以下代码与注释已省略一部分非关键接口代码,主要呈现示例的主业务流程与主要接口的使用。
在工程目录prj.conf
文件中需配置以下模块:
# I2C配置
CONFIG_I2C=y
CONFIG_I2C_LOG_LEVEL_INF=y
CONFIG_I2C_SLAVE=y
CONFIG_I2C_SLAVE_INIT_PRIORITY=60
CONFIG_I2C_SLAVE_VIRTUAL_DEVICE=y
开发板提供了多组 I2C。本示例使用i2c0(GPIO_A_10, GPIO_A_11)
这组GPIO口,因此需要在设备树中将这两组 GPIO 复用为 I2C 引脚功能,可通过boards
目录下 overlay 文件的方式完成 I2C 引脚的设备树配置。
设备树文件csk6_duomotai_devkit.overlay
配置如下:
/*
* SPDX-License-Identifier: Apache-2.0
*/
&pinctrl {
/* 将GPIOA_10配置为i2c0 scl */
pinctrl_i2c0_scl_default: i2c0_scl_default{
pinctrls = <I2C0_SCL_GPIOA_10>;
};
/* 将GPIOA_11配置为i2c0 sda */
pinctrl_i2c0_sda_default: i2c0_sda_default{
pinctrls = <I2C0_SDA_GPIOA_11>;
};
};
&i2c0 {
status = "okay";
pinctrl-0 = <&pinctrl_i2c0_scl_default &pinctrl_i2c0_sda_default>;
pinctrl-names = "default";
i2cslavevdev0: i2cslavevdev@32 {
compatible = "listenai,i2c-slavevdev";
reg = <0x32>;
size = <256>;
};
};
如果需要修改 I2C 引脚或通道,可在SDK的.sdk\csk\dts\arm\csk\csk6-pinctrl.h
文件中查看可使用的IO口,该文件定义了芯片所有IO口可用外设功能,开发者仅需要选择对应的 IO 即可,例如:
#define I2C0_SCL_GPIOA_00 CSK6_PINMUX(a, 0, 8)
#define I2C0_SDA_GPIOA_01 CSK6_PINMUX(a, 1, 8)
#define I2C0_SCL_GPIOA_02 CSK6_PINMUX(a, 2, 8)
#define I2C0_SDA_GPIOA_03 CSK6_PINMUX(a, 3, 8)
#define I2C0_SCL_GPIOA_04 CSK6_PINMUX(a, 4, 8)
#define I2C0_SDA_GPIOA_05 CSK6_PINMUX(a, 5, 8)
#define I2C0_SCL_GPIOA_06 CSK6_PINMUX(a, 6, 8)
#define I2C0_SDA_GPIOA_07 CSK6_PINMUX(a, 7, 8)
#define I2C0_SCL_GPIOA_08 CSK6_PINMUX(a, 8, 8)
#define I2C0_SDA_GPIOA_09 CSK6_PINMUX(a, 9, 8)
#define I2C0_SCL_GPIOA_10 CSK6_PINMUX(a, 10, 8)
#define I2C0_SDA_GPIOA_11 CSK6_PINMUX(a, 11, 8)
#define I2C0_SCL_GPIOA_12 CSK6_PINMUX(a, 12, 8)
#define I2C0_SDA_GPIOA_13 CSK6_PINMUX(a, 13, 8)
#define I2C0_SCL_GPIOA_14 CSK6_PINMUX(a, 14, 8)
…
如果您想了解更多关于设备树的信息,请学习设备树章节。
1.i2c 虚拟从设备初始化
i2_slave_vdev_init();
2.配置i2c 虚拟从设备事件处理回调
slave_vdev_event_handler_register(i2_vdev_0, &vdev_handler);
3.启动i2c 虚拟从设备事件处理任务
start_slave_vdev_handler_task(i2_vdev_0);
void i2_slave_vdev_init(void)
{
int ret;
i2_vdev_0 = DEVICE_DT_GET(NODE_VIRTUAL_DEV);
int addr_0 = DT_REG_ADDR(NODE_VIRTUAL_DEV);
if (i2_vdev_0 == NULL) {
LOG_ERR("I2C Slave Virtual device not found \n");
return;
}
LOG_INF("I2C Addr: 0x%X", addr_0);
int i = 0;
for (i = 0; i < TEST_DATA_SIZE; i++) {
i2_vdev_0_data[i] = i;
}
ret = slave_vdev_program(i2_vdev_0, i2_vdev_0_data, TEST_DATA_SIZE);
/* Attach each i2_vdev to its owning bus as a slave device. */
ret = i2c_target_driver_register(i2_vdev_0);
}