Fix POE boot failure on RAK4631 Ethernet builds

Drive WB_IO2 (slot power switch) HIGH via early constructor before the
Arduino framework initializes. Without this, the board brownouts on
POE-only power because the slot MOSFET isn't enabled early enough for
the RAK13800 POE module to deliver power to the baseboard.

Also remove the W5100S hardware reset pulse from Ethernet init — the
chip comes out of power-on reset cleanly, and toggling reset kills
the PHY link which breaks POE power delivery.
This commit is contained in:
Ryan Gregg 2026-03-20 17:56:04 -07:00
parent eba2446747
commit 3c1a0941aa
3 changed files with 22 additions and 18 deletions

View file

@ -36,13 +36,11 @@ static void ethernet_task(void* param) {
(void)param;
Serial.println("ETH: Initializing hardware");
pinMode(PIN_ETHERNET_POWER_EN, OUTPUT);
digitalWrite(PIN_ETHERNET_POWER_EN, HIGH);
vTaskDelay(pdMS_TO_TICKS(100));
// WB_IO2 (power enable) is already driven HIGH by early constructor
// in RAK4631Board.cpp to support POE boot.
// Skip hardware reset — the W5100S comes out of power-on reset cleanly,
// and toggling reset kills the PHY link which breaks POE power.
pinMode(PIN_ETHERNET_RESET, OUTPUT);
digitalWrite(PIN_ETHERNET_RESET, LOW);
vTaskDelay(pdMS_TO_TICKS(100));
digitalWrite(PIN_ETHERNET_RESET, HIGH);
ETHERNET_SPI_PORT.begin();

View file

@ -22,20 +22,13 @@ bool SerialEthernetInterface::begin() {
ETHERNET_DEBUG_PRINTLN("Ethernet initializing");
#ifdef PIN_ETHERNET_POWER_EN
ETHERNET_DEBUG_PRINTLN("Ethernet power enable");
pinMode(PIN_ETHERNET_POWER_EN, OUTPUT);
digitalWrite(PIN_ETHERNET_POWER_EN, HIGH); // Power up.
delay(100);
ETHERNET_DEBUG_PRINTLN("Ethernet power enabled");
#endif
// WB_IO2 (power enable) is already driven HIGH by early constructor
// in RAK4631Board.cpp to support POE boot.
// Skip hardware reset — the W5100S comes out of power-on reset cleanly,
// and toggling reset kills the PHY link which breaks POE power.
#ifdef PIN_ETHERNET_RESET
pinMode(PIN_ETHERNET_RESET, OUTPUT);
digitalWrite(PIN_ETHERNET_RESET, LOW); // Reset Time.
delay(100);
digitalWrite(PIN_ETHERNET_RESET, HIGH); // Reset Time.
ETHERNET_DEBUG_PRINTLN("Ethernet reset pulse");
digitalWrite(PIN_ETHERNET_RESET, HIGH);
#endif
uint8_t mac[6];

View file

@ -1,8 +1,21 @@
#include <Arduino.h>
#include <Wire.h>
#include "nrf_gpio.h"
#include "RAK4631Board.h"
#ifdef ETHERNET_ENABLED
// Drive WB_IO2 HIGH as early as possible using direct register access.
// WB_IO2 (P1.02, Arduino pin 34) controls the WisBlock slot power switch.
// With POE through RAK13800, this must be enabled before the framework
// initializes or the board will brownout from insufficient power delivery.
// Priority 102 runs just after SystemInit.
static void __attribute__((constructor(102))) rak4631_early_poe_power() {
nrf_gpio_cfg_output(NRF_GPIO_PIN_MAP(1, 2)); // WB_IO2 = P1.02
nrf_gpio_pin_set(NRF_GPIO_PIN_MAP(1, 2));
}
#endif
#ifdef NRF52_POWER_MANAGEMENT
// Static configuration for power management
// Values set in variant.h defines