Ethernet
Pin configuration - Ethernet
Since 5.3.0:
In Device OS 5.3.x, it is possible to reconfigure the pins that are used for Ethernet control signals CS, RESET, and INT. This may be desirable if you need to use pins D3-D5 for other purposes, such as SPI1
.
In Device OS 5.9.9 and later, it's possible to configure RESET and INT as PIN_INVALID, meaning you are not using hardware reset and interrupt.
The correct order of operations is:
Start with
FEATURE_ETHERNET_DETECTION
disabled this will prevent probing the default GPIO that you are using for other purposes, which may have unintended consequences.It is recommended that you enable threading and SEMI_AUTOMATIC mode because you will need to execute code before connecting to the cloud.
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
- If
Ethernet.isOn()
is false (it's off), then remap the pins. This setting is persistent on reset, cold boot, application firmware flash, and Device OS upgrade. It also is used when in safe mode so Device OS can be upgraded OTA over Ethernet.
if_wiznet_pin_remap remap = {};
remap.base.type = IF_WIZNET_DRIVER_SPECIFIC_PIN_REMAP;
remap.cs_pin = A0;
remap.reset_pin = A2;
remap.int_pin = A1;
auto ret = if_request(nullptr, IF_REQ_DRIVER_SPECIFIC, &remap, sizeof(remap), nullptr);
// ret is SYSTEM_ERROR_NONE on success
- After successful reconfiguration, enable ethernet detection with System.enableFeature(FEATURE_ETHERNET_DETECTION), and then reset the device with System.reset(). This will be fast because the device did not connect to the cloud the first time. This setting is persistent on reset, cold boot, application firmware flash, and Device OS upgrade. It also is used when in safe mode so Device OS can be upgraded OTA over Ethernet.
System.enableFeature(FEATURE_ETHERNET_DETECTION);
System.reset();
In Device OS 6.1.1 and earlier, if you wanted to restore a pin to its default value, you could set it to PIN_INVALID
. This is no
longer possible as PIN_INVALID
is now a usable value for the int_pin
for operation without a hardware interrupt pin.
You must set it back to the actual default pin to restore default pin mapping.
Here's a full sample application for testing:
// SAMPLE APPLICATION
#include "Particle.h"
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
Serial1LogHandler log1Handler(115200, LOG_LEVEL_ALL);
retained uint8_t resetRetry = 0;
void setup() {
#if HAL_PLATFORM_WIFI && !HAL_PLATFORM_WIFI_SCAN_ONLY
// To force Ethernet only, clear Wi-Fi credentials
Log.info("Clear Wi-Fi credentionals...");
WiFi.clearCredentials();
#endif // HAL_PLATFORM_WIFI && !HAL_PLATFORM_WIFI_SCAN_ONLY
// Disable Listening Mode if not required
if (System.featureEnabled(FEATURE_DISABLE_LISTENING_MODE)) {
Log.info("FEATURE_DISABLE_LISTENING_MODE enabled");
} else {
Log.info("Disabling Listening Mode...");
System.enableFeature(FEATURE_DISABLE_LISTENING_MODE);
}
Log.info("Checking if Ethernet is on...");
if (Ethernet.isOn()) {
Log.info("Ethernet is on");
uint8_t macAddrBuf[8] = {};
uint8_t* macAddr = Ethernet.macAddress(macAddrBuf);
if (macAddr != nullptr) {
Log.info("Ethernet MAC: %02x %02x %02x %02x %02x %02x",
macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
}
Ethernet.connect();
waitFor(Ethernet.ready, 30000);
Log.info("Ethernet.ready: %d", Ethernet.ready());
resetRetry = 0;
} else if (++resetRetry <= 3) {
Log.info("Ethernet is off or not detected, attmpting to remap pins: %d/3", resetRetry);
if_wiznet_pin_remap remap = {};
remap.base.type = IF_WIZNET_DRIVER_SPECIFIC_PIN_REMAP;
remap.cs_pin = D10;
remap.reset_pin = D6;
remap.int_pin = D7;
auto ret = if_request(nullptr, IF_REQ_DRIVER_SPECIFIC, &remap, sizeof(remap), nullptr);
if (ret != SYSTEM_ERROR_NONE) {
Log.error("Ethernet GPIO config error: %d", ret);
} else {
if (System.featureEnabled(FEATURE_ETHERNET_DETECTION)) {
Log.info("FEATURE_ETHERNET_DETECTION enabled");
} else {
Log.info("Enabling Ethernet...");
System.enableFeature(FEATURE_ETHERNET_DETECTION);
}
delay(500);
System.reset();
}
}
Particle.connect();
}
void loop() {
static system_tick_t lastPublish = millis();
static int count = 0;
static bool reconnect = false;
if (Particle.connected()) {
reconnect = false;
if (millis() - lastPublish >= 10000UL) {
Particle.publish("mytest", String(++count), PRIVATE, WITH_ACK);
lastPublish = millis();
}
}
// Detect a network dropout and reconnect quickly
if (!reconnect && !Ethernet.ready()) {
Log.info("Particle disconnect...");
Particle.disconnect();
waitFor(Particle.disconnected, 5000);
Log.info("Network disconnect...");
Network.disconnect();
Particle.connect();
reconnect = true;
}
}
Muon Ethernet configuration
The following code can be used to enable Ethernet on the Muon. This only needs to be done once and the device must be reset after configuration for the changes to take effect.
// Enable 3V3_AUX
SystemPowerConfiguration powerConfig = System.getPowerConfiguration();
powerConfig.auxiliaryPowerControlPin(D7).interruptPin(A7);
System.setPowerConfiguration(powerConfig);
// Enable Ethernet
if_wiznet_pin_remap remap = {};
remap.base.type = IF_WIZNET_DRIVER_SPECIFIC_PIN_REMAP;
System.enableFeature(FEATURE_ETHERNET_DETECTION);
remap.cs_pin = A3;
remap.reset_pin = PIN_INVALID;
remap.int_pin = A4;
auto ret = if_request(nullptr, IF_REQ_DRIVER_SPECIFIC, &remap, sizeof(remap), nullptr);
M.2 SoM Breakout board Ethernet configuration
The following code can be used to enable Ethernet on the M.2 SoM breakout board. This only needs to be done once and the device must be reset after configuration for the changes to take effect.
// Enable 3V3_AUX
SystemPowerConfiguration powerConfig = System.getPowerConfiguration();
powerConfig.auxiliaryPowerControlPin(D23).interruptPin(A6);
System.setPowerConfiguration(powerConfig);
// Enable Ethernet
if_wiznet_pin_remap remap = {};
remap.base.type = IF_WIZNET_DRIVER_SPECIFIC_PIN_REMAP;
System.enableFeature(FEATURE_ETHERNET_DETECTION);
remap.cs_pin = D5;
remap.reset_pin = PIN_INVALID;
remap.int_pin = PIN_INVALID;
auto ret = if_request(nullptr, IF_REQ_DRIVER_SPECIFIC, &remap, sizeof(remap), nullptr);