From 06a353cfa09e0e9b6c5c566dbf508e53309595e9 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 25 Aug 2024 16:29:59 +0100 Subject: [PATCH 1/3] stm32 merge (mdns disabled} --- EthernetInterface.cpp | 164 ++++++++++++++++++++++++++++-------------- EthernetInterface.h | 2 +- platformio.ini | 26 +++++++ 3 files changed, 136 insertions(+), 56 deletions(-) diff --git a/EthernetInterface.cpp b/EthernetInterface.cpp index 6b201c1..6943f03 100644 --- a/EthernetInterface.cpp +++ b/EthernetInterface.cpp @@ -29,8 +29,15 @@ #include "CommandDistributor.h" #include "WiThrottle.h" #include "DCCTimer.h" +#if __has_include ( "MDNS_Generic.h") + #include "MDNS_Generic.h" + // #define DO_MDNS !!!!!!!!!!!!! breaks mega + EthernetUDP udp; + MDNS mdns(udp); +#endif -extern void looptimer(unsigned long timeout, const FSH* message); + +//extern void looptimer(unsigned long timeout, const FSH* message); bool EthernetInterface::connected=false; EthernetServer * EthernetInterface::server= nullptr; @@ -42,48 +49,73 @@ RingStream * EthernetInterface::outboundRing = nullptr; * @brief Setup Ethernet Connection * */ -void EthernetInterface::setup() -{ - connected=false; +void EthernetInterface::setup() // STM32 VERSION +{ + DIAG(F("Ethernet begin")); + + #ifdef STM32_ETHERNET + // Set a HOSTNAME for the DHCP request - a nice to have, but hard it seems on LWIP for STM32 + // The default is "lwip", which is **always** set in STM32Ethernet/src/utility/ethernetif.cpp + // for some reason. One can edit it to instead read: + // #if LWIP_NETIF_HOSTNAME + // /* Initialize interface hostname */ + // if (netif->hostname == NULL) + // netif->hostname = "lwip"; + // #endif /* LWIP_NETIF_HOSTNAME */ + // Which seems more useful! We should propose the patch... so the following line actually works! + netif_set_hostname(&gnetif, WIFI_HOSTNAME); // Should probably be passed in the contructor... + #define _MAC_ MacAddressDefault() + #else byte mac[6]; DCCTimer::getSimulatedMacAddress(mac); - DIAG(F("Ethernet begin")); - -#ifdef IP_ADDRESS + #define _MAC_ mac + #endif + + #ifdef IP_ADDRESS static IPAddress myIP(IP_ADDRESS); - Ethernet.begin(mac, myIP); -#else - if (Ethernet.begin(mac) == 0) - { - LCD(4,F("IP: No DHCP")); - return; - } -#endif - auto ip = Ethernet.localIP(); // look what IP was obtained (dynamic or static) - if (!ip) { - LCD(4,F("IP: None")); - return; - } - server = new EthernetServer(IP_PORT); // Ethernet Server listening on default port IP_PORT - server->begin(); - #ifdef LCD_DRIVER - const byte lcdData[]={LCD_DRIVER}; - const bool wideDisplay=lcdData[1]>=24; // data[1] is cols. - #else - const bool wideDisplay=true; - #endif - if (wideDisplay) { - // OLEDS or just usb diag is ok on one line. - LCD(4,F("IP %d.%d.%d.%d:%d"), ip[0], ip[1], ip[2], ip[3], IP_PORT); - } - else { // LCDs generally too narrow, so take 2 lines - LCD(4,F("IP %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); - LCD(5,F("Port %d"), IP_PORT); - } + Ethernet.begin(_MAC_,myIP); + setup(false); + #else + if (Ethernet.begin(_MAC_)==0) + { + LCD(4,F("IP: No DHCP")); + return; + } + #endif + + auto ip = Ethernet.localIP(); // look what IP was obtained (dynamic or static) + if (!ip) { + LCD(4,F("IP: None")); + return; + } + server = new EthernetServer(IP_PORT); // Ethernet Server listening on default port IP_PORT + server->begin(); + + // Arrange display of IP address and port + #ifdef LCD_DRIVER + const byte lcdData[]={LCD_DRIVER}; + const bool wideDisplay=lcdData[1]>=24; // data[1] is cols. + #else + const bool wideDisplay=true; + #endif + if (wideDisplay) { + // OLEDS or just usb diag is ok on one line. + LCD(4,F("IP %d.%d.%d.%d:%d"), ip[0], ip[1], ip[2], ip[3], IP_PORT); + } + else { // LCDs generally too narrow, so take 2 lines + LCD(4,F("IP %d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); + LCD(5,F("Port %d"), IP_PORT); + } - outboundRing=new RingStream(OUTBOUND_RING_SIZE); - connected=true; + outboundRing=new RingStream(OUTBOUND_RING_SIZE); + #ifdef DO_MDNS + mdns.begin(Ethernet.localIP(), WIFI_HOSTNAME); // hostname + mdns.addServiceRecord(WIFI_HOSTNAME "._withrottle", IP_PORT, MDNSServiceTCP); + // Not sure if we need to run it once, but just in case! + mdns.run(); + #endif + connected=true; } @@ -109,6 +141,11 @@ void EthernetInterface::loop() warnedAboutLink=false; } + #ifdef DO_MDNS + // Always do this because we don't want traffic to intefere with being found! + mdns.run(); + #endif + // switch (Ethernet.maintain()) { case 1: @@ -127,27 +164,44 @@ void EthernetInterface::loop() break; } - // get client from the server - auto client = server->accept(); - - // check for new client - if (client) - { - if (Diag::ETHERNET) DIAG(F("Ethernet: New client ")); - byte socket; + // get client from the server + #if defined (STM32_ETHERNET) + // STM32Ethernet doesn't use accept(), just available() + auto client = server->available(); + if (client) { + // check for new client + byte socket; + bool sockfound = false; + for (socket = 0; socket < MAX_SOCK_NUM; socket++) + { + if (client == clients[socket]) + { + sockfound = true; + break; + } + } + if (!sockfound) + { // new client for (socket = 0; socket < MAX_SOCK_NUM; socket++) { - if (!clients[socket]) - { - // On accept() the EthernetServer doesn't track the client anymore - // so we store it in our client array - if (Diag::ETHERNET) DIAG(F("Socket %d"),socket); - clients[socket] = client; - break; - } + if (!clients[socket]) + { + clients[socket] = client; + sockFound=true; + if (Diag::ETHERNET) + DIAG(F("Ethernet: New client socket %d"), socket); + break; + } } - if (socket==MAX_SOCK_NUM) DIAG(F("new Ethernet OVERFLOW")); + } + if (!sockFound) DIAG(F("new Ethernet OVERFLOW")); } + + #else + auto client = server->accept(); + if (client) clients[client.getSocketNumber()]=client; + #endif + // check for incoming data from all possible clients for (byte socket = 0; socket < MAX_SOCK_NUM; socket++) diff --git a/EthernetInterface.h b/EthernetInterface.h index e03d79b..8440dde 100644 --- a/EthernetInterface.h +++ b/EthernetInterface.h @@ -45,7 +45,7 @@ * */ -#define MAX_ETH_BUFFER 512 +#define MAX_ETH_BUFFER 128 #define OUTBOUND_RING_SIZE 2048 class EthernetInterface { diff --git a/platformio.ini b/platformio.ini index b39b136..6985327 100644 --- a/platformio.ini +++ b/platformio.ini @@ -104,6 +104,14 @@ lib_deps = ${env.lib_deps} arduino-libraries/Ethernet SPI + MDNS_Generic + +lib_ignore = WiFi101 + WiFi101_Generic + WiFiEspAT + WiFiMulti_Generic + WiFiNINA_Generic + monitor_speed = 115200 monitor_echo = yes build_flags = @@ -246,6 +254,24 @@ monitor_echo = yes ; Experimental - Ethernet work still in progress ; +[env:Nucleo-F429ZI] +platform = ststm32 +board = nucleo_f429zi +framework = arduino +lib_deps = ${env.lib_deps} + stm32duino/STM32Ethernet @ ^1.3.0 + stm32duino/STM32duino LwIP @ ^2.1.2 + MDNS_Generic +lib_ignore = WiFi101 + WiFi101_Generic + WiFiEspAT + WiFiMulti_Generic + WiFiNINA_Generic +build_flags = -std=c++17 -Os -g2 -Wunused-variable +monitor_speed = 115200 +monitor_echo = yes +upload_protocol = stlink + ; [env:Nucleo-F429ZI] ; platform = ststm32 ; board = nucleo_f429zi From 4ed2ee9adc9e9921e6ea883a45293ba2159a4bbc Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 25 Aug 2024 16:50:49 +0100 Subject: [PATCH 2/3] mDNS restored on mega --- EthernetInterface.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/EthernetInterface.cpp b/EthernetInterface.cpp index 6943f03..bea4162 100644 --- a/EthernetInterface.cpp +++ b/EthernetInterface.cpp @@ -31,13 +31,13 @@ #include "DCCTimer.h" #if __has_include ( "MDNS_Generic.h") #include "MDNS_Generic.h" - // #define DO_MDNS !!!!!!!!!!!!! breaks mega + #define DO_MDNS EthernetUDP udp; MDNS mdns(udp); #endif -//extern void looptimer(unsigned long timeout, const FSH* message); +extern void looptimer(unsigned long timeout, const FSH* message); bool EthernetInterface::connected=false; EthernetServer * EthernetInterface::server= nullptr; @@ -52,7 +52,11 @@ RingStream * EthernetInterface::outboundRing = nullptr; void EthernetInterface::setup() // STM32 VERSION { - DIAG(F("Ethernet begin")); + DIAG(F("Ethernet begin" + #ifdef DO_MDNS + " with mDNS" + #endif + )); #ifdef STM32_ETHERNET // Set a HOSTNAME for the DHCP request - a nice to have, but hard it seems on LWIP for STM32 @@ -126,7 +130,8 @@ void EthernetInterface::setup() // STM32 VERSION void EthernetInterface::loop() { if (!connected) return; - + looptimer(5000, F("E.loop")); + static bool warnedAboutLink=false; if (Ethernet.linkStatus() == LinkOFF){ if (warnedAboutLink) return; @@ -134,7 +139,8 @@ void EthernetInterface::loop() warnedAboutLink=true; return; } - + looptimer(5000, F("E.loop warn")); + // link status must be ok here if (warnedAboutLink) { DIAG(F("Ethernet link RESTORED")); @@ -144,6 +150,8 @@ void EthernetInterface::loop() #ifdef DO_MDNS // Always do this because we don't want traffic to intefere with being found! mdns.run(); + looptimer(5000, F("E.mdns")); + #endif // @@ -163,7 +171,8 @@ void EthernetInterface::loop() //DIAG(F("maintained")); break; } - + looptimer(5000, F("E.maintain")); + // get client from the server #if defined (STM32_ETHERNET) // STM32Ethernet doesn't use accept(), just available() From 30236f9b36629544febe02ef9723075b2d6d7046 Mon Sep 17 00:00:00 2001 From: pmantoine Date: Fri, 30 Aug 2024 11:52:27 +0800 Subject: [PATCH 3/3] STM32 Ethernet fixed --- EthernetInterface.cpp | 11 +++++------ EthernetInterface.h | 8 ++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/EthernetInterface.cpp b/EthernetInterface.cpp index bea4162..8e84569 100644 --- a/EthernetInterface.cpp +++ b/EthernetInterface.cpp @@ -69,12 +69,11 @@ void EthernetInterface::setup() // STM32 VERSION // #endif /* LWIP_NETIF_HOSTNAME */ // Which seems more useful! We should propose the patch... so the following line actually works! netif_set_hostname(&gnetif, WIFI_HOSTNAME); // Should probably be passed in the contructor... - #define _MAC_ MacAddressDefault() - #else +#endif + byte mac[6]; DCCTimer::getSimulatedMacAddress(mac); #define _MAC_ mac - #endif #ifdef IP_ADDRESS static IPAddress myIP(IP_ADDRESS); @@ -180,16 +179,16 @@ void EthernetInterface::loop() if (client) { // check for new client byte socket; - bool sockfound = false; + bool sockFound = false; for (socket = 0; socket < MAX_SOCK_NUM; socket++) { if (client == clients[socket]) { - sockfound = true; + sockFound = true; break; } } - if (!sockfound) + if (!sockFound) { // new client for (socket = 0; socket < MAX_SOCK_NUM; socket++) { diff --git a/EthernetInterface.h b/EthernetInterface.h index 8440dde..9ea2718 100644 --- a/EthernetInterface.h +++ b/EthernetInterface.h @@ -35,6 +35,14 @@ #if defined (ARDUINO_TEENSY41) #include //TEENSY Ethernet Treiber #include +#elif defined (ARDUINO_NUCLEO_F429ZI) || defined (ARDUINO_NUCLEO_F439ZI) || defined (ARDUINO_NUCLEO_F4X9ZI) + #include +// #include "STM32lwipopts.h" + #include + #include + extern "C" struct netif gnetif; + #define STM32_ETHERNET + #define MAX_SOCK_NUM 8 #else #include "Ethernet.h" #endif