Zephyr配置使用w5500
本文演示如何配置使用w5500.
Zephyr中含有大量的外设驱动,根据实际的硬件经过简单的配置就可以轻松的使用外设驱动,从而避免繁重的驱动开发和调试工作。本文基于mm_feather开发板演示如何配置使用w5500。
设备树 链接到标题
增加一个w5500 链接到标题
W5500是一款高性价比的以太网芯片,通过SPI接口和MCU进行高速通信,MCU作为SPI主机,W5500作为SPI从机。MCU和W5500通信的硬件连接引脚如下:
| W5500 PIN | MCU LPSPI PIN | 连接/作用 |
|---|---|---|
| SCK | LPSPI4 SCK | MCU SPI时钟/输出到W5500 |
| MOSI | LPSPI4 MOSI | MCU SPI数据/输出到W5500 |
| MISO | LPSPI4 MISO | MCU SPI数据输入/从W5500读数据 |
| CS | GPIO1.26 | MCU SPI片选/输出信号选择W5500的SPI |
| INT | GPIO1.28 | MCU 中断输入引脚/接收W5500的中断 |
| RST | GPIO2.18 | MCU GPIO/输出复位信号复位W5500 |
得益于Zephyr的设备树,再根据上面的硬件连接添加一个外设十分方便,在mm_feather.dts中原本有使能lpspi4
&lpspi4 {
status = "okay";
pcs-sck-delay = <2>;
sck-pcs-delay = <2>;
transfer-delay = <2>;
};
现在我们要将w5500做为device挂在lpspi4的总线下,devicetree写为
&lpspi4 {
status = "okay";
pcs-sck-delay = <2>;
sck-pcs-delay = <2>;
transfer-delay = <2>;
cs-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>;
w5500: w5500@0 {
compatible = "wiznet,w5500";
label = "w5500";
reg = <0>;
spi-max-frequency = <49000000>;
int-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
};
};
-
cs-gpios这里将lpspi使用的片选指定为GPIO控制 -
w5500@0表示lpspi4下面挂的第一个device -
compatible指定了w5500的绑定文件,对应到绑定文件就是dts/bindings/ethernet/wiznet,w5500.yaml -
wizent,w5500.yaml中包含了spi-device.yaml,提供了-
label是所有节点都含有的,代码中访问驱动名由lable指定的w5500 -
reg指定该spi device的寄存器序号,当有多个device时要和cs-gpios来对应 -
spi-max-frequency指定device的spi通信最大速率
-
-
int-gpiosw5500的中断输出引脚 -
reset-gpiosw5500的复位输入引脚
增加多个设备 链接到标题
这里简单示例一下,一个spi下挂多个device的写法,例如在lpspi4下除了w5500外又加挂了一个enc28j60作为双网卡通信
&lpspi4 {
status = "okay";
pcs-sck-delay = <2>;
sck-pcs-delay = <2>;
transfer-delay = <2>;
cs-gpios = <&gpio1 26 GPIO_ACTIVE_LOW>,
<&gpio1 27 GPIO_ACTIVE_LOW>;
w5500: w5500@0 {
compatible = "wiznet,w5500";
label = "w5500";
reg = <0>;
spi-max-frequency = <49000000>;
int-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 18 GPIO_ACTIVE_LOW>;
};
enc28j60: enc28j60@1 {
compatible = "microchip,enc28j60";
label = "ENC28J60";
reg = <0x1>;
spi-max-frequency = <10000000>;
int-gpios = <&gpio2 12 0>;
};
};
这里就可以很清晰的看到cs-gpio是这一组gpio,其顺序对应于后面spi device节点的reg序号,也就是gpio1.26为w5500的片选,gpio1.27为enc28j60的片选。
配置 链接到标题
在设备树中将w5500添加好后,也就为驱动提供了必要的硬件信息,最后就只用在配置选项中开启编译选项,就可能使用W5500了,配置选项的说明如下
#启用zephyr网络
CONFIG_NETWORKING=y
# w5500是从L2 ethernet接入,配置L2
CONFIG_NET_L2_ETHERNET=y
# 配置启用w5500
CONFIG_ETH_W5500=y
#以下配置是纯TCP/IP协议栈的,可以按需增加和减少
CONFIG_NET_IPV4=y
CONFIG_NET_DHCPV4=n
CONFIG_NET_UDP=y
CONFIG_NET_TCP=y
CONFIG_NET_ARP=y
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.168.101.33"
PinMux 链接到标题
现代的MCU大多数都支持pinmux,目前zephyr对rt系列芯片的Pinmux支持不全,因此还需要添加引脚功能的初始化。这步对于其它soc并不是必须,例如nrf的直接在设备树中就可以指定。
在/boards/arm/mm_feather/pinmux.c中增加如下代码
#if DT_NODE_HAS_STATUS(DT_NODELABEL(lpspi4), okay) && CONFIG_ETH_W5500
// 配置spi4的引脚功能
IOMUXC_SetPinMux(IOMUXC_GPIO_B0_01_LPSPI4_SDI, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_B0_02_LPSPI4_SDO, 0U);
IOMUXC_SetPinMux(IOMUXC_GPIO_B0_03_LPSPI4_SCK, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_01_LPSPI4_SDI, 0x10B0u);
IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_02_LPSPI4_SDO, 0x10B0u);
IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_03_LPSPI4_SCK, 0x10B0u);
// 配置reset的引脚功能
IOMUXC_SetPinMux(IOMUXC_GPIO_B1_02_GPIO2_IO18, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_B1_02_GPIO2_IO18, IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2) |
IOMUXC_SW_PAD_CTL_PAD_DSE(6));
// 配置cs的引脚功能
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_10_GPIO1_IO26, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_10_GPIO1_IO26, IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2) |
IOMUXC_SW_PAD_CTL_PAD_DSE(6));
// 配置INT的引脚功能
IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_12_GPIO1_IO28, 0U);
IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_12_GPIO1_IO28, IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2) |
IOMUXC_SW_PAD_CTL_PAD_DSE(6));
#endif