Skip to content

ESP32 v2.0.0-rc1 - Using W5500 driver from ESP-IDF and other devices via SPI.h at the same bus #5482

Closed
@swbew

Description

@swbew

Description:

Hey Guys,

I'm trying to implement the esp-idf W5500 driver with lwip using 'direct access' to esp-idf in arduino-esp32. With ESP-IDF 4.4 comes the possibility to use SPI-Ethernet chips in lwip. Additionally I want to use a RC522 RFID-Reader, which is connected to the same SPI bus. For this I want to use the MFRC522 (Arduino) library from here: https://github.com/miguelbalboa/rfid via SPI.h library.

I took the example code from the ESP-IDF to initialize the W5500 from here:
https://github.com/espressif/esp-idf/blob/master/examples/ethernet/basic/main/ethernet_example_main.c

Using the W5500 as single device on the SPI bus, works like a charm. But as soon as I access my RC522 RFID reader via SPI.h, the ESP crashes after a few seconds (see test sketch below) with the following Serial output:

assertion "spi_ll_get_running_cmd(hw) == 0" failed: file "IDF/components/hal/spi_hal_iram.c", line 68, function: spi_hal_setup_trans

abort() was called at PC 0x4016eb0b on core 0

Decoded backtrace:

Decoding stack results
0x400ec91d: panic_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/panic.c line 402
0x4008ca2d: esp_system_abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_system/esp_system.c line 128
0x40092b51: abort at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/newlib/abort.c line 46
0x4016eb0b: __assert_func at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp32-elf/src/newlib/newlib/libc/stdlib/assert.c line 62
0x40090df1: spi_hal_setup_trans at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/hal/esp32/include/hal/spi_ll.h line 153
0x4008439d: spi_new_trans at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/driver/spi_master.c line 558
0x4008458b: spi_device_polling_start at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/driver/spi_master.c line 938
0x4008466c: spi_device_polling_transmit at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/driver/spi_master.c line 977
0x400ef758: w5500_read at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_eth/src/esp_eth_mac_w5500.c line 96
0x400f0294: emac_w5500_transmit at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_eth/src/esp_eth_mac_w5500.c line 136
0x400ef185: esp_eth_transmit at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_eth/src/esp_eth.c line 328
0x401879af: esp_netif_transmit at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/esp_netif/lwip/esp_netif_lwip.c line 877
0x40109fe9: ethernet_low_level_output at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/port/esp32/netif/ethernetif.c line 118
0x401076e5: ethernet_output at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/netif/ethernet.c line 312
0x40102212: etharp_output_to_arp_index at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/ipv4/etharp.c line 785
0x401027a5: etharp_output at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/ipv4/etharp.c line 884
0x4010376d: ip4_output_if_opt_src at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/ipv4/ip4.c line 1089
0x401037e1: ip4_output_if at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/ipv4/ip4.c line 890
0x401029eb: icmp_input at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/ipv4/icmp.c line 250
0x40103447: ip4_input at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/core/ipv4/ip4.c line 790
0x40107641: ethernet_input at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/netif/ethernet.c line 186
0x400f7c7d: tcpip_thread at /Users/ficeto/Desktop/ESP32/ESP32S2/esp-idf-public/components/lwip/lwip/src/api/tcpip.c line 180

How can I get Ethernet working with the W5500 board via ESP-IDF while also using SPI.h from arduino-esp32 for RC522 (MFRC522) as a second SPI device on the same bus?
Is it planned to support SPI-Ethernet chips in ETH.h with the final release of arduino-esp32 v2.0.0?

Hardware/Environment:

Board WeMos D1 Mini 32
Version/Date arduino-esp32 v2.0.0 RC1
IDE name VSCode + PlatformIO
Flash Frequency 40Mhz
PSRAM enabled no
Upload Speed 115200
Computer OS Windows 10 20H2

Pins used for SPI:

MOSI: 23
MISO: 19
SCK: 18
SS_RFID: 5
SS_W5500: 15
INT_W5500: 25

Sketch:

#include <Arduino.h>
#include <WiFi.h>
#include <ETH.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "driver/spi_master.h"
#include <SPI.h>
#include <MFRC522.h>

MFRC522 mfrc522 = MFRC522();
AsyncWebServer server(80);

const char* PARAM_MESSAGE = "message";
unsigned long rfidCooldown;

void notFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

