From eaf1b9452bef48f22e1b9b5e7efd607e3a1a23fc Mon Sep 17 00:00:00 2001 From: tekka Date: Sat, 7 Apr 2018 14:46:01 +0200 Subject: [PATCH] ESP32: Support HW (#865) This fixes https://github.com/mysensors/MySensors/issues/968 --- .ci/arduino.groovy | 66 ++++++- .ci/pipeline.groovy | 10 +- MyConfig.h | 19 +- MySensors.h | 10 +- core/MyCapabilities.h | 2 + core/MyGatewayTransportEthernet.cpp | 44 +++-- core/MyGatewayTransportMQTTClient.cpp | 24 ++- core/MySensorsCore.cpp | 1 + core/MySigningAtsha204Soft.cpp | 2 +- core/MyTransport.cpp | 2 +- drivers/AES/AES_config.h | 2 + drivers/RF24/RF24.h | 2 +- drivers/RFM69/new/RFM69_new.h | 3 +- drivers/RFM69/old/RFM69_old.h | 3 +- drivers/RFM95/RFM95.cpp | 1 - drivers/RFM95/RFM95.h | 3 +- examples/GatewayESP32/GatewayESP32.ino | 76 ++++++++ .../GatewayESP32MQTTClient.ino | 90 ++++++++++ hal/architecture/ESP32/MyHwESP32.cpp | 168 ++++++++++++++++++ hal/architecture/ESP32/MyHwESP32.h | 89 ++++++++++ hal/architecture/ESP32/MyMainESP32.cpp | 49 +++++ keywords.txt | 7 + 22 files changed, 643 insertions(+), 30 deletions(-) create mode 100644 examples/GatewayESP32/GatewayESP32.ino create mode 100644 examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino create mode 100644 hal/architecture/ESP32/MyHwESP32.cpp create mode 100644 hal/architecture/ESP32/MyHwESP32.h create mode 100644 hal/architecture/ESP32/MyMainESP32.cpp diff --git a/.ci/arduino.groovy b/.ci/arduino.groovy index ce51237..da74a5d 100644 --- a/.ci/arduino.groovy +++ b/.ci/arduino.groovy @@ -26,7 +26,9 @@ def parseWarnings(String key) { excludePattern: '''.*/EEPROM\\.h,.*/Dns\\.cpp,.*/socket\\.cpp,.*/util\\.h,.*/Servo\\.cpp, .*/Adafruit_NeoPixel\\.cpp,.*/UIPEthernet.*,.*/SoftwareSerial\\.cpp, .*/pins_arduino\\.h,.*/Stream\\.cpp,.*/USBCore\\.cpp,.*/Wire\\.cpp, - .*/hardware/STM32F1.*,.*/hardware/esp8266.*,.*/libraries/SD/.*''', + .*/hardware/STM32F1.*,.*/hardware/esp8266.*,.*/hardware/espressif/esp32.*, + .*/libraries/SD/.*''', + healthy: '', includePattern: '', messagesPattern: '', parserConfigurations: [[parserName: 'Arduino/AVR', pattern: 'compiler_'+key+'.log']], unHealthy: '', unstableNewAll: '0', unstableTotalAll: '0' @@ -47,6 +49,8 @@ def buildMySensorsMicro(config, sketches, String key) { sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && sketches[sketch].path != config.library_root+'examples/GatewayGSMMQTTClient/GatewayGSMMQTTClient.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino') { buildArduino(config, fqbn, sketches[sketch].path, key+'_MySensorsMicro') } @@ -80,6 +84,8 @@ def buildMySensorsGw(config, sketches, String key) { sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && sketches[sketch].path != config.library_root+'examples/GatewayGSMMQTTClient/GatewayGSMMQTTClient.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewaySerialRS485/GatewaySerialRS485.ino' && sketches[sketch].path != config.library_root+'examples/MotionSensorRS485/MotionSensorRS485.ino') { buildArduino(config, fqbn, sketches[sketch].path, key+'_MySensorsGw') @@ -112,6 +118,8 @@ def buildArduinoUno(config, sketches, String key) { if (sketches[sketch].path != config.library_root+'examples/GatewayESP8266/GatewayESP8266.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino') { buildArduino(config, fqbn, sketches[sketch].path, key+'_ArduinoUno') } @@ -143,6 +151,8 @@ def buildArduinoMega(config, sketches, String key) { if (sketches[sketch].path != config.library_root+'examples/GatewayESP8266/GatewayESP8266.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino') { buildArduino(config, fqbn, sketches[sketch].path, key+'_ArduinoMega') } @@ -174,6 +184,8 @@ def buildSTM32F1(config, sketches, String key) { if (sketches[sketch].path != config.library_root+'examples/GatewayESP8266/GatewayESP8266.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino') { buildArduino(config, fqbn, sketches[sketch].path, key+'_STM32F1') } @@ -209,6 +221,8 @@ def buildEsp8266(config, sketches, String key) { sketches[sketch].path != config.library_root+'examples/GatewayW5100/GatewayW5100.ino' && sketches[sketch].path != config.library_root+'examples/GatewayW5100MQTTClient/GatewayW5100MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayGSMMQTTClient/GatewayGSMMQTTClient.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/MotionSensorRS485/MotionSensorRS485.ino' && sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino' && sketches[sketch].path != config.library_root+'examples/SoilMoistSensor/SoilMoistSensor.ino') { @@ -234,6 +248,54 @@ def buildEsp8266(config, sketches, String key) { } } +def buildEsp32(config, sketches, String key) { + def fqbn = '-fqbn espressif:esp32:node32s -warnings=default -prefs build.f_cpu=80000000 -prefs build.mcu=esp32' + config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (ESP32 - '+key+')', 'Building...', '${BUILD_URL}flowGraphTable/') + try { + for (sketch = 0; sketch < sketches.size(); sketch++) { + if (sketches[sketch].path != config.library_root+'examples/BatteryPoweredSensor/BatteryPoweredSensor.ino' && + sketches[sketch].path != config.library_root+'examples/BinarySwitchSleepSensor/BinarySwitchSleepSensor.ino' && + sketches[sketch].path != config.library_root+'examples/CO2Sensor/CO2Sensor.ino' && + sketches[sketch].path != config.library_root+'examples/DustSensor/DustSensor.ino' && + sketches[sketch].path != config.library_root+'examples/DustSensorDSM/DustSensorDSM.ino' && + sketches[sketch].path != config.library_root+'examples/EnergyMeterPulseSensor/EnergyMeterPulseSensor.ino' && + sketches[sketch].path != config.library_root+'examples/LightSensor/LightSensor.ino' && + sketches[sketch].path != config.library_root+'examples/LogOTANode/LogOTANode.ino' && + sketches[sketch].path != config.library_root+'examples/MotionSensor/MotionSensor.ino' && + sketches[sketch].path != config.library_root+'examples/MotionSensorRS485/MotionSensorRS485.ino' && + sketches[sketch].path != config.library_root+'examples/PassiveNode/PassiveNode.ino' && + sketches[sketch].path != config.library_root+'examples/GatewaySerialRS485/GatewaySerialRS485.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayW5100/GatewayW5100.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayW5100MQTTClient/GatewayW5100MQTTClient.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayGSMMQTTClient/GatewayGSMMQTTClient.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP8266/GatewayESP8266.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && + sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino' && + sketches[sketch].path != config.library_root+'examples/MotionSensorRS485/MotionSensorRS485.ino' && + sketches[sketch].path != config.library_root+'examples/SoilMoistSensor/SoilMoistSensor.ino') { + buildArduino(config, '-prefs build.flash_freq=80m -prefs build.flash_size=4MB '+fqbn, sketches[sketch].path, key+'_Esp32') + } + } + } catch (ex) { + echo "Build failed with: "+ ex.toString() + config.pr.setBuildStatus(config, 'FAILURE', 'Toll gate (ESP32 - '+key+')', 'Build error', '${BUILD_URL}') + throw ex + } finally { + parseWarnings(key+'_Esp32') + } + if (currentBuild.currentResult == 'UNSTABLE') { + config.pr.setBuildStatus(config, 'ERROR', 'Toll gate (ESP32 - '+key+')', 'Warnings found', '${BUILD_URL}warnings2Result/new') + if (config.is_pull_request) { + error 'Termiated due to warnings found' + } + } else if (currentBuild.currentResult == 'FAILURE') { + config.pr.setBuildStatus(config, 'FAILURE', 'Toll gate (ESP32 - '+key+')', 'Build error', '${BUILD_URL}') + } else { + config.pr.setBuildStatus(config, 'SUCCESS', 'Toll gate (ESP32 - '+key+')', 'Pass', '') + } +} + def buildnRF5(config, sketches, String key) { def fqbn = '-fqbn sandeepmistry:nRF5:Generic_nRF52832 -prefs build.f_cpu=16000000 -prefs build.mcu=cortex-m4' config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (nRF5 - '+key+')', 'Building...', '${BUILD_URL}flowGraphTable/') @@ -246,6 +308,8 @@ def buildnRF5(config, sketches, String key) { sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayGSMMQTTClient/GatewayGSMMQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' && + sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' && sketches[sketch].path != config.library_root+'examples/GatewaySerialRS485/GatewaySerialRS485.ino' && sketches[sketch].path != config.library_root+'examples/GatewayW5100/GatewayW5100.ino' && sketches[sketch].path != config.library_root+'examples/GatewayW5100MQTTClient/GatewayW5100MQTTClient.ino' && diff --git a/.ci/pipeline.groovy b/.ci/pipeline.groovy index 36b9951..e59d78a 100644 --- a/.ci/pipeline.groovy +++ b/.ci/pipeline.groovy @@ -97,6 +97,9 @@ def call(Closure body) { stage('MySensorsGW (tests)') { arduino.buildMySensorsGw(config, config.tests, 'Tests') } + stage('ESP32 (tests)') { + arduino.buildEsp32(config, config.tests, 'Tests') + } stage('nRF52832 (tests)') { arduino.buildnRF52832(config, config.tests, 'Tests') } @@ -142,11 +145,16 @@ def call(Closure body) { stage('ESP8266 (examples)') { arduino.buildEsp8266(config, config.examples, 'Examples') } + // No point in building examples for ESP32 yet + /* + stage('ESP32 (examples)') { + arduino.buildEsp32(config, config.examples, 'Examples') + } + */ // No point in building examples for STM32F1 yet /* stage('STM32F1 (Examples)') { arduino.buildSTM32F1(config, config.tests, 'Examples') - } */ stage('ArduinoUno (examples)') { arduino.buildArduinoUno(config, config.examples, 'Examples') diff --git a/MyConfig.h b/MyConfig.h index 4dd9d3a..9cfb2f7 100644 --- a/MyConfig.h +++ b/MyConfig.h @@ -1342,6 +1342,8 @@ * @brief Define this for Ethernet GW based on the ENC28J60 module. * @def MY_GATEWAY_ESP8266 * @brief Define this for Ethernet GW based on the ESP8266. + * @def MY_GATEWAY_ESP32 + * @brief Define this for Ethernet GW based on the ESP32. * @def MY_GATEWAY_LINUX * @brief Define this for Ethernet GW based on Linux. * @def MY_GATEWAY_TINYGSM @@ -1351,6 +1353,7 @@ //#define MY_GATEWAY_W5100 //#define MY_GATEWAY_ENC28J60 //#define MY_GATEWAY_ESP8266 +//#define MY_GATEWAY_ESP32 //#define MY_GATEWAY_LINUX //#define MY_GATEWAY_TINYGSM @@ -1823,6 +1826,19 @@ #endif /** @}*/ // End of ESP8266SettingGrpPub group +/** +* @defgroup ESP32SettingGrpPub ESP32 +* @ingroup PlatformSettingGrpPub +* @brief These options control ESP32 specific configurations. +* @{ +*/ + +// +// no ESP32 settings +// + +/** @}*/ // End of ESP32SettingGrpPub group + /** * @defgroup LinuxSettingGrpPub Linux * @ingroup PlatformSettingGrpPub @@ -1891,7 +1907,7 @@ * MY_IS_GATEWAY is true when @ref MY_GATEWAY_FEATURE is set. * MY_NODE_TYPE contain a string describing the class of sketch/node (gateway/repeater/node). */ -#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60) || defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX) || defined(MY_GATEWAY_MQTT_CLIENT) || defined(MY_GATEWAY_TINYGSM) +#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60) || defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32)|| defined(MY_GATEWAY_LINUX) || defined(MY_GATEWAY_MQTT_CLIENT) || defined(MY_GATEWAY_TINYGSM) #define MY_GATEWAY_FEATURE #define MY_IS_GATEWAY (true) #define MY_NODE_TYPE "GW" @@ -2053,6 +2069,7 @@ #define MY_GATEWAY_W5100 #define MY_GATEWAY_ENC28J60 #define MY_GATEWAY_ESP8266 +#define MY_GATEWAY_ESP32 #define MY_GATEWAY_LINUX #define MY_GATEWAY_TINYGSM #define MY_IP_ADDRESS 192,168,178,66 diff --git a/MySensors.h b/MySensors.h index 3f4facf..31d6ddf 100644 --- a/MySensors.h +++ b/MySensors.h @@ -59,6 +59,8 @@ #include "hal/architecture/MyHw.h" #if defined(ARDUINO_ARCH_ESP8266) #include "hal/architecture/ESP8266/MyHwESP8266.cpp" +#elif defined(ARDUINO_ARCH_ESP32) +#include "hal/architecture/ESP32/MyHwESP32.cpp" #elif defined(ARDUINO_ARCH_AVR) #include "drivers/AVR/DigitalWriteFast/digitalWriteFast.h" #include "hal/architecture/AVR/MyHwAVR.cpp" @@ -203,8 +205,8 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs #if !defined(MY_PORT) #error You must define MY_PORT (controller or gateway port to open) #endif -#if defined(MY_GATEWAY_ESP8266) -// GATEWAY - ESP8266 +#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) +// GATEWAY - ESP8266 / ESP32 #include "core/MyGatewayTransportEthernet.cpp" #elif defined(MY_GATEWAY_LINUX) // GATEWAY - Generic Linux @@ -286,7 +288,7 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs // RAM ROUTING TABLE #if defined(MY_RAM_ROUTING_TABLE_FEATURE) && defined(MY_REPEATER_FEATURE) // activate feature based on architecture -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_NRF5) || defined(ARDUINO_ARCH_STM32F1) || defined(TEENSYDUINO) || defined(__linux__) +#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_NRF5) || defined(ARDUINO_ARCH_STM32F1) || defined(TEENSYDUINO) || defined(__linux__) #define MY_RAM_ROUTING_TABLE_ENABLED #elif defined(ARDUINO_ARCH_AVR) #if defined(__avr_atmega1280__) || defined(__avr_atmega1284__) || defined(__avr_atmega2560__) @@ -416,6 +418,8 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs #include "hal/architecture/ESP8266/MyMainESP8266.cpp" #elif defined(ARDUINO_ARCH_NRF5) #include "hal/architecture/NRF5/MyMainNRF5.cpp" +#elif defined(ARDUINO_ARCH_ESP32) +#include "hal/architecture/ESP32/MyMainESP32.cpp" #elif defined(__linux__) #include "hal/architecture/Linux/MyMainLinuxGeneric.cpp" #elif defined(ARDUINO_ARCH_STM32F1) diff --git a/core/MyCapabilities.h b/core/MyCapabilities.h index 6840898..d83875c 100644 --- a/core/MyCapabilities.h +++ b/core/MyCapabilities.h @@ -160,6 +160,8 @@ #define MY_CAP_ARCH "N" #elif defined(ARDUINO_ARCH_ESP8266) #define MY_CAP_ARCH "E" +#elif defined(ARDUINO_ARCH_ESP32) +#define MY_CAP_ARCH "F" #elif defined(ARDUINO_ARCH_AVR) #define MY_CAP_ARCH "A" #elif defined(ARDUINO_ARCH_STM32F1) diff --git a/core/MyGatewayTransportEthernet.cpp b/core/MyGatewayTransportEthernet.cpp index 9ec4512..7676613 100644 --- a/core/MyGatewayTransportEthernet.cpp +++ b/core/MyGatewayTransportEthernet.cpp @@ -30,14 +30,14 @@ IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS); IPAddress _ethernetGatewayIP(MY_IP_ADDRESS); #if defined(MY_IP_GATEWAY_ADDRESS) IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS); -#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_GATEWAY_ADDRESS */ +#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) // Assume the gateway will be the machine on the same network as the local IP // but with last octet being '1' IPAddress _gatewayIp(_ethernetGatewayIP[0], _ethernetGatewayIP[1], _ethernetGatewayIP[2], 1); #endif /* End of MY_IP_GATEWAY_ADDRESS */ #if defined(MY_IP_SUBNET_ADDRESS) IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS); -#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_SUBNET_ADDRESS */ +#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) IPAddress _subnetIp(255, 255, 255, 0); #endif /* End of MY_IP_SUBNET_ADDRESS */ #endif /* End of MY_IP_ADDRESS */ @@ -57,12 +57,12 @@ typedef struct { uint8_t idx; } inputBuffer; -#if defined(MY_GATEWAY_ESP8266) +#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) // Some re-defines to make code more readable below #define EthernetServer WiFiServer #define EthernetClient WiFiClient #define EthernetUDP WiFiUDP -#endif /* End of MY_GATEWAY_ESP8266 */ +#endif #if defined(MY_GATEWAY_CLIENT_MODE) #if defined(MY_USE_UDP) @@ -81,7 +81,7 @@ static inputBuffer inputString; #else static EthernetClient client = EthernetClient(); #endif /* End of MY_USE_UDP */ -#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_CLIENT_MODE */ +#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX) static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS]; static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS]; static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS]; @@ -136,9 +136,29 @@ bool gatewayTransportInit(void) } GATEWAY_DEBUG(PSTR("GWT:TIN:IP=%s\n"), WiFi.localIP().toString().c_str()); #endif /* End of MY_ESP8266_SSID */ -#elif defined(MY_GATEWAY_LINUX) /* Elif part of MY_GATEWAY_ESP8266 */ +#elif defined(MY_GATEWAY_ESP32) +#if defined(MY_ESP32_SSID) + // Turn off access point + WiFi.mode(WIFI_STA); +#if defined(MY_ESP32_HOSTNAME) + WiFi.setHostname(MY_ESP32_HOSTNAME); +#endif +#ifdef MY_IP_ADDRESS + WiFi.config(_ethernetGatewayIP, _gatewayIp, _subnetIp); +#endif +#ifndef MY_ESP32_BSSID +#define MY_ESP32_BSSID NULL +#endif + (void)WiFi.begin(MY_ESP32_SSID, MY_ESP32_PASSWORD, 0, MY_ESP32_BSSID); + while (WiFi.waitForConnectResult() != WL_CONNECTED) { + wait(500); + GATEWAY_DEBUG(PSTR(".")); + } + GATEWAY_DEBUG(PSTR("IP: %s\n"), WiFi.localIP().toString().c_str()); +#endif +#elif defined(MY_GATEWAY_LINUX) // Nothing to do here -#else /* Else part of MY_GATEWAY_ESP8266 */ +#else #if defined(MY_IP_GATEWAY_ADDRESS) && defined(MY_IP_SUBNET_ADDRESS) // DNS server set to gateway ip Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP, _gatewayIp, _gatewayIp, _subnetIp); @@ -157,7 +177,7 @@ bool gatewayTransportInit(void) Ethernet.localIP()[1], Ethernet.localIP()[2], Ethernet.localIP()[3]); // give the Ethernet interface a second to initialize delay(1000); -#endif /* End of MY_GATEWAY_ESP8266 */ +#endif /* MY_GATEWAY_ESP8266 / MY_GATEWAY_ESP32 */ #if defined(MY_GATEWAY_CLIENT_MODE) #if defined(MY_USE_UDP) @@ -236,7 +256,7 @@ bool gatewayTransportSend(MyMessage &message) #endif /* End of MY_USE_UDP */ #else /* Else part of MY_GATEWAY_CLIENT_MODE */ // Send message to connected clients -#if defined(MY_GATEWAY_ESP8266) +#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) { if (clients[i] && clients[i].connected()) { nbytes += clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg)); @@ -253,7 +273,7 @@ bool gatewayTransportSend(MyMessage &message) #if defined(MY_USE_UDP) // Nothing to do here #else -#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE) +#if (defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX)) && !defined(MY_GATEWAY_CLIENT_MODE) bool _readFromClient(uint8_t i) { while (clients[i].connected() && clients[i].available()) { @@ -366,7 +386,7 @@ bool gatewayTransportAvailable(void) } #endif /* End of MY_USE_UDP */ #else /* Else part of MY_GATEWAY_CLIENT_MODE */ -#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_LINUX) +#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) || defined(MY_GATEWAY_LINUX) // ESP8266: Go over list of clients and stop any that are no longer connected. // If the server has a new client connection it will be assigned to a free slot. bool allSlotsOccupied = true; @@ -443,7 +463,7 @@ MyMessage& gatewayTransportReceive(void) return _ethernetMsg; } -#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_LINUX) +#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266) && !defined(MY_GATEWAY_ESP32) && !defined(MY_GATEWAY_LINUX) void gatewayTransportRenewIP(void) { /* renew/rebind IP address diff --git a/core/MyGatewayTransportMQTTClient.cpp b/core/MyGatewayTransportMQTTClient.cpp index d7016bc..e3bf94f 100644 --- a/core/MyGatewayTransportMQTTClient.cpp +++ b/core/MyGatewayTransportMQTTClient.cpp @@ -30,19 +30,20 @@ IPAddress _brokerIp(MY_CONTROLLER_IP_ADDRESS); IPAddress _MQTT_clientIp(MY_IP_ADDRESS); #if defined(MY_IP_GATEWAY_ADDRESS) IPAddress _gatewayIp(MY_IP_GATEWAY_ADDRESS); -#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_GATEWAY_ADDRESS */ +#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) // Assume the gateway will be the machine on the same network as the local IP // but with last octet being '1' IPAddress _gatewayIp(_MQTT_clientIp[0], _MQTT_clientIp[1], _MQTT_clientIp[2], 1); #endif /* End of MY_IP_GATEWAY_ADDRESS */ + #if defined(MY_IP_SUBNET_ADDRESS) IPAddress _subnetIp(MY_IP_SUBNET_ADDRESS); -#elif defined(MY_GATEWAY_ESP8266) /* Elif part of MY_IP_SUBNET_ADDRESS */ +#elif defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) IPAddress _subnetIp(255, 255, 255, 0); #endif /* End of MY_IP_SUBNET_ADDRESS */ #endif /* End of MY_IP_ADDRESS */ -#if defined(MY_GATEWAY_ESP8266) +#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) #define EthernetClient WiFiClient #elif defined(MY_GATEWAY_LINUX) // Nothing to do here @@ -120,7 +121,7 @@ bool reconnectMQTT(void) bool gatewayTransportConnect(void) { -#if defined(MY_GATEWAY_ESP8266) +#if defined(MY_GATEWAY_ESP8266) || defined(MY_GATEWAY_ESP32) while (WiFi.status() != WL_CONNECTED) { wait(500); GATEWAY_DEBUG(PSTR("GWT:TPC:CONNECTING...\n")); @@ -216,7 +217,20 @@ bool gatewayTransportInit(void) #define MY_ESP8266_BSSID NULL #endif (void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD, 0, MY_ESP8266_BSSID); -#endif /* End of MY_GATEWAY_ESP8266 */ +#elif defined(MY_GATEWAY_ESP32) + // Turn off access point + WiFi.mode(WIFI_STA); +#if defined(MY_ESP32_HOSTNAME) + WiFi.setHostname(MY_ESP32_HOSTNAME); +#endif /* End of MY_ESP32_HOSTNAME */ +#if defined(MY_IP_ADDRESS) + WiFi.config(_MQTT_clientIp, _gatewayIp, _subnetIp); +#endif /* End of MY_IP_ADDRESS */ +#ifndef MY_ESP32_BSSID +#define MY_ESP32_BSSID NULL +#endif + (void)WiFi.begin(MY_ESP32_SSID, MY_ESP32_PASSWORD, 0, MY_ESP32_BSSID); +#endif gatewayTransportConnect(); diff --git a/core/MySensorsCore.cpp b/core/MySensorsCore.cpp index fcb6939..6b92b99 100644 --- a/core/MySensorsCore.cpp +++ b/core/MySensorsCore.cpp @@ -32,6 +32,7 @@ #endif // message buffers + MyMessage _msg; // Buffer for incoming messages MyMessage _msgTmp; // Buffer for temporary messages (acks and nonces among others) diff --git a/core/MySigningAtsha204Soft.cpp b/core/MySigningAtsha204Soft.cpp index 19c5f65..acd7bca 100644 --- a/core/MySigningAtsha204Soft.cpp +++ b/core/MySigningAtsha204Soft.cpp @@ -1,4 +1,4 @@ -/* +/* * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each diff --git a/core/MyTransport.cpp b/core/MyTransport.cpp index 5059510..06f0c14 100644 --- a/core/MyTransport.cpp +++ b/core/MyTransport.cpp @@ -1,4 +1,4 @@ -/* +/* * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each diff --git a/drivers/AES/AES_config.h b/drivers/AES/AES_config.h index ab38489..aa608a1 100644 --- a/drivers/AES/AES_config.h +++ b/drivers/AES/AES_config.h @@ -31,6 +31,8 @@ typedef unsigned char byte; #define PSTR(x) (x) #elif defined(ARDUINO_ARCH_ESP8266) #include +#elif defined(ARDUINO_ARCH_ESP32) +#include #elif defined(ARDUINO_ARCH_SAMD) #define printf_P printf #else diff --git a/drivers/RF24/RF24.h b/drivers/RF24/RF24.h index cecaf7c..4b182b7 100644 --- a/drivers/RF24/RF24.h +++ b/drivers/RF24/RF24.h @@ -67,7 +67,7 @@ #elif defined(ARDUINO_ARCH_ESP8266) #define DEFAULT_RF24_CE_PIN (4) //!< DEFAULT_RF24_CE_PIN #elif defined(ARDUINO_ARCH_ESP32) -#warning not implemented yet +#define DEFAULT_RF24_CE_PIN (17) //!< DEFAULT_RF24_CE_PIN #elif defined(ARDUINO_ARCH_SAMD) #define DEFAULT_RF24_CE_PIN (27) //!< DEFAULT_RF24_CE_PIN #elif defined(LINUX_ARCH_RASPBERRYPI) diff --git a/drivers/RFM69/new/RFM69_new.h b/drivers/RFM69/new/RFM69_new.h index 5b74c38..1f08b08 100644 --- a/drivers/RFM69/new/RFM69_new.h +++ b/drivers/RFM69/new/RFM69_new.h @@ -80,7 +80,8 @@ #elif defined(ARDUINO_ARCH_ESP8266) #define DEFAULT_RFM69_IRQ_PIN (5) //!< DEFAULT_RFM69_IRQ_PIN #elif defined(ARDUINO_ARCH_ESP32) -#warning not implemented yet +#define DEFAULT_RFM69_IRQ_PIN (16) //!< DEFAULT_RFM69_IRQ_PIN +#define DEFAULT_RFM69_IRQ_NUM digitalPinToInterrupt(DEFAULT_RFM69_IRQ_PIN) //!< DEFAULT_RFM69_IRQ_NUM #elif defined(ARDUINO_ARCH_SAMD) #define DEFAULT_RFM69_IRQ_PIN (2) //!< DEFAULT_RFM69_IRQ_PIN #elif defined(LINUX_ARCH_RASPBERRYPI) diff --git a/drivers/RFM69/old/RFM69_old.h b/drivers/RFM69/old/RFM69_old.h index 42a1aaa..9e56b6a 100644 --- a/drivers/RFM69/old/RFM69_old.h +++ b/drivers/RFM69/old/RFM69_old.h @@ -46,7 +46,8 @@ #define DEFAULT_RFM69_IRQ_PIN (5) //!< DEFAULT_RFM69_IRQ_PIN #define DEFAULT_RFM69_IRQ_NUM digitalPinToInterrupt(MY_RFM69_IRQ_PIN) //!< DEFAULT_RFM69_IRQ_NUM #elif defined(ARDUINO_ARCH_ESP32) -#warning not implemented yet +#define DEFAULT_RFM69_IRQ_PIN (16) //!< DEFAULT_RFM69_IRQ_PIN +#define DEFAULT_RFM69_IRQ_NUM digitalPinToInterrupt(DEFAULT_RFM69_IRQ_PIN) //!< DEFAULT_RFM69_IRQ_NUM #elif defined(ARDUINO_ARCH_SAMD) #define DEFAULT_RFM69_IRQ_PIN (2) //!< DEFAULT_RFM69_IRQ_PIN #define DEFAULT_RFM69_IRQ_NUM digitalPinToInterrupt(MY_RFM69_IRQ_PIN) //!< DEFAULT_RFM69_IRQ_NUM diff --git a/drivers/RFM95/RFM95.cpp b/drivers/RFM95/RFM95.cpp index 903d5e4..8fcb589 100644 --- a/drivers/RFM95/RFM95.cpp +++ b/drivers/RFM95/RFM95.cpp @@ -214,7 +214,6 @@ LOCAL bool RFM95_initialise(const uint32_t frequencyHz) RFM95_setFrequency(frequencyHz); (void)RFM95_setTxPowerLevel(MY_RFM95_TX_POWER_DBM); - if (!RFM95_sanityCheck()) { // sanity check failed, check wiring or replace module RFM95_DEBUG(PSTR("!RFM95:INIT:SANCHK FAIL\n")); diff --git a/drivers/RFM95/RFM95.h b/drivers/RFM95/RFM95.h index a302ac6..4db4a5a 100644 --- a/drivers/RFM95/RFM95.h +++ b/drivers/RFM95/RFM95.h @@ -91,7 +91,8 @@ #elif defined(ARDUINO_ARCH_ESP8266) #define DEFAULT_RFM95_IRQ_PIN (5) //!< DEFAULT_RFM95_IRQ_PIN #elif defined(ARDUINO_ARCH_ESP32) -#warning not implemented yet +#define DEFAULT_RFM95_IRQ_PIN (16) //!< DEFAULT_RFM95_IRQ_PIN +#define DEFAULT_RFM95_IRQ_NUM digitalPinToInterrupt(DEFAULT_RFM95_IRQ_PIN) //!< DEFAULT_RFM95_IRQ_NUM #elif defined(ARDUINO_ARCH_SAMD) #define DEFAULT_RFM95_IRQ_PIN (2) //!< DEFAULT_RFM95_IRQ_PIN #elif defined(LINUX_ARCH_RASPBERRYPI) diff --git a/examples/GatewayESP32/GatewayESP32.ino b/examples/GatewayESP32/GatewayESP32.ino new file mode 100644 index 0000000..6bd440f --- /dev/null +++ b/examples/GatewayESP32/GatewayESP32.ino @@ -0,0 +1,76 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2018 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + * + * REVISION HISTORY + * Version 1.0 - tekka + * + * DESCRIPTION + * The ESP32 gateway sends data received from sensors to the WiFi link. + * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. + * + * Make sure to fill in your ssid and WiFi password below. + */ + +// Enable debug prints to serial monitor +#define MY_DEBUG + +// Enables and select radio type (if attached) +#define MY_RADIO_NRF24 +//#define MY_RADIO_RFM69 +//#define MY_RADIO_RFM95 + +#define MY_GATEWAY_ESP32 + +#define MY_ESP32_SSID "MySSID" +#define MY_ESP32_PASSWORD "MyVerySecretPassword" + +// Set the hostname for the WiFi Client. This is the hostname +// it will pass to the DHCP server if not static. +#define MY_ESP32_HOSTNAME "ESP32_GW" + +// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) +//#define MY_IP_ADDRESS 192,168,1,100 + +// If using static ip you can define Gateway and Subnet address as well +//#define MY_IP_GATEWAY_ADDRESS 192,168,1,1 +//#define MY_IP_SUBNET_ADDRESS 255,255,255,0 + +// The port to keep open on node server mode +#define MY_PORT 5003 + +// How many clients should be able to connect to this gateway (default 1) +#define MY_GATEWAY_MAX_CLIENTS 2 + +#include + +void setup() +{ + // Setup locally attached sensors +} + +void presentation() +{ + // Present locally attached sensors here +} + +void loop() +{ + // Send locally attached sensors data here +} diff --git a/examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino b/examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino new file mode 100644 index 0000000..9d58793 --- /dev/null +++ b/examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino @@ -0,0 +1,90 @@ +/** + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2018 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + ******************************* + * + * REVISION HISTORY + * Version 1.0 - tekka + * + * DESCRIPTION + * The ESP32 gateway sends data received from sensors to the WiFi link. + * The gateway also accepts input on ethernet interface, which is then sent out to the radio network. + * + * Make sure to fill in your ssid and WiFi password below. + */ + +// Enable debug prints to serial monitor +#define MY_DEBUG + +// Enables and select radio type (if attached) +#define MY_RADIO_NRF24 +//#define MY_RADIO_RFM69 +//#define MY_RADIO_RFM95 + +#define MY_GATEWAY_MQTT_CLIENT +#define MY_GATEWAY_ESP32 + +// Set this node's subscribe and publish topic prefix +#define MY_MQTT_PUBLISH_TOPIC_PREFIX "mygateway1-out" +#define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "mygateway1-in" + +// Set MQTT client id +#define MY_MQTT_CLIENT_ID "mysensors-1" + +// Enable these if your MQTT broker requires usenrame/password +//#define MY_MQTT_USER "username" +//#define MY_MQTT_PASSWORD "password" + +// Set WIFI SSID and password +#define MY_ESP32_SSID "MySSID" +#define MY_ESP32_PASSWORD "MyVerySecretPassword" + +// Set the hostname for the WiFi Client. This is the hostname +// it will pass to the DHCP server if not static. +#define MY_ESP32_HOSTNAME "ESP32_MQTT_GW" + +// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) +//#define MY_IP_ADDRESS 192,168,178,87 + +// If using static ip you can define Gateway and Subnet address as well +//#define MY_IP_GATEWAY_ADDRESS 192,168,178,1 +//#define MY_IP_SUBNET_ADDRESS 255,255,255,0 + +// MQTT broker ip address. +#define MY_CONTROLLER_IP_ADDRESS 192, 168, 1, 5 + +// The MQTT broker port to to open +#define MY_PORT 1883 + +#include + +void setup() +{ + // Setup locally attached sensors +} + +void presentation() +{ + // Present locally attached sensors here +} + +void loop() +{ + // Send locally attech sensors data here +} + diff --git a/hal/architecture/ESP32/MyHwESP32.cpp b/hal/architecture/ESP32/MyHwESP32.cpp new file mode 100644 index 0000000..25578fc --- /dev/null +++ b/hal/architecture/ESP32/MyHwESP32.cpp @@ -0,0 +1,168 @@ +/* + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2018 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * Arduino core for ESP32: https://github.com/espressif/arduino-esp32 + * + * MySensors ESP32 implementation, Copyright (C) 2017-2018 Olivier Mauti + * + */ + +#include "MyHwESP32.h" + +bool hwInit(void) +{ +#if !defined(MY_DISABLED_SERIAL) + MY_SERIALDEVICE.begin(MY_BAUD_RATE, SERIAL_8N1); +#endif + return EEPROM.begin(MY_EEPROM_SIZE); +} + +void hwReadConfigBlock(void *buf, void *addr, size_t length) +{ + uint8_t *dst = static_cast(buf); + int offs = reinterpret_cast(addr); + while (length-- > 0) { + *dst++ = EEPROM.read(offs++); + } +} + +void hwWriteConfigBlock(void *buf, void *addr, size_t length) +{ + uint8_t *src = static_cast(buf); + int offs = reinterpret_cast(addr); + while (length-- > 0) { + EEPROM.write(offs++, *src++); + } + EEPROM.commit(); +} + +uint8_t hwReadConfig(const int addr) +{ + uint8_t value; + hwReadConfigBlock(&value, reinterpret_cast(addr), 1); + return value; +} + +void hwWriteConfig(const int addr, uint8_t value) +{ + if (hwReadConfig(addr) != value) { + hwWriteConfigBlock(&value, reinterpret_cast(addr), 1); + } +} + +bool hwUniqueID(unique_id_t *uniqueID) +{ + uint64_t val = ESP.getEfuseMac(); + (void)memcpy((void *)uniqueID, (void *)&val, 8); + (void)memset((void *)(uniqueID + 8), MY_HWID_PADDING_BYTE, 8); // padding + return true; +} + +ssize_t hwGetentropy(void *__buffer, size_t __length) +{ + // cut length if > 256 + if (__length > 256) { + __length = 256; + } + uint8_t *dst = (uint8_t *)__buffer; + // get random numbers + for (size_t i = 0; i < __length; i++) { + dst[i] = (uint8_t)esp_random(); + } + return __length; +} + +int8_t hwSleep(uint32_t ms) +{ + // TODO: Not supported! + (void)ms; + return MY_SLEEP_NOT_POSSIBLE; +} + +int8_t hwSleep(const uint8_t interrupt, const uint8_t mode, uint32_t ms) +{ + // TODO: Not supported! + (void)interrupt; + (void)mode; + (void)ms; + return MY_SLEEP_NOT_POSSIBLE; +} + +int8_t hwSleep(const uint8_t interrupt1, const uint8_t mode1, const uint8_t interrupt2, + const uint8_t mode2, + uint32_t ms) +{ + // TODO: Not supported! + (void)interrupt1; + (void)mode1; + (void)interrupt2; + (void)mode2; + (void)ms; + return MY_SLEEP_NOT_POSSIBLE; +} + +uint16_t hwCPUVoltage(void) +{ + // in mV + return FUNCTION_NOT_SUPPORTED; +} + +uint16_t hwCPUFrequency(void) +{ + // in 1/10Mhz + return static_cast(ESP.getCpuFreqMHz() * 10); +} + +uint8_t hwCPUTemperature(void) +{ + // CPU temperature in °C + return static_cast(temperatureRead()); +} + +uint16_t hwFreeMem(void) +{ + return static_cast(ESP.getFreeHeap()); +} + +void hwDebugPrint(const char *fmt, ...) +{ + char fmtBuffer[MY_SERIAL_OUTPUT_SIZE]; +#ifdef MY_GATEWAY_SERIAL + // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE) + snprintf_P(fmtBuffer, sizeof(fmtBuffer), PSTR("0;255;%d;0;%d;%lu "), C_INTERNAL, I_LOG_MESSAGE, + millis()); + MY_SERIALDEVICE.print(fmtBuffer); +#else + // prepend timestamp + MY_SERIALDEVICE.print(millis()); + MY_SERIALDEVICE.print(" "); +#endif + va_list args; + va_start(args, fmt); +#ifdef MY_GATEWAY_SERIAL + // Truncate message if this is gateway node + vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args); + fmtBuffer[sizeof(fmtBuffer) - 2] = '\n'; + fmtBuffer[sizeof(fmtBuffer) - 1] = '\0'; +#else + vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args); +#endif + va_end(args); + MY_SERIALDEVICE.print(fmtBuffer); + MY_SERIALDEVICE.flush(); +} diff --git a/hal/architecture/ESP32/MyHwESP32.h b/hal/architecture/ESP32/MyHwESP32.h new file mode 100644 index 0000000..64d6ac7 --- /dev/null +++ b/hal/architecture/ESP32/MyHwESP32.h @@ -0,0 +1,89 @@ +/* + * The MySensors Arduino library handles the wireless radio link and protocol + * between your home built sensors/actuators and HA controller of choice. + * The sensors forms a self healing radio network with optional repeaters. Each + * repeater and gateway builds a routing tables in EEPROM which keeps track of the + * network topology allowing messages to be routed to nodes. + * + * Created by Henrik Ekblad + * Copyright (C) 2013-2018 Sensnology AB + * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors + * + * Documentation: http://www.mysensors.org + * Support Forum: http://forum.mysensors.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * Arduino core for ESP32: https://github.com/espressif/arduino-esp32 + * + * MySensors ESP32 implementation, Copyright (C) 2017-2018 Olivier Mauti + * + * Radio wiring ESP32(Node32s): RF24, RFM69, RFM95: + * + * | IO | RF24 | RFM69 | RFM95 | + * |------|------|-------|-------| + * | MOSI | 23 | 23 | 23 | + * | MISO | 19 | 19 | 19 | + * | SCK | 18 | 18 | 18 | + * | CSN | 5 | 5 | 5 | + * | CE | 17 | - | - | + * | RST | - | 17 | 17 | + * | IRQ | 16* | 16 | 16 | + * * = optional + * + */ + +#ifndef MyHwESP32_h +#define MyHwESP32_h + +#include +#include "EEPROM.h" + +#ifdef __cplusplus +#include +#endif + +#define MY_SERIALDEVICE Serial + +#define min(a,b) ((a)<(b)?(a):(b)) +#define max(a,b) ((a)>(b)?(a):(b)) + +#define MIN min +#define MAX max + +#define MY_EEPROM_SIZE 1024 + +#define hwDigitalWrite(__pin, __value) digitalWrite(__pin, __value) +#define hwDigitalRead(__pin) digitalRead(__pin) +#define hwPinMode(__pin, __value) pinMode(__pin, __value) +#define hwWatchdogReset() +#define hwReboot() ESP.restart() +#define hwMillis() millis() +#define hwMicros() micros() +#define hwRandomNumberInit() randomSeed(esp_random()) + +bool hwInit(void); +void hwReadConfigBlock(void *buf, void *addr, size_t length); +void hwWriteConfigBlock(void *buf, void *addr, size_t length); +void hwWriteConfig(const int addr, uint8_t value); +uint8_t hwReadConfig(const int addr); +ssize_t hwGetentropy(void *__buffer, size_t __length); +#define MY_HW_HAS_GETENTROPY + +/** +* Restore interrupt state. +* Helper function for MY_CRITICAL_SECTION. +*/ +static __inline__ void __psRestore(const uint32_t *__s) +{ + XTOS_RESTORE_INTLEVEL(*__s); +} + +#ifndef DOXYGEN +#define MY_CRITICAL_SECTION for ( uint32_t __psSaved __attribute__((__cleanup__(__psRestore))) = XTOS_DISABLE_ALL_INTERRUPTS, __ToDo = 1; __ToDo ; __ToDo = 0 ) +#endif /* DOXYGEN */ + + +#endif diff --git a/hal/architecture/ESP32/MyMainESP32.cpp b/hal/architecture/ESP32/MyMainESP32.cpp new file mode 100644 index 0000000..99be171 --- /dev/null +++ b/hal/architecture/ESP32/MyMainESP32.cpp @@ -0,0 +1,49 @@ +/* +* The MySensors Arduino library handles the wireless radio link and protocol +* between your home built sensors/actuators and HA controller of choice. +* The sensors forms a self healing radio network with optional repeaters. Each +* repeater and gateway builds a routing tables in EEPROM which keeps track of the +* network topology allowing messages to be routed to nodes. +* +* Created by Henrik Ekblad +* Copyright (C) 2013-2018 Sensnology AB +* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors +* +* Documentation: http://www.mysensors.org +* Support Forum: http://forum.mysensors.org +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* version 2 as published by the Free Software Foundation. +* +*/ + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "Arduino.h" + +#if CONFIG_AUTOSTART_ARDUINO + +#if CONFIG_FREERTOS_UNICORE +#define ARDUINO_RUNNING_CORE 0 +#else +#define ARDUINO_RUNNING_CORE 1 +#endif + +void MySensorsTask(void *pvParameters) +{ + _begin(); // Startup MySensors library + for (;;) { + micros(); // update overflow + _process(); // Process incoming data + loop(); // Call sketch loop + } +} + +extern "C" void app_main() +{ + initArduino(); + xTaskCreatePinnedToCore(MySensorsTask, "MySensorsTask", 8192, NULL, 1, NULL, ARDUINO_RUNNING_CORE); +} + +#endif diff --git a/keywords.txt b/keywords.txt index 0a53ed8..917d3f5 100644 --- a/keywords.txt +++ b/keywords.txt @@ -229,6 +229,7 @@ MY_RS485_SOH_COUNT LITERAL1 # Gateway / MQTT MY_GATEWAY_CLIENT_MODE LITERAL1 MY_GATEWAY_ENC28J60 LITERAL1 +MY_GATEWAY_ESP32 LITERAL1 MY_GATEWAY_ESP8266 LITERAL1 MY_GATEWAY_MQTT_CLIENT LITERAL1 MY_GATEWAY_SERIAL LITERAL1 @@ -255,6 +256,12 @@ MY_MAC_ADDRESS LITERAL1 MY_PORT LITERAL1 MY_USE_UDP LITERAL1 +# ESP32 +MY_ESP32_SSID LITERAL1 +MY_ESP32_PASSWORD LITERAL1 +MY_ESP32_BSSID LITERAL1 +MY_ESP32_HOSTNAME LITERAL1 + # ESP8266 MY_ESP8266_BSSID LITERAL1 MY_ESP8266_HOSTNAME LITERAL1