# Adding a W5500 ethernet adapter to Zephyr (ESP32)

**URL:** <https://hub.mender.io/t/adding-a-w5500-ethernet-adapter-to-zephyr-esp32/7692>\
**Category:** Zephyr\
**Created:** [April 4, 2025, 9:24am UTC](https://hub.mender.io/t/adding-a-w5500-ethernet-adapter-to-zephyr-esp32/7692 "2025-04-04T09:24:05Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![TheYoctoJester](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/theyoctojester/32/1444_2.png) [@TheYoctoJester](https://hub.mender.io/u/TheYoctoJester)\
**Post date:** [April 4, 2025, 9:24am UTC](https://hub.mender.io/t/adding-a-w5500-ethernet-adapter-to-zephyr-esp32/7692/1 "2025-04-04T09:24:05Z")

</div>

## Introduction

The ESP32 family is a very popular platform for getting started with Zephyr. It is cheap, easy to obtain and offers integrated WiFi connectivity. It’s also the reference board for the Mender MCU client.

But there are times when WiFi doesn’t cut it, right? Sometimes you just want a plain old wired connection.

Good news is that Zephyr offers a rich variety of drivers for hardware support. Amongst these is the [W5500](https://wiznet.io/products/iethernet-chips/w5500), specifically as a shield such as [ARCELI W5500 ETH — Zephyr Project Documentation](https://docs.zephyrproject.org/latest/boards/shields/arceli_eth_w5500/doc/index.html).

We will use a slightly miniaturized variant, but as they all behave identical just pick whichever is easy to obtain for you.

 ![W5500SPIEthernetModul-144081_1920x1920](https://canada1.discourse-cdn.com/flex036/uploads/mender/original/2X/2/2667fa4a3a6551ba4a5aee882343f3d578fb8976.jpeg) ![W5500SPIEthernetModul-144080_1920x1920](https://canada1.discourse-cdn.com/flex036/uploads/mender/original/2X/7/71bb47fa3e692e44dd73348a9aca1a921af997d4.jpeg)

## Prerequisites

To follow this tutorial, you need a Zephyr workspace matching your board already set up. We will use the ESP32-S3-DevKitC, so you can just follow the [Getting Started tutorial](https://hub.mender.io/t/getting-started-with-the-mender-mcu-client-esp32-s3-devkitc/7480) to prepare everything required.

Given this setup, we will build the `mender-mcu-integration` target. If you want to use a different one, please adapt the paths of the created files and build invocation accordingly.

## Use ethernet instead of WiFi

### Making the connection

The W5500 requires a number of connections. A power supply, SPI port and two GPIO lines for reset and interrupt. Below is a suggestion which is known to work as a starting point:

```auto
W5500 V -> J1-Pin 1 / 3.3V
W5500 RES -> J1-Pin 5 / GPIO5
W5500 MI -> J1-Pin 19 / GPIO13
W5500 INT -> J1-Pin 4 / GPIO4
W5500 CS -> J1-Pin 16 / GPIO10
W5500 SCK -> J1-Pin 18 / GPIO12
W5500 MO -> J1-Pin 17 / GPIO11
W5500 G -> J3-Pin 1 / G

```

An example setup might look like that:

 ![IMG_0038](https://canada1.discourse-cdn.com/flex036/uploads/mender/original/2X/e/e8b46824cb5e4dd0208d9923283b0159317d9eba.jpeg)

### Port configuration

In order to access the new peripheral from Zephyr, it must be configured accordingly in the so-called device tree. This is a build time mechanism to declare the available hardware, usually focused on the peripherals which extend a specific base board. We will only use the overlay mechanism, which is meant for exactly that use case.

Create a file called `mender-mcu-integration/my_w5500.overlay` with the following content:

```auto
&spi2 {
  status = "okay";
  eth_w5500: eth_w5500@0 {
    compatible = "wiznet,w5500";
    status = "okay";
    reg = <0x0>;
    spi-max-frequency = <8000000>;
    int-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
    reset-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
    /* *************************** */
    /* Write here your MAC address */
    /* *************************** */
    local-mac-address = [00 08 DC 01 02 03];
  };
};

```

Thats quite a mouthful, so lets break it down a bit.

First, the SPI port is enabled. Unless some other peripheral or overlay is already doing the same, the default for `status` is `"disabled"`. Overlays are merged down, so the last one “wins”. Hence, a common practise is for the base device tree definition to only activate the absolute minimum of peripherals to boot and run a specific board. Overlays then only do enable the pieces they require. In our case for `spi2` this is:

```auto
&spi2 {
  status = "okay";
  ...
}

```

Next we define the ethernet peripheral we want to use. The important parts here are first the `compatible` string, which defines the driver to be used. There is somewhat complex matching involved, but it shall suffice here to say that if a string here matches the string which a driver provides, then the driver is instantiated for this instance. And second, of course, is to enable the peripheral explicitly as we do want to use it.

```auto
eth_w5500: eth_w5500@0 {
  compatible = "wiznet,w5500";
  status = "okay";
  ...
};

```

There are a few more detailed settings which are required. The most important ones are:

```auto
int-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
local-mac-address = [00 08 DC 01 02 03];

```

Those configure the GPIO lines for the interrupt and reset lines, and provide the MAC address to be used.

After this, the Zephyr networking stack needs to be configured.

### Enabling the driver

Zephyr uses the `Kconfig` configuration system which was originally created for the Linux kernel. It is based on configuration files which define all desired `CONFIG_*` statements and therefore reasonably convenient to read. However modifying them directly is not recommended unless you are very familiar with the inner folkings of the concerned subsystem because there are a lot of dependencies are mutual exclusions amongst options. Therefore, use the `west -b menuconfig` facility to this avail.

The resulting configuration files do not necessarily have to be full-featured and covering all possible options. Just like for the device tree, additional fragments are the equivalent of overlays here. Those can be used to add specific parts to a base configuration, and we will also use this.

Create a file `mender-mcu-integration/my_w5500.conf` with the following content:

```auto
CONFIG_WIFI=n
CONFIG_SPI=y
CONFIG_NET_MGMT=y
CONFIG_NET_L2_ETHERNET=y
CONFIG_ETH_W5500=y
CONFIG_ETH_W5500_TIMEOUT=1000

```

This has a number of effects:

- SPI support is added by enabling the corresponding subsystem

- WiFI support is disabled. Technically you could have both at the same time, but for ease of use we “force” the network stack to ethernet in this tutorial

- ethernet and the corresponding link management support are enabled

- the W5500 driver is enabled and configured for a slightly longer timeout than default

### Build and flash

The last thing remaining is to build. Being based on the `mender-mcu-integration` setup, the invocation could be this:

```auto
west build --sysbuild -board esp32s3_devkitc/esp32s3/procpu mender-mcu-integration -- \
-DEXTRA_CONF_FILE=mender.conf \
-DEXTRA_CONF_FILE=my_w5500.conf \
-DEXTRA_DTC_OVERLAY_FILE=my_w5500.overlay
-DCONFIG_MENDER_ARTIFACT_NAME=\"w5500\"

```

If you are using a different project, adjust board and target accordingly, and disregard the `mender.conf` fragment.

Flash the board, and watch it connect:

```auto
west flash && west espressif monitor

```

will print something similar to

```auto
[1970-01-01T00:00:01,714000Z] <inf> eth_w5500: eth_w5500@0: Link up
[1970-01-01T00:00:07,246000Z] <inf> net_dhcpv4: Received: 192.168.89.36

```

early during boot. Probably with a different IP address. 🙂

## Conclusion

Zephyr offers a number of building blocks which make it very easy to add new peripherals to an existing board:

- the Kconfig configuration system and its fragments

- device tree description of the hardware and its overlays

- an extensive and growing ecosystem of subsystems and drivers

This tutorial can be used as a blueprint to connect and use a lot of other peripherals. So what will you build next? Let us know!