bool setupW5500() {
  WiFi.begin();
  tcpip_adapter_set_default_eth_handlers();

  // Initialize TCP/IP network interface (should be called only once in application)
  ESP_ERROR_CHECK(esp_netif_init());
  esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
  esp_netif_t *eth_netif = esp_netif_new(&cfg);
  // Set default handlers to process TCP/IP stuffs
  ESP_ERROR_CHECK(esp_eth_set_default_handlers(eth_netif));
    
  esp_eth_mac_t *eth_mac = NULL;
  esp_eth_phy_t *eth_phy = NULL;

  gpio_install_isr_service(0);

  spi_bus_config_t buscfg = {
    .mosi_io_num = 23,
    .miso_io_num = 19,
    .sclk_io_num = 18,
    .quadwp_io_num = -1,
    .quadhd_io_num = -1,
  };
  ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, 1));

  spi_device_handle_t spi_handle = NULL;
  spi_device_interface_config_t devcfg = {
      .command_bits = 16, // Actually it's the address phase in W5500 SPI frame
      .address_bits = 8,  // Actually it's the control phase in W5500 SPI frame
      .mode = 0,
      .clock_speed_hz = 12 * 1000 * 1000,
      .spics_io_num = 15,
      .queue_size = 20
  };
  ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &devcfg, &spi_handle));
  /* w5500 ethernet driver is based on spi driver */
  eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(spi_handle);
  w5500_config.int_gpio_num = 25;

  eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  phy_config.reset_gpio_num = -1;

  eth_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config);
  if(eth_mac == NULL){
      log_e("esp_eth_mac_new_esp32 failed");
      return false;
  }

  eth_phy = esp_eth_phy_new_w5500(&phy_config);
  if(eth_phy == NULL){
      log_e("esp_eth_phy_new failed");
      return false;
  }
    
  esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(eth_mac, eth_phy);
  esp_eth_handle_t eth_handle = NULL;
  ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config, &eth_handle));

  uint8_t macArr[] = { 0x02, 0x00, 0x00, 0x12, 0x34, 0x56 };
  ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, macArr));

  /* attach Ethernet driver to TCP/IP stack */
  ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handle)));
  /* start Ethernet driver state machine */
  ESP_ERROR_CHECK(esp_eth_start(eth_handle));

return true;
}

void setupRFID(){
  SPI.begin();
  mfrc522.PCD_SetAntennaGain(112);
  delay(50);
  mfrc522.PCD_Init(5, 0);
  delay(50);
  Serial.printf("[ INFO ] RFID SS_PIN: %u and Gain Factor: %u", 5, 112);
  Serial.println("");
  delay(50);
}

void setupWebserver() {
      server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(200, "text/plain", "Hello, world");
    });

    // Send a GET request to <IP>/get?message=<message>
    server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
        String message;
        if (request->hasParam(PARAM_MESSAGE)) {
            message = request->getParam(PARAM_MESSAGE)->value();
        } else {
            message = "No message sent";
        }
        request->send(200, "text/plain", "Hello, GET: " + message);
    });

    // Send a POST request to <IP>/post with a form field message set to <message>
    server.on("/post", HTTP_POST, [](AsyncWebServerRequest *request){
        String message;
        if (request->hasParam(PARAM_MESSAGE, true)) {
            message = request->getParam(PARAM_MESSAGE, true)->value();
        } else {
            message = "No message sent";
        }
        request->send(200, "text/plain", "Hello, POST: " + message);
    });

    server.onNotFound(notFound);
    server.begin();

    Serial.print("IP Address: ");
    Serial.println(ETH.localIP());
}

bool rfidloop() {
  mfrc522.PCD_Init();
  delay(50);

  if (! mfrc522.PICC_IsNewCardPresent()) {
    delay(50);
    return false;
  }
  if (! mfrc522.PICC_ReadCardSerial()) {
    delay(50);
    return false;
  }
  
  rfidCooldown = millis() + 2000;
  Serial.println("[ RFID ] Card detected to read!");
  mfrc522.PICC_HaltA();
   
  Serial.print(F("[ INFO ] PICC's UID: "));
  String uid = "";
  for (int i = 0; i < mfrc522.uid.size; ++i) {
    uid += String(mfrc522.uid.uidByte[i], HEX);
  }
  Serial.println(uid);
  return true;
}

void setup() {
    Serial.begin(9600);
    setupRFID();  //comment this line to get Ethernet working
    
    setupW5500();    //comment this line to get RFID working
    setupWebserver(); //comment this line to get RFID working
}

void loop() {
  if (rfidCooldown < millis()) {
    rfidloop();
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions