Description
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(ð_config, ð_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
Labels
Type
Projects
Status