diff --git a/Config.h b/Config.h index cf3b238..55d5653 100644 --- a/Config.h +++ b/Config.h @@ -1,6 +1,6 @@ #pragma once -#define NUKI_HUB_VERSION "8.2" +#define NUKI_HUB_VERSION "8.3" #define MQTT_QOS_LEVEL 1 #define MQTT_CLEAN_SESSIONS false \ No newline at end of file diff --git a/Network.cpp b/Network.cpp index 288fd02..88cdb94 100644 --- a/Network.cpp +++ b/Network.cpp @@ -29,6 +29,22 @@ Network::Network(Preferences *preferences, const String& maintenancePathPrefix) void Network::setupDevice() { + int hardwareDetect = _preferences->getInt(preference_network_hardware); + int hardwareDetectGpio = _preferences->getInt(preference_network_hardware_gpio); + + Log->print("Hardware detect : "); Log->println(hardwareDetect); + Log->print("Hardware detect GPIO: "); Log->println(hardwareDetectGpio); + + if(hardwareDetect == 0) + { + hardwareDetect = 2; + _preferences->putInt(preference_network_hardware, hardwareDetect); + } + if(hardwareDetectGpio == 0) + { + hardwareDetectGpio = 26; + _preferences->putInt(preference_network_hardware_gpio, hardwareDetectGpio); + } if(strcmp(WiFi_fallbackDetect, "wifi_fallback") == 0) { @@ -37,27 +53,30 @@ void Network::setupDevice() } else { - int hardwareDetect = _preferences->getInt(preference_network_hardware_detect); - - if(hardwareDetect == 0) + if(hardwareDetect == 1) { - hardwareDetect = 26; - _preferences->putInt(preference_network_hardware_detect, hardwareDetect); - } - - if(hardwareDetect == -1) - { - Log->println(F("W5500 hardware is disable, using Wifi.")); + Log->println(F("W5500 hardware is disabled, using Wifi.")); _networkDeviceType = NetworkDeviceType::WiFi; } + else if(hardwareDetect == 2) + { + Log->print(F("Using PIN ")); + Log->print(hardwareDetectGpio); + Log->println(F(" for network device selection")); + + pinMode(hardwareDetectGpio, INPUT_PULLUP); + _networkDeviceType = NetworkDeviceType::W5500; +// digitalRead(hardwareDetectGpio) == HIGH ? NetworkDeviceType::WiFi : NetworkDeviceType::W5500; + } + else if(hardwareDetect == 3) + { + Log->print(F("W5500 on M5Stack Atom POE")); + _networkDeviceType = NetworkDeviceType::W5500; + } else { - Log->print(F("Using PIN ")); - Log->print(hardwareDetect); - Log->println(F(" for network device selection")); - - pinMode(hardwareDetect, INPUT_PULLUP); - _networkDeviceType = digitalRead(hardwareDetect) == HIGH ? NetworkDeviceType::WiFi : NetworkDeviceType::W5500; + Log->println(F("Unknown hardware selected, falling back to Wifi.")); + _networkDeviceType = NetworkDeviceType::WiFi; } } @@ -65,7 +84,7 @@ void Network::setupDevice() { case NetworkDeviceType::W5500: Log->println(F("Network device: W5500")); - _device = new W5500Device(_hostname, _preferences); + _device = new W5500Device(_hostname, _preferences, hardwareDetect); break; case NetworkDeviceType::WiFi: Log->println(F("Network device: Builtin WiFi")); diff --git a/Pins.h b/Pins.h index 59a1d26..e29cf79 100644 --- a/Pins.h +++ b/Pins.h @@ -1,7 +1,5 @@ #pragma once -#define ETHERNET_CS_PIN 5 -#define ETHERNET_RESET_PIN 33 #define TRIGGER_LOCK_PIN 32 #define TRIGGER_UNLOCK_PIN 33 #define TRIGGER_UNLATCH_PIN 27 diff --git a/PreferencesKeys.h b/PreferencesKeys.h index bf06518..806bf44 100644 --- a/PreferencesKeys.h +++ b/PreferencesKeys.h @@ -16,7 +16,8 @@ #define preference_mqtt_crt "mqttcrt" #define preference_mqtt_key "mqttkey" #define preference_mqtt_hass_discovery "hassdiscovery" -#define preference_network_hardware_detect "nwhwdt" +#define preference_network_hardware "nwhw" +#define preference_network_hardware_gpio "nwhwdt" #define preference_rssi_publish_interval "rssipb" #define preference_hostname "hostname" #define preference_network_timeout "nettmout" diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index dfe5ed3..c6ba8d1 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -239,9 +239,14 @@ bool WebCfgServer::processArgs(String& message) _preferences->putString(preference_mqtt_key, value); configChanged = true; } + else if(key == "NWHW") + { + _preferences->putInt(preference_network_hardware, value.toInt()); + configChanged = true; + } else if(key == "NWHWDT") { - _preferences->putInt(preference_network_hardware_detect, value.toInt()); + _preferences->putInt(preference_network_hardware_gpio, value.toInt()); configChanged = true; } else if(key == "RSSI") @@ -607,7 +612,8 @@ void WebCfgServer::buildMqttConfigHtml(String &response) printTextarea(response, "MQTTCA", "MQTT SSL CA Certificate (*, optional)", _preferences->getString(preference_mqtt_ca).c_str(), TLS_CA_MAX_SIZE, _network->encryptionSupported()); printTextarea(response, "MQTTCRT", "MQTT SSL Client Certificate (*, optional)", _preferences->getString(preference_mqtt_crt).c_str(), TLS_CERT_MAX_SIZE, _network->encryptionSupported()); printTextarea(response, "MQTTKEY", "MQTT SSL Client Key (*, optional)", _preferences->getString(preference_mqtt_key).c_str(), TLS_KEY_MAX_SIZE, _network->encryptionSupported()); - printDropDown(response, "NWHWDT", "Network hardware detection", String(_preferences->getInt(preference_network_hardware_detect)), getNetworkDetectionOptions()); + printDropDown(response, "NWHW", "Network hardware", String(_preferences->getInt(preference_network_hardware)), getNetworkDetectionOptions()); + printDropDown(response, "NWHWDT", "Network hardware detection", String(_preferences->getInt(preference_network_hardware_gpio)), getNetworkGpioOptions()); printInputField(response, "RSSI", "RSSI Publish interval (seconds; -1 to disable)", _preferences->getInt(preference_rssi_publish_interval), 6); printInputField(response, "NETTIMEOUT", "Network Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5); printCheckBox(response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect)); @@ -956,7 +962,16 @@ const std::vector> WebCfgServer::getNetworkDetectionOp { std::vector> options; - options.push_back(std::make_pair("-1", "Disable W5500")); + options.push_back(std::make_pair("1", "Disable W5500 (Wifi only)")); + options.push_back(std::make_pair("2", "Detect W5500 (GPIO CS=5; SCK=18; MISO=19; MOSI=23; RST=33)")); + options.push_back(std::make_pair("3", "M5Stack Atom POE (W5500)")); + + return options; +} + +const std::vector> WebCfgServer::getNetworkGpioOptions() const +{ + std::vector> options; for(int i=16; i <= 33; i++) { @@ -966,4 +981,4 @@ const std::vector> WebCfgServer::getNetworkDetectionOp } return options; -} +} \ No newline at end of file diff --git a/WebCfgServer.h b/WebCfgServer.h index 4ca7693..cf1be2b 100644 --- a/WebCfgServer.h +++ b/WebCfgServer.h @@ -50,6 +50,7 @@ private: void buildNavigationButton(String& response, const char* caption, const char* targetPath); const std::vector> getNetworkDetectionOptions() const; + const std::vector> getNetworkGpioOptions() const; void printParameter(String& response, const char* description, const char* value); diff --git a/lib/Ethernet/src/Ethernet.cpp b/lib/Ethernet/src/Ethernet.cpp index 9257090..d502c13 100644 --- a/lib/Ethernet/src/Ethernet.cpp +++ b/lib/Ethernet/src/Ethernet.cpp @@ -100,9 +100,10 @@ void EthernetClass::begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress g _dnsServerAddress = dns; } -void EthernetClass::init(uint8_t sspin) +void EthernetClass::init(uint8_t sspin, uint8_t sckpin, uint8_t misopin, uint8_t mosipin) { W5100.setSS(sspin); + W5100.setSPI(sckpin, misopin, mosipin); } EthernetLinkStatus EthernetClass::linkStatus() diff --git a/lib/Ethernet/src/Ethernet.h b/lib/Ethernet/src/Ethernet.h index 0045de8..5a1e780 100644 --- a/lib/Ethernet/src/Ethernet.h +++ b/lib/Ethernet/src/Ethernet.h @@ -89,7 +89,7 @@ public: static void begin(uint8_t *mac, IPAddress ip, IPAddress dns); static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway); static void begin(uint8_t *mac, IPAddress ip, IPAddress dns, IPAddress gateway, IPAddress subnet); - static void init(uint8_t sspin = 10); + static void init(uint8_t sspin = 10, uint8_t sckpin = 255, uint8_t misopin = 255, uint8_t mosipin = 255); static void MACAddress(uint8_t *mac_address); static IPAddress localIP(); diff --git a/lib/Ethernet/src/utility/w5100.cpp b/lib/Ethernet/src/utility/w5100.cpp index 6e7dbd2..e7ec24d 100644 --- a/lib/Ethernet/src/utility/w5100.cpp +++ b/lib/Ethernet/src/utility/w5100.cpp @@ -53,6 +53,9 @@ uint8_t W5100Class::chip = 0; uint8_t W5100Class::CH_BASE_MSB; uint8_t W5100Class::ss_pin = SS_PIN_DEFAULT; +uint8_t W5100Class::sck_pin = 255; +uint8_t W5100Class::miso_pin = 255; +uint8_t W5100Class::mosi_pin = 255; #ifdef ETHERNET_LARGE_BUFFERS uint16_t W5100Class::SSIZE = 2048; uint16_t W5100Class::SMASK = 0x07FF; @@ -101,7 +104,11 @@ uint8_t W5100Class::init(void) delay(560); //Serial.println("w5100 init"); - SPI.begin(); + if(sck_pin != 255 && miso_pin != 255 && mosi_pin != 255) { + SPI.begin(sck_pin, miso_pin, mosi_pin, -1); + } else { + SPI.begin(); + } initSS(); resetSS(); SPI.beginTransaction(SPI_ETHERNET_SETTINGS); diff --git a/lib/Ethernet/src/utility/w5100.h b/lib/Ethernet/src/utility/w5100.h index b2e8ec8..210503a 100644 --- a/lib/Ethernet/src/utility/w5100.h +++ b/lib/Ethernet/src/utility/w5100.h @@ -298,6 +298,9 @@ public: private: static uint8_t chip; static uint8_t ss_pin; + static uint8_t sck_pin; + static uint8_t miso_pin; + static uint8_t mosi_pin; static uint8_t softReset(void); static uint8_t isW5100(void); static uint8_t isW5200(void); @@ -332,6 +335,11 @@ public: return false; } static void setSS(uint8_t pin) { ss_pin = pin; } + static void setSPI(uint8_t sckpin, uint8_t misopin, uint8_t mosipin) { + sck_pin = sckpin; + miso_pin = misopin; + mosi_pin = mosipin; + } private: #if defined(__AVR__) diff --git a/networkDevices/W5500Device.cpp b/networkDevices/W5500Device.cpp index 06afa8b..0822237 100644 --- a/networkDevices/W5500Device.cpp +++ b/networkDevices/W5500Device.cpp @@ -6,9 +6,10 @@ #include "../Logger.h" #include "../MqttTopics.h" -W5500Device::W5500Device(const String &hostname, Preferences* preferences) +W5500Device::W5500Device(const String &hostname, Preferences* preferences, int variant) : NetworkDevice(hostname), - _preferences(preferences) + _preferences(preferences), + _variant((W5500Variant)variant) { initializeMacAddress(_mac); @@ -37,7 +38,17 @@ void W5500Device::initialize() resetDevice(); - Ethernet.init(ETHERNET_CS_PIN); + switch(_variant) + { + case W5500Variant::M5StackAtomPoe: + _resetPin = -1; + Ethernet.init(19, 22, 23, 33); + break; + default: + _resetPin = -1; + Ethernet.init(5); + break; + } if(_preferences->getBool(preference_mqtt_log_enabled)) { @@ -123,13 +134,15 @@ void W5500Device::reconfigure() void W5500Device::resetDevice() { + if(_resetPin == -1) return; + Log->println(F("Resetting network hardware.")); - pinMode(ETHERNET_RESET_PIN, OUTPUT); - digitalWrite(ETHERNET_RESET_PIN, HIGH); + pinMode(_resetPin, OUTPUT); + digitalWrite(_resetPin, HIGH); delay(250); - digitalWrite(ETHERNET_RESET_PIN, LOW); + digitalWrite(_resetPin, LOW); delay(50); - digitalWrite(ETHERNET_RESET_PIN, HIGH); + digitalWrite(_resetPin, HIGH); delay(1500); } diff --git a/networkDevices/W5500Device.h b/networkDevices/W5500Device.h index 953a6ed..a86fb06 100644 --- a/networkDevices/W5500Device.h +++ b/networkDevices/W5500Device.h @@ -6,10 +6,16 @@ #include #include +enum class W5500Variant +{ + Generic = 2, + M5StackAtomPoe = 3 +}; + class W5500Device : public NetworkDevice { public: - explicit W5500Device(const String& hostname, Preferences* _preferences); + explicit W5500Device(const String& hostname, Preferences* _preferences, int variant); ~W5500Device(); virtual void initialize(); @@ -59,8 +65,10 @@ private: Preferences* _preferences = nullptr; int _maintainResult = 0; + int _resetPin = -1; bool _hasDHCPAddress = false; char* _path; + W5500Variant _variant; byte _mac[6]; }; \ No newline at end of file