本文演示如何配置使用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
1 | &lpspi4 { |
现在我们要将w5500做为device挂在lpspi4
的总线下,devicetree写为
1 | &lpspi4 { |
cs-gpios
这里将lpspi使用的片选指定为GPIO控制w5500@0
表示lpspi4
下面挂的第一个devicecompatible
指定了w5500的绑定文件,对应到绑定文件就是dts/bindings/ethernet/wiznet,w5500.yaml
wizent,w5500.yaml
中包含了spi-device.yaml
,提供了label
是所有节点都含有的,代码中访问驱动名由lable
指定的w5500reg
指定该spi device的寄存器序号,当有多个device时要和cs-gpios来对应spi-max-frequency
指定device的spi通信最大速率
int-gpios
w5500的中断输出引脚reset-gpios
w5500的复位输入引脚
增加多个设备
这里简单示例一下,一个spi下挂多个device的写法,例如在lpspi4
下除了w5500外又加挂了一个enc28j60作为双网卡通信
1 | &lpspi4 { |
这里就可以很清晰的看到cs-gpio
是这一组gpio,其顺序对应于后面spi device节点的reg
序号,也就是gpio1.26为w5500的片选,gpio1.27为enc28j60的片选。
配置
在设备树中将w5500添加好后,也就为驱动提供了必要的硬件信息,最后就只用在配置选项中开启编译选项,就可能使用W5500了,配置选项的说明如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#启用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
中增加如下代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 配置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));