DOCUMENTATION NETWORK Ethernet
Overview
Getting Started
BASE
Reference
Worker
Setup modules
COMMODETTO
Reference
Poco Renderer
Outlines
Creating Fonts
Crypt
Data
DEVICES
Moddable One
Moddable Two
Moddable Three
Moddable Four
Moddable Six
ESP32
ESP8266
nRF52
nRF52 Low Power Notes
Raspberry Pi Pico
M5Core Ink
M5Paper
Wasm
SiLabs Gecko
QCA4020
Moddable Zero
Moddable Display Developer Guide
DISPLAYS
Overview
Adafruit 1.8" ST7735
Adafruit OLED Display
BuyDisplay 2.8" CTP - ESP8266
Crystalfontz ePaper
DotStar
Generic 1.44"
Generic 2.4" & 2.8" (Resistive Touch) - ESP32
Generic 2.4" & 2.8" (Resistive Touch) - ESP8266
Generic 2.4" & 2.8" (Resistive Touch) - Pico
Sharp Memory
Sharp Memory Screen 1.3"
SparkFun TeensyView
Switch Science Reflective LCD
DRIVERS
DESTM32S display
DotStar display
ILI9341 display
LPM013M126A display
LS013B4DN04 display
MCP230XX GPIO expander
NeoStrand
SSD1306 display
SSD1351 display
ST7735 display
Files
IO
TC53 IO
Firmata
NETWORK
Reference
TLS (SecureSocket)
BLE
Ethernet
Web Things
PINS
Reference
Audio Output
PIU
Reference
Localization
Keyboard
Expanding Keyboard
Die Cut
Using After Effects Motion Data
TOOLS
Reference
Manifest
Defines in Manifests
Testing
XS
Handle
JavaScript language considerations on embedded devices using the XS engine
Mods – User Installed Extensions
ROM Colors
Using XS Preload to Optimize Applications
XS Conformance
XS Marshalling
XS Platforms
XS in C
XS linker warnings
xsbug
xst
XS Compartment
XS Profiler
XS Scopes

Ethernet

Copyright 2021 Moddable Tech, Inc.
Revised: September 10, 2024

Overview

The Moddable SDK supports Ethernet for the ESP32. Ethernet support is an extension to our network support, which includes support for Wi-Fi and protocols like HTTP/HTTPS, MQTT, WebSockets, DNS, and mDNS. Most of the networking examples in the Moddable SDK enable Wi-Fi by default; however, examples that work with Wi-Fi can easily be modified to use Ethernet instead.

This document provides information about how to enable Ethernet in applications, details of the JavaScript API used to establish and monitor an Ethernet connection, and wiring instructions for a compatible Ethernet breakout board.

Table of Contents

Configuration

The Moddable SDK supports any Ethernet module that can be wired into the hardware and integrated with the ESP-IDF. We've worked with various Microchip ENC28J60 and WIZnet W5500 SPI-to-Ethernet module breakout boards and achieved good results.

The ESP32 processors and their SDK offer excellent support for Ethernet. They support both internal Ethernet MAC controllers and external SPI-to-Ethernet modules. The WT32-ETH01 modules use the ESP32's internal MAC and an external PHY chip for Ethernet support (see $MODDABLE/build/devices/esp32/targets\wt32_eth01). You specify esp32/wt32_eth01 as the device. The sdkconfig.defaults file specifies whether to enable Ethernet and the type of Ethernet module or interface to use. For the WT32-ETH01 to use the internal MAC and external PHY, it requires the target device's sdkconfig.defaults file to contain:

CONFIG_ETH_ENABLED=y
CONFIG_ETH_USE_ESP32_EMAC=y
CONFIG_ETH_PHY_INTERFACE_RMII=y
CONFIG_ETH_RMII_CLK_INPUT=y
CONFIG_ETH_RMII_CLK_IN_GPIO=0
CONFIG_ETH_DMA_BUFFER_SIZE=512
CONFIG_ETH_DMA_RX_BUFFER_NUM=10
CONFIG_ETH_DMA_TX_BUFFER_NUM=10

For the WIZnet W5500, it requires the sdkconfig.defaults in the target processor to contain:

CONFIG_ETH_ENABLED=y
CONFIG_ETH_USE_SPI_ETHERNET=y
CONFIG_ETH_SPI_ETHERNET_W5500=y

Using the ENC28J80 module with an ESP32, it is installed using the dependency feature in $MODDABLE/modules/network/ethernet/manifest.json to dynamically load the module and associated files for the device, including the sdkconfig values.

         {
           "name": "enc28j60",
           "version": "^1.0.1",
           "includes": [
             "include"
           ]
         }
       ],

The $MODDABLE/modules/network/ethernet directory contains a manifest.json_enc28j60 and manifest.json_w5500 file. One of these needs to be copied to manifest.json to define the Ethernet -SPI setup parameters for the particular chip.

     "defines": {
        "ethernet": {
        	"enc28j60": 1,
        	"w5500": 0,
			"hostname":"\"Moddable\"",
            "hz": 6000000,
            "int_pin": 33,
            "spi": {
            	"command_bits": 3,
				"address_bits": 5,
                "cs_pin": 27,
                "port": "SPI3_HOST",
                "miso_pin": 35,
                "mosi_pin": 26,
                "sck_pin": 0,
                "polling_ms": 0,
				"dma_ch": 3
            }
        }
    }

The drivers in $MODDABLE/modules/network/ethernet/esp32/drivers contain the code that calls the setup functions for the Ethernet MAC and PHY components in the Espressif SDK. The main Ethernet code is in $MODDABLE/modules/network/ethernet/esp32/ethernet.c and is primarily driven by the values specified in the manifest.json file.

The CMakeLists.txt file for the target device needs to specify that it includes the Ethernet libraries from the ESP32 SDK. For the add_prebuilt_library line, it needs to look similar to

add_prebuilt_library(xsesp32 ${CMAKE_BINARY_DIR}/xs_${ESP32_SUBCLASS}.a
			REQUIRES esp_timer esp_wifi spi_flash bt esp_lcd nvs_flash spiffs  esp_driver_gpio esp_driver_spi esp_eth esp_netif log ${ESP_COMPONENTS}
		)

Example, for the ESP32-S3, you will find the file in $MODDABLE/build/devices/esp32/xsProj-esp32s3/main/CMakeLists.txt and the sdkconfig.defaults in the directory above.

Wiring

This section contains wiring information for ENC28J60 modules (examples pictured below), which is directly applicable to W5500 modules.

The ESP32 communicates with the ENC28J60 over the SPI interface.

ENC28J60 ESP32
INT GPIO 33
CS GPIO 27
MISO GPIO 35
MOSI GPIO 26
SCK GPIO 0
PWR PWR
GND GND

The diagram below shows a Moddable Two (an ESP32-based hardware module) wired to a HanRun ENC28J60 module.

You can use other ESP32-based development boards too. Many developers use NodeMCU ESP32 boards, pictured in the diagram below. These boards require you to solder to the GPIO 0 pad since they do not have a pinout for GPIO 0 (because GPIO 0 is used by the BOOT button).

Enabling Ethernet in Applications

Most of the networking examples in the Moddable SDK enable Wi-Fi by default. They do this by including the manifest_net.json manifest.

"include": [
	/* other included manifests here */
	"$(MODDABLE)/examples/manifest_net.json"
],

If you want to use Ethernet in these examples, you can simply replace manifest_net.json with manifest_net_ethernet.json. Note that you should not include both manifest_net.json and manifest_net_ethernet.json; only include one or the other.

"include": [
	/* other included manifests here */,
	"$(MODDABLE)/modules/network/ethernet/manifest_net_ethernet.json"
],

The manifest_net_ethernet.json manifest includes a setup/network module that automatically sets up the connection to Ethernet. The connection is set up before the rest of the application runs. In other words, the device connects to Ethernet, then the application's main module is executed. If the device is unable to connect to Ethernet, the main module is never executed.

You may choose to remove the setup/network module from your own applications and instead set up and monitor the Ethernet connection in the application code using the JavaScript APIs described in the Class Ethernet section below.

ESP-IDF ENC28J60 Driver Multicast Packet Issue

The ENC28J60 driver in the ESP-IDF contains a bug that causes multicast packets to be filtered out in hardware. Moddable has fixed this bug via an ESP-IDF pull request that will be included in a future ESP-IDF release. Until that time, if your project needs multicast you can apply this small fix in the file $IDF_PATH/examples/ethernet/enc28j60/main/esp_eth_mac_enc28j60.c, lines 551-552:

-    // set up default filter mode: (unicast OR broadcast) AND crc valid
-    MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN) == ESP_OK,
+    // set up default filter mode: (unicast OR broadcast OR multicast) AND crc valid
+    MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN | ERXFCON_MCEN) == ESP_OK,

Class Ethernet

The Ethernet class provides access to use and configure the Ethernet capabilities of an Ethernet module.

import Ethernet from "ethernet";

The software for Ethernet is nearly identical to Wi-Fi with the exception of establishing a connection. Since Ethernet implements the same API as Wi-Fi, you can mostly use Ethernet as a drop-in replacement to Wi-Fi in examples from the Moddable SDK and in your own applications, rather than rewriting large portions of them.

static start()

The start method begins the underlying process to manage the device's connection to the network.

Ethernet.start();

constructor(callback)

The Ethernet constructor creates a monitor for the Ethernet status. It takes a callback function to receive status messages. Messages are strings representing the state of the Ethernet connection. The Ethernet class has properties that correspond to each string as a convenience for developers.

Property Description
Ethernet.connected Physical link established
Ethernet.disconnected Physical link lost
Ethernet.gotIP IP address has been assigned via DHCP and network connection is ready for use
Ethernet.lostIP IP address has been lost and network connection is no longer usable

Note: Applications must call the static start method of the Ethernet class to initiate the Ethernet connection. Without calling start, the callback passed into the Ethernet constructor will never be called.

Ethernet.start();
let monitor = new Ethernet((msg) => {
	switch (msg) {
		case Ethernet.disconnected:
			// Ethernet disconnected
			break;
		case Ethernet.gotIP:
			// Got IP address
			break;
	}
});

close()

The close method closes the connection between the Ethernet instance and the underlying process managing the device's connection to the network. In other words, it prevents future calls to the callback function, but it does not disconnect from the network.

let monitor = new Ethernet((msg) => {
	trace(`Ethernet msg: ${msg}\n`);
});

monitor.close();

Example: Get Ethernet IP address

The following example begins the process of connecting to Ethernet and traces to the console when the connection succeeds with an IP address being assigned to the Ethernet device.

The Net.get method can be used to get the IP and MAC addresses of the Ethernet interface, as with Wi-Fi. An optional second argument to Net.get specifies which interface to query: "ethernet", "ap", or "station". If no second argument is provided, Net.get defaults to the active network interface (for example, when the only network connection is Ethernet, the Ethernet interface is the default).

Ethernet.start();
let monitor = new Ethernet((msg) => {
	switch (msg) {
		case Ethernet.connected:
			trace(`Physical link established. Waiting for IP address.\n`);
			break;

		case Ethernet.gotIP:
			let ip = Net.get("IP", "ethernet");
        	trace(`Ethernet connected. IP address ${ip}\n`);
        	break;

		case Ethernet.disconnected:
			trace(`Ethernet connection lost.\n`);
			break;
    }
});

Example: Get MAC address of Ethernet device

The following example gets the MAC address of the Ethernet device and traces it to the console.

The Net.get method is documented in the Net section of the networking documentation. Note that there is a second argument passed into the Net.get function in this example: the string "ethernet". This specifies that you want to get the MAC address of the ethernet device, not the MAC address of the Wi-Fi device on the ESP32.

let mac = Net.get("MAC", "ethernet");
trace(`Ethernet MAC address is ${mac}\n`);