From f0f5db24a911b3e1dbe78eb0224ac2ff4d6a96d3 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Wed, 29 Apr 2020 17:04:37 +0200 Subject: [PATCH 01/23] Update lvgl --- lib/lvgl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lvgl b/lib/lvgl index 549c75c0..85f281bd 160000 --- a/lib/lvgl +++ b/lib/lvgl @@ -1 +1 @@ -Subproject commit 549c75c07fbabc5c6799ef5d676875eadd5874e6 +Subproject commit 85f281bd3b4a6cb60381ff3d8a73534748e7d079 From 7e826979828d30b8dc90eef78f791db7125b76ff Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:30:17 +0200 Subject: [PATCH 02/23] Add DMA define --- src/hasp_gui.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 021b890a..d590718f 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -628,6 +628,13 @@ void guiSetup() { /* TFT init */ tft.begin(); + +#ifdef USE_DMA_TO_TFT +// DMA - should work with STM32F2xx/F4xx/F7xx processors +// NOTE: >>>>>> DMA IS FOR SPI DISPLAYS ONLY <<<<<< +tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767) +#endif + tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */ #if TOUCH_DRIVER == 0 tft.setTouch(calData); @@ -673,8 +680,13 @@ void guiSetup() lv_fs_if_init(); // auxilary file system drivers #endif - /* Dump TFT Cofiguration */ + /* Dump TFT Configuration */ tftSetup(tft); +#ifdef USE_DMA_TO_TFT + Log.verbose(F("TFT: DMA : ENABELD")); +#else + Log.verbose(F("TFT: DMA : DISABELD")); +#endif /* Load User Settings */ // guiSetConfig(settings); @@ -814,7 +826,7 @@ void IRAM_ATTR guiLoop() #ifdef STM32_CORE_VERSION_MAJOR tick.update(); - while(Serial.available()) { + while(Serial.available()) { char ch = Serial.read(); Serial.print(ch); if (ch == 13 ||ch == 10) { @@ -991,6 +1003,7 @@ bool guiSetConfig(const JsonObject & settings) oobeSetAutoCalibrate(true); } + if (status) tft.setTouch(calData); changed |= status; } From f9d14e7fba2702a5faf2b54f174a9c54ca94428c Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:30:51 +0200 Subject: [PATCH 03/23] Update debug for STM32 --- src/hasp_debug.cpp | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 854b9db4..9a7192ba 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -15,7 +15,7 @@ #endif #include "hasp_hal.h" -#if HASP_USE_MQTT>0 +#if HASP_USE_MQTT > 0 #include "hasp_mqtt.h" #endif @@ -73,7 +73,7 @@ Syslog * syslog; // Serial Settings uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10 bool debugSerialStarted = false; -bool debugAnsiCodes = true; +bool debugAnsiCodes = true; //#define TERM_COLOR_Black "\u001b[30m" #define TERM_COLOR_GRAY "\e[37m" @@ -94,7 +94,8 @@ String debugHaspHeader() { String header((char *)0); header.reserve(256); - header = F(" _____ _____ _____ _____\r\n" + if(debugAnsiCodes) header += TERM_COLOR_YELLOW; + header += F(" _____ _____ _____ _____\r\n" " | | | _ | __| _ |\r\n" " | | |__ | __|\r\n" " |__|__|__|__|_____|__|\r\n" @@ -216,21 +217,23 @@ static void debugPrintTimestamp(int level, Print * _logOutput) time_t rawtime; struct tm * timeinfo; - //time(&rawtime); - //timeinfo = localtime(&rawtime); + // time(&rawtime); + // timeinfo = localtime(&rawtime); // strftime(buffer, sizeof(buffer), "%b %d %H:%M:%S.", timeinfo); // Serial.println(buffer); debugSendAnsiCode(F(TERM_COLOR_CYAN), _logOutput); - /* if(timeinfo->tm_year >= 120) { - char buffer[64]; - strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S.", timeinfo); // Literal String - _logOutput->print(buffer); - _logOutput->printf(PSTR("%03lu]"), millis() % 1000); - } else */ { - _logOutput->printf(PSTR("[%20.3f]"), (float)millis() / 1000); + /* if(timeinfo->tm_year >= 120) { + char buffer[64]; + strftime(buffer, sizeof(buffer), "[%b %d %H:%M:%S.", timeinfo); // Literal String + _logOutput->print(buffer); + _logOutput->printf(PSTR("%03lu]"), millis() % 1000); + } else */ + { + //_logOutput->printf(PSTR("[%20.3f]"), (float)millis() / 1000); + _logOutput->printf(PSTR("[%20d]"), millis() ); } } @@ -328,15 +331,15 @@ void debugPreSetup(JsonObject settings) uint32_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as() * 10; if(baudrate == 0) baudrate = SERIAL_SPEED; - if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */ + if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */ #ifdef STM32_CORE_VERSION_MAJOR - Serial.setRx(PA3); // User Serial2 - Serial.setTx(PA2); + // Serial.setRx(PA3); // User Serial2 + // Serial.setTx(PA2); #endif Serial.begin(baudrate); /* prepare for possible serial debug */ delay(10); - Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true); + Log.registerOutput(0, &Serial, LOG_LEVEL_VERBOSE, true); debugSerialStarted = true; Serial.println(); Log.trace(("Serial started at %u baud"), baudrate); From cd91930104f51d9c6edd42b20c7326765ad45685 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:31:07 +0200 Subject: [PATCH 04/23] Update debug for STM32 --- lib/ArduinoLog/ArduinoLog.h | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/ArduinoLog/ArduinoLog.h b/lib/ArduinoLog/ArduinoLog.h index 645d4f74..d0f9f3d9 100644 --- a/lib/ArduinoLog/ArduinoLog.h +++ b/lib/ArduinoLog/ArduinoLog.h @@ -285,19 +285,15 @@ class Logging { if(_logOutput[i] == NULL || level>_level[i]) continue; if(_prefix != NULL) { - // _prefix(level, _logOutput[i]); + _prefix(level, _logOutput[i]); } va_list args; va_start(args, msg); -#ifdef STM32_CORE_VERSION_MAJOR - print(_logOutput[i], msg, args); - Serial.println(); -#else - print(_logOutput[i], msg, args); -#endif + print(_logOutput[i], msg, args); + if(_suffix != NULL) { - // _suffix(level, _logOutput[i]); + _suffix(level, _logOutput[i]); } } From 814006aad88e761686b1c520623e075061e08ac0 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:31:36 +0200 Subject: [PATCH 05/23] Code cleanup --- src/hasp_config.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 86fec041..8e4a0ada 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -23,11 +23,6 @@ #include "EEPROM.h" #endif -#ifndef FPSTR -#define FPSTR(pstr_pointer) (reinterpret_cast(pstr_pointer)) -#endif - - void confDebugSet(const char * name) { /*char buffer[128]; From 6e4fa9ee974622e15be383e8a1b5cafb105054a1 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:32:09 +0200 Subject: [PATCH 06/23] Code cleanup --- src/hasp_dispatch.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp index bed14991..d4965ce2 100644 --- a/src/hasp_dispatch.cpp +++ b/src/hasp_dispatch.cpp @@ -48,11 +48,15 @@ void dispatchOutput(int output, bool state) int pin = 0; if(pin >= 0) { + Log.notice(F("PIN OUTPUT STATE %d"),state); #if defined(ARDUINO_ARCH_ESP32) ledcWrite(99, state ? 1023 : 0); // ledChannel and value -#else +#elif defined(ARDUINO_ARCH_ESP8266) analogWrite(pin, state ? 1023 : 0); +#else + pinMode (PE0, OUTPUT); + digitalWrite(PE0, state ? 1 : 0); #endif } } @@ -95,11 +99,6 @@ void dispatchAttribute(String strTopic, const char * payload) { if(strTopic.startsWith("p[")) { dispatchButtonAttribute(strTopic, payload); - } else if(strTopic.startsWith(F("output"))) { -#if defined(ARDUINO_ARCH_ESP8266) - uint8_t state = isON(payload) ? HIGH : LOW; - digitalWrite(D1, state); -#endif } else if(strTopic == F("page")) { dispatchPage(payload); @@ -184,7 +183,7 @@ void dispatchBacklight(String strPayload) void dispatchCommand(String cmnd) { - // dispatchPrintln(F("CMND"), cmnd); + dispatchPrintln(F("CMND"), cmnd); if(cmnd.startsWith(F("page "))) { cmnd = cmnd.substring(5, cmnd.length()); @@ -293,6 +292,8 @@ void dispatch_button(uint8_t id, const char * event) { #if HASP_USE_MQTT > 0 mqtt_send_input(id, event); +#else + Log.notice(F("OUT: input%d = %s"), id, event); #endif } From 3296b5005bce761a3de1d139ee19375666c0a24b Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:32:30 +0200 Subject: [PATCH 07/23] Test support for STM32 --- src/hasp_button.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/hasp_button.cpp b/src/hasp_button.cpp index 400a0b84..b30efe74 100644 --- a/src/hasp_button.cpp +++ b/src/hasp_button.cpp @@ -36,17 +36,13 @@ static void button_event_cb(AceButton * button, uint8_t eventType, uint8_t butto memcpy_P(buffer, PSTR("UP"), sizeof(buffer)); break; } + Log.verbose(F("BTNS: setup(): ready")); + dispatch_button(button->getId(), buffer); } void buttonSetup(void) { - // button[0] = new Button(2); - button[1] = new AceButton(3, HIGH, 1); - button[2] = new AceButton(4, HIGH, 2); - - Log.verbose(F("BTNS: setup(): ready")); - ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig(); buttonConfig->setEventHandler(button_event_cb); @@ -63,6 +59,25 @@ void buttonSetup(void) buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME); + + // button[0] = new Button(2); +#if defined(ARDUINO_ARCH_ESP8266) + button[1] = new AceButton(3, HIGH, 1); +#else + //button[1] = new AceButton(3, HIGH, 1); +#endif + pinMode (PC13, INPUT_PULLUP); + button[0] = new AceButton(buttonConfig, PC13, HIGH, 0); + + pinMode (PA0, INPUT_PULLUP); + button[1] = new AceButton(buttonConfig, PA0, HIGH, 1); + + pinMode (PD15, INPUT); + button[2] = new AceButton(buttonConfig, PD15, HIGH, 2); + + Log.verbose(F("BTNS: setup(): ready")); + + } void IRAM_ATTR buttonLoop(void) From 9ab641b9efea14724a36c2355872f51ad51c3ab9 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:32:39 +0200 Subject: [PATCH 08/23] Add logging --- lib/lv_fs_if/lv_fs_spiffs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lv_fs_if/lv_fs_spiffs.cpp b/lib/lv_fs_if/lv_fs_spiffs.cpp index 49acb1ce..aad335bd 100644 --- a/lib/lv_fs_if/lv_fs_spiffs.cpp +++ b/lib/lv_fs_if/lv_fs_spiffs.cpp @@ -150,7 +150,7 @@ static lv_fs_res_t fs_open(lv_fs_drv_t * drv, void * file_p, const char * path, Log.verbose(F("LVFS: %d"), __LINE__); lv_spiffs_file_t * fp = (lv_spiffs_file_t *)file_p; /*Just avoid the confusing casings*/ // Log.verbose(F("LVFS: Copying %s"), f.name()); - Log.verbose(F("LVFS: %d"), __LINE__); + Log.verbose(F("LVFS: %d - %x - %d"), __LINE__, fp, sizeof(lv_spiffs_file_t)); if (fp != NULL) (*fp) = file; // memcpy(fp,&file,sizeof(lv_spiffs_file_t)); Log.verbose(F("LVFS: %d"), __LINE__); From 60e40f876702811c7d839dcdc2eaa1cc44548907 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:38:05 +0200 Subject: [PATCH 09/23] Update lvgl --- lib/lvgl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/lvgl b/lib/lvgl index 85f281bd..549c75c0 160000 --- a/lib/lvgl +++ b/lib/lvgl @@ -1 +1 @@ -Subproject commit 85f281bd3b4a6cb60381ff3d8a73534748e7d079 +Subproject commit 549c75c07fbabc5c6799ef5d676875eadd5874e6 From c15af62a46f3f9b102a5e429066b097cec3a6d6e Mon Sep 17 00:00:00 2001 From: fvanroie Date: Thu, 30 Apr 2020 17:42:44 +0200 Subject: [PATCH 10/23] Fix merge issue --- platformio.ini | 4 +++- src/hasp_dispatch.cpp | 5 +---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 81b7f8d9..3c9bec90 100644 --- a/platformio.ini +++ b/platformio.ini @@ -88,6 +88,7 @@ esp32_flags= stm32_flags= ${env.build_flags} -D IRAM_ATTR= ; No IRAM_ATTR available on STM32 + -D STM32 ; -- By default there are no ${override.build_flags} set ; -- to use it, copy platformio_override.ini from the template @@ -144,7 +145,8 @@ build_flags = -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4) -D TOUCH_CS=PC4 ;NC -D TFT_RST=-1 ;D4 - -D STM32 + -D HASP_OUTPUT_PIN=PA1 ; User LED D2 on DevEBox board + -D HASP_INPUT_PIN=PA0 ; User Button K1 on DevEBox board lib_deps = ${env.lib_deps} diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp index a93a485e..43156964 100644 --- a/src/hasp_dispatch.cpp +++ b/src/hasp_dispatch.cpp @@ -98,10 +98,7 @@ void dispatchAttribute(String strTopic, const char * payload) { if(strTopic.startsWith("p[")) { dispatchButtonAttribute(strTopic, payload); -<<<<<<< HEAD - -======= ->>>>>>> 408b27b8155bd5f1c11900503df88956925fa6bd + } else if(strTopic == F("page")) { dispatchPage(payload); From bbb45057153d808cd9dade224cb24df6e37e3ab2 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Fri, 1 May 2020 21:57:55 +0200 Subject: [PATCH 11/23] Code clean-up --- src/hasp.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hasp.h b/src/hasp.h index c9dbbab9..beda81e2 100644 --- a/src/hasp.h +++ b/src/hasp.h @@ -81,8 +81,6 @@ void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color); void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload); -void haspSendCmd(String nextionCmd); -void haspParseJson(String & strPayload); void haspNewObject(const JsonObject & config, uint8_t & saved_page_id); void haspReconnect(void); From d669e47704b72d4060a57a9da422b13b8c31e74f Mon Sep 17 00:00:00 2001 From: fvanroie Date: Fri, 1 May 2020 21:58:10 +0200 Subject: [PATCH 12/23] Code clean-up --- src/hasp_gui.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 337f8761..06c21d2e 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -306,14 +306,6 @@ static void IRAM_ATTR lv_tick_handler(void) lv_tick_inc(guiTickPeriod); } -#ifdef STM32_CORE_VERSION -void Update_IT_callback(void) -{ - Serial.print("?"); - lv_tick_inc(guiTickPeriod); -} -#endif - /* Reading input device (simulated encoder here) */ /*bool read_encoder(lv_indev_drv_t * indev, lv_indev_data_t * data) { @@ -823,7 +815,7 @@ tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767 void IRAM_ATTR guiLoop() { -#ifdef STM32_CORE_VERSION_MAJOR +#if defined(STM32F4xx) tick.update(); while(Serial.available()) { From 1a456481469ae507b6fdccfa23b4a8c331d5e4fc Mon Sep 17 00:00:00 2001 From: fvanroie Date: Fri, 1 May 2020 21:58:45 +0200 Subject: [PATCH 13/23] Code clean-up --- src/hasp_eeprom.cpp | 46 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/src/hasp_eeprom.cpp b/src/hasp_eeprom.cpp index 1aed0979..ddc3d8d8 100644 --- a/src/hasp_eeprom.cpp +++ b/src/hasp_eeprom.cpp @@ -1,49 +1,17 @@ #include #include "EEPROM.h" -#include "hasp_debug.h" - -void eepromWrite(char addr, std::string & data); -std::string eepromRead(char addr); - void eepromSetup() { + +#if defined(STM32Fxx) + eeprom_buffer_fill(); +#endif + + // ESP8266 // Don't start at boot, only at write // EEPROM.begin(1024); // debugPrintln("EEPROM: Started Eeprom"); } void eepromLoop() -{} - -void eepromUpdate(uint16_t addr, char ch) -{ - if(EEPROM.read(addr) != ch) { - EEPROM.write(addr, ch); - } -} - -void eepromWrite(uint16_t addr, std::string & data) -{ - int count = data.length(); - for(int i = 0; i < count; i++) { - eepromUpdate(addr + i, data[i]); - } - eepromUpdate(addr + count, '\0'); - // EEPROM.commit(); -} - -std::string eepromRead(uint16_t addr) -{ - char data[1024]; // Max 1024 Bytes - int len = 0; - unsigned char k; - k = EEPROM.read(addr); - while(k != '\0' && len < 1023) // Read until null character - { - k = EEPROM.read(addr + len); - if((uint8_t(k) < 32) || (uint8_t(k) > 127)) break; // check for printable ascii, includes '\0' - data[len] = k; - len++; - } - return std::string(data); -} \ No newline at end of file +{} \ No newline at end of file From 7650a2ed811271d464aaba3a3a34851e97675120 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:15:54 +0200 Subject: [PATCH 14/23] Move from button to gpio --- src/hasp_button.cpp | 90 ----------------------- src/hasp_button.h | 10 --- src/hasp_gpio.cpp | 170 +++++++++++++++++++++++++++++++++++++++++--- src/hasp_gpio.h | 24 ++++++- 4 files changed, 184 insertions(+), 110 deletions(-) delete mode 100644 src/hasp_button.cpp delete mode 100644 src/hasp_button.h diff --git a/src/hasp_button.cpp b/src/hasp_button.cpp deleted file mode 100644 index b30efe74..00000000 --- a/src/hasp_button.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "Arduino.h" -#include "ArduinoLog.h" -#include "AceButton.h" - -#include "hasp_conf.h" -#include "lv_conf.h" - -#include "hasp_mqtt.h" // testing memory consumption -#include "hasp_button.h" -#include "hasp_dispatch.h" - -using namespace ace_button; -static AceButton * button[HASP_NUM_INPUTS]; // Connect your button between pin 2 and GND - -static void button_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState) -{ - char buffer[8]; - switch(eventType) { - case 0: // AceButton::kEventPressed: - memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer)); - break; - case 2: // AceButton::kEventClicked: - memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer)); - break; - // case AceButton::kEventDoubleClicked: - // memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer)); - // break; - case 4: // AceButton::kEventLongPressed: - memcpy_P(buffer, PSTR("LONG"), sizeof(buffer)); - break; - case 5: // AceButton::kEventRepeatPressed: - return; // Fix needed for switches - memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer)); - break; - case 1: // AceButton::kEventReleased: - memcpy_P(buffer, PSTR("UP"), sizeof(buffer)); - break; - } - Log.verbose(F("BTNS: setup(): ready")); - - dispatch_button(button->getId(), buffer); -} - -void buttonSetup(void) -{ - ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig(); - buttonConfig->setEventHandler(button_event_cb); - - // Features - buttonConfig->setFeature(ButtonConfig::kFeatureClick); - buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); - buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress); - // buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick); - // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); - - // Delays - buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); - buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME); - - // button[0] = new Button(2); -#if defined(ARDUINO_ARCH_ESP8266) - button[1] = new AceButton(3, HIGH, 1); -#else - //button[1] = new AceButton(3, HIGH, 1); -#endif - pinMode (PC13, INPUT_PULLUP); - button[0] = new AceButton(buttonConfig, PC13, HIGH, 0); - - pinMode (PA0, INPUT_PULLUP); - button[1] = new AceButton(buttonConfig, PA0, HIGH, 1); - - pinMode (PD15, INPUT); - button[2] = new AceButton(buttonConfig, PD15, HIGH, 2); - - Log.verbose(F("BTNS: setup(): ready")); - - -} - -void IRAM_ATTR buttonLoop(void) -{ - // Should be called every 4-5ms or faster, for the default debouncing time - // of ~20ms. - for(uint8_t i = 0; i < HASP_NUM_INPUTS; i++) { - if(button[i]) button[i]->check(); - } -} diff --git a/src/hasp_button.h b/src/hasp_button.h deleted file mode 100644 index e19bb556..00000000 --- a/src/hasp_button.h +++ /dev/null @@ -1,10 +0,0 @@ -#if HASP_USE_BUTTON - -#ifndef HASP_BUTTON_H -#define HASP_BUTTON_H - -void buttonSetup(void); -void IRAM_ATTR buttonLoop(void); - -#endif -#endif diff --git a/src/hasp_gpio.cpp b/src/hasp_gpio.cpp index 4094d7e6..cf3ceee9 100644 --- a/src/hasp_gpio.cpp +++ b/src/hasp_gpio.cpp @@ -1,14 +1,166 @@ -#include -#include "ArduinoJson.h" +#include "Arduino.h" +#include "ArduinoLog.h" + +#include "AceButton.h" +#include "lv_conf.h" // For timing defines + +#include "hasp_conf.h" +#include "hasp_gpio.h" +#include "hasp_dispatch.h" + +#define HASP_NUM_GPIO_CONFIG 5 + +uint8_t gpioUsedInputCount = 0; +uint16_t gpioConfig[HASP_NUM_GPIO_CONFIG]; + +using namespace ace_button; +static AceButton * button[HASP_NUM_INPUTS]; + +static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState) +{ + char buffer[16]; + switch(eventType) { + case 0: // AceButton::kEventPressed: + memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer)); + break; + case 2: // AceButton::kEventClicked: + memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer)); + break; + case AceButton::kEventDoubleClicked: + memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer)); + break; + case 4: // AceButton::kEventLongPressed: + memcpy_P(buffer, PSTR("LONG"), sizeof(buffer)); + break; + case 5: // AceButton::kEventRepeatPressed: + // return; // Fix needed for switches + memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer)); + break; + case 1: // AceButton::kEventReleased: + memcpy_P(buffer, PSTR("UP"), sizeof(buffer)); + break; + default: + memcpy_P(buffer, PSTR("UNKNOWN"), sizeof(buffer)); + } + dispatch_button(button->getId(), buffer); +} + +void aceButtonSetup(void) +{ + ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig(); + buttonConfig->setEventHandler(gpio_event_cb); + + // Features + buttonConfig->setFeature(ButtonConfig::kFeatureClick); + buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); + buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress); + // buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick); + // buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); + + // Delays + buttonConfig->setClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig->setDoubleClickDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig->setLongPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig->setRepeatPressDelay(LV_INDEV_DEF_LONG_PRESS_TIME); + buttonConfig->setRepeatPressInterval(LV_INDEV_DEF_LONG_PRESS_REP_TIME); +} + +void IRAM_ATTR gpioLoop(void) +{ + // Should be called every 4-5ms or faster, for the default debouncing time of ~20ms. + for(uint8_t i = 0; i < gpioUsedInputCount; i++) { + if(button[i]) button[i]->check(); + } +} + +void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel) +{ + uint8_t i; + for(i = 0; i < HASP_NUM_INPUTS; i++) { + + if(!button[i]) { + button[i] = new AceButton(pin, default_state, channel); + + if(button[i]) { + pinMode(pin, input_mode); + + ButtonConfig * buttonConfig = button[i]->getButtonConfig(); + buttonConfig->setEventHandler(gpio_event_cb); + buttonConfig->setFeature(ButtonConfig::kFeatureClick); + buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick); + buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); + buttonConfig->setFeature(ButtonConfig::kFeatureRepeatPress); + buttonConfig->setFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); + + Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel, input_mode,default_state); + gpioUsedInputCount = i + 1; + return; + } + } + } + Log.error(F("GPIO: Failed to create Button%d pin %d (channel %d). All %d slots available are in use!"), i, pin, + channel, HASP_NUM_INPUTS); +} void gpioSetup() { -#if defined(ARDUINO_ARCH_ESP8266) - pinMode(D1, OUTPUT); - pinMode(D2, INPUT_PULLUP); -#endif -#if defined(STM32_CORE_VERSION) - pinMode(HASP_OUTPUT_PIN, OUTPUT); - pinMode(HASP_INPUT_PIN, INPUT_PULLUP); + aceButtonSetup(); + + //gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3); + + for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { + uint8_t pin = (gpioConfig[i] >> 8) & 0xFF; + uint8_t channel = gpioConfig[i] & 0b111; // 3bit + uint8_t input_mode = (gpioConfig[i] >> 3) & 0b11; // 2bit gpio mode + uint8_t gpiotype = (gpioConfig[i] >> 5) & 0b111; // 3bit + uint8_t default_state = gpioConfig[i] & 0b1; // 1bit: 0=LOW, 1=HIGH + + switch(input_mode) { + case 1: + input_mode = OUTPUT; + break; + case 2: + input_mode = INPUT_PULLUP; + break; + case 3: + input_mode = INPUT_PULLDOWN; + break; + default: + input_mode = INPUT; + } + + switch(gpiotype) { + case HASP_GPIO_SWITCH: + case HASP_GPIO_BUTTON: + gpioAddButton(pin, input_mode, default_state, channel); + break; + + case HASP_GPIO_RELAY: + pinMode(pin, OUTPUT); + break; + + // case HASP_GPIO_LED: + case HASP_GPIO_PWM: + case HASP_GPIO_BACKLIGHT: + pinMode(pin, OUTPUT); +#if defined(ARDUINO_ARCH_ESP32) + // configure LED PWM functionalitites + ledcSetup(channel, 20000, 10); + // attach the channel to the GPIO to be controlled + ledcAttachPin(pin, channel); #endif + break; + } + } + + /* + #if defined(ARDUINO_ARCH_ESP8266) + pinMode(D1, OUTPUT); + pinMode(D2, INPUT_PULLUP); + #endif + #if defined(STM32F4xx) + pinMode(HASP_OUTPUT_PIN, OUTPUT); + pinMode(HASP_INPUT_PIN, INPUT); + #endif + */ } \ No newline at end of file diff --git a/src/hasp_gpio.h b/src/hasp_gpio.h index 075f3a12..9a5c3b91 100644 --- a/src/hasp_gpio.h +++ b/src/hasp_gpio.h @@ -1,3 +1,25 @@ +#ifndef HASP_GPIO_H +#define HASP_GPIO_H + #include "ArduinoJson.h" -void gpioSetup(); +#ifdef __cplusplus +extern "C" { +#endif + +void gpioSetup(void); +void IRAM_ATTR gpioLoop(void); + +enum lv_hasp_gpio_type_t { + HASP_GPIO_SWITCH = 0, + HASP_GPIO_BUTTON = 1, + HASP_GPIO_RELAY = 2, + HASP_GPIO_PWM = 3, + HASP_GPIO_BACKLIGHT = 4, +}; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif \ No newline at end of file From 80b1c0e6fa45470770d8aad04fa3746526efee51 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:16:17 +0200 Subject: [PATCH 15/23] Move from button to gpio --- include/hasp_conf.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/hasp_conf.h b/include/hasp_conf.h index 96b88a60..14366c88 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -22,10 +22,10 @@ #define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0) #define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM) -#define HASP_USE_EEPROM (HASP_HAS_FILESYSTEM) +#define HASP_USE_EEPROM 1 #define HASP_USE_SDCARD 0 -#define HASP_USE_BUTTON 1 +#define HASP_USE_GPIO 1 #define HASP_USE_QRCODE 1 #define HASP_USE_PNGDECODE 0 @@ -43,7 +43,6 @@ #if HASP_USE_SPIFFS>0 #if defined(ARDUINO_ARCH_ESP32) #include "SPIFFS.h" -#include "hasp_eeprom.h" #endif #include // Include the SPIFFS library #include "hasp_spiffs.h" From 81ad8654565f5fd96b40d4cf2acfcf7157d36fce Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:16:40 +0200 Subject: [PATCH 16/23] stm32 memory manager --- src/hasp_hal.cpp | 140 +++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 52 deletions(-) diff --git a/src/hasp_hal.cpp b/src/hasp_hal.cpp index 83eb07c7..83e7a363 100644 --- a/src/hasp_hal.cpp +++ b/src/hasp_hal.cpp @@ -107,56 +107,7 @@ String halGetResetInfo() #endif } - #ifdef __arm__ - // should use uinstd.h to define sbrk but Due causes a conflict - extern "C" char* sbrk(int incr); - #else // __ARM__ - extern char *__brkval; - #endif // __arm__ - - int freeMemory() { - char top; - #ifdef __arm__ - return &top - reinterpret_cast(sbrk(0)); - #elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151) - return &top - __brkval; - #else // __arm__ - return __brkval ? &top - __brkval : &top - __malloc_heap_start; - #endif // __arm__ - } -uint8_t halGetHeapFragmentation() -{ -#if defined(ARDUINO_ARCH_ESP32) - return (int8_t)(100.00f - (float)ESP.getMaxAllocHeap() * 100.00f / (float)ESP.getFreeHeap()); -#elif defined(ARDUINO_ARCH_ESP8266) - return ESP.getHeapFragmentation(); -#else - return 255; -#endif -} - -size_t halGetMaxFreeBlock() -{ -#if defined(ARDUINO_ARCH_ESP32) - return ESP.getMaxAllocHeap(); -#elif defined(ARDUINO_ARCH_ESP8266) - return ESP.getMaxFreeBlockSize(); -#else - return freeMemory(); -#endif -} - -size_t halGetFreeHeap(void) -{ -#if defined(ARDUINO_ARCH_ESP32) - return ESP.getFreeHeap(); -#elif defined(ARDUINO_ARCH_ESP8266) - return ESP.getFreeHeap(); -#else - return 1; -#endif -} String halGetCoreVersion() { @@ -193,8 +144,8 @@ String halGetChipModel() case CHIP_ESP32S2: model += F("ESP32-S2"); break; - #endif - default: +#endif + default: model = F("Unknown ESP"); } model += F(" rev"); @@ -202,4 +153,89 @@ String halGetChipModel() #endif // ESP32 return model; -} \ No newline at end of file +} + + +/*******************************/ +/* Memory Management Functions */ + +#if defined(STM32F4xx) +#include // for mallinfo() +#include // for sbrk() + +int freeHighMemory() +{ + char top; +#ifdef __arm__ + return &top - reinterpret_cast(sbrk(0)); +#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151) + return &top - __brkval; +#else // __arm__ + return __brkval ? &top - __brkval : &top - __malloc_heap_start; +#endif // __arm__ +} +#endif + +/* +extern char *fake_heap_end; // current heap start +extern char *fake_heap_start; // current heap end + +char* getHeapStart() { + return fake_heap_start; +} + +char* getHeapEnd() { + return (char*)sbrk(0); +} + +char* getHeapLimit() { + return fake_heap_end; +} + +int getMemUsed() { // returns the amount of used memory in bytes + struct mallinfo mi = mallinfo(); + return mi.uordblks; +} + +int getMemFree() { // returns the amount of free memory in bytes + struct mallinfo mi = mallinfo(); + return mi.fordblks + freeHighMemory(); +} */ + +size_t halGetMaxFreeBlock() +{ +#if defined(ARDUINO_ARCH_ESP32) + return ESP.getMaxAllocHeap(); +#elif defined(ARDUINO_ARCH_ESP8266) + return ESP.getMaxFreeBlockSize(); +#else + return freeHighMemory(); +#endif +} + +size_t halGetFreeHeap(void) +{ +#if defined(ARDUINO_ARCH_ESP32) + return ESP.getFreeHeap(); +#elif defined(ARDUINO_ARCH_ESP8266) + return ESP.getFreeHeap(); +#else + struct mallinfo chuncks = mallinfo(); + + // fordblks + // This is the total size of memory occupied by free (not in use) chunks. + + return chuncks.fordblks + freeHighMemory(); +#endif +} + +uint8_t halGetHeapFragmentation() +{ +#if defined(ARDUINO_ARCH_ESP32) + return (int8_t)(100.00f - (float)ESP.getMaxAllocHeap() * 100.00f / (float)ESP.getFreeHeap()); +#elif defined(ARDUINO_ARCH_ESP8266) + return ESP.getHeapFragmentation(); +#else + return (int8_t)(100.00f - (float)freeHighMemory() * 100.00f / (float)halGetFreeHeap()); +#endif +} From ec37e3d72a8207948ec286f28547a310042159a8 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:19:29 +0200 Subject: [PATCH 17/23] Move from button to gpio --- src/main.cpp | 64 ++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 020416c5..2bb65501 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,11 @@ #include "hasp_conf.h" // load first #include +#include "hasp_conf.h" #include "hasp_debug.h" -#include "hasp_spiffs.h" #include "hasp_config.h" #include "hasp_gui.h" #include "hasp.h" -#include "hasp_conf.h" #include "hasp_oobe.h" #include "hasp_gpio.h" @@ -23,7 +22,7 @@ void setup() /* Init Storage */ #if HASP_USE_EEPROM -// eepromSetup(); // Don't start at boot, only at write + eepromSetup(); // Don't start at boot, only at write #endif #if HASP_USE_SPIFFS @@ -44,7 +43,10 @@ void setup() ***************************/ debugSetup(); gpioSetup(); + +#if HASP_USE_GPIO guiSetup(); +#endif #if HASP_USE_WIFI wifiSetup(); @@ -76,10 +78,6 @@ void setup() #endif // WIFI -#if HASP_USE_BUTTON - buttonSetup(); -#endif - #if HASP_USE_TASMOTA_SLAVE slaveSetup(); #endif @@ -90,15 +88,21 @@ void setup() void loop() { /* Storage Loops */ +/* #if HASP_USE_EEPROM - eepromLoop(); -#endif - // spiffsLoop(); -#if HASP_USE_SDCARD - // sdcardLoop(); + // eepromLoop(); // Not used #endif - // configLoop(); +#if HASP_USE_SPIFFS + // spiffsLoop(); // Not used +#endif + +#if HASP_USE_SDCARD + // sdcardLoop(); // Not used +#endif + + // configLoop(); // Not used +*/ /* Graphics Loops */ // tftLoop(); @@ -107,6 +111,10 @@ void loop() /* Application Loops */ // haspLoop(); +#if HASP_USE_GPIO + gpioLoop(); +#endif + /* Network Services Loops */ #if HASP_USE_WIFI @@ -126,10 +134,6 @@ void loop() mdnsLoop(); #endif // MDNS -#if HASP_USE_BUTTON - buttonLoop(); -#endif // BUTTON - #if HASP_USE_OTA otaLoop(); #endif // OTA @@ -140,7 +144,9 @@ void loop() slaveLoop(); #endif // TASMOTASLAVE - // Every Second Loop + // digitalWrite(HASP_OUTPUT_PIN, digitalRead(HASP_INPUT_PIN)); // sets the LED to the button's value + + /* Timer Loop */ if(millis() - mainLastLoopTime >= 1000) { /* Run Every Second */ #if HASP_USE_OTA @@ -149,27 +155,25 @@ void loop() debugEverySecond(); /* Run Every 5 Seconds */ - if(mainLoopCounter == 0 || mainLoopCounter == 4) { +#if HASP_USE_WIFI + if(mainLoopCounter == 0 || mainLoopCounter == 5) { + isConnected = wifiEvery5Seconds(); #if HASP_USE_HTTP httpEvery5Seconds(); #endif - -#if HASP_USE_WIFI - isConnected = wifiEvery5Seconds(); - #if HASP_USE_MQTT mqttEvery5Seconds(isConnected); -#endif - #endif } +#endif // Wifi - /* Update counters */ + /* Reset loop counter every 10 seconds */ + if(mainLoopCounter >= 9) { + mainLoopCounter = 0; + } else { + mainLoopCounter++; + } mainLastLoopTime += 1000; - mainLoopCounter++; - if(mainLoopCounter >= 10) { - mainLoopCounter = 0; - } } delay(3); From c4d85bf2e4eb175bb0c0ce5649388b694a4195c6 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:20:39 +0200 Subject: [PATCH 18/23] Code clean-up --- src/hasp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hasp.h b/src/hasp.h index beda81e2..169871a9 100644 --- a/src/hasp.h +++ b/src/hasp.h @@ -99,10 +99,10 @@ void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event); * MACROS **********************/ -#endif /*LV_USE_DEMO*/ +#endif /*HASP_USE_APP*/ #ifdef __cplusplus } /* extern "C" */ #endif -#endif /*DEMO_H*/ +#endif /*HASP_H*/ From d26c0c0200fd91714c947df20409dd41b3c88536 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:21:50 +0200 Subject: [PATCH 19/23] Add led brightness --- src/hasp_attribute.cpp | 56 +++++++++++++++++++++++++----------------- src/hasp_attribute.h | 1 + 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/hasp_attribute.cpp b/src/hasp_attribute.cpp index 43a7aa6f..de69758f 100644 --- a/src/hasp_attribute.cpp +++ b/src/hasp_attribute.cpp @@ -84,13 +84,6 @@ static lv_color_t haspPayloadToColor(const char * payload) case 7: if(!strcmp_P(payload, PSTR("magenta"))) return haspLogColor(LV_COLOR_MAGENTA); - /* HEX format #rrggbb or #rrggbbaa */ - int r, g, b, a; - if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x%2x", &r, &g, &b, &a) == 4) { - return haspLogColor(LV_COLOR_MAKE(r, g, b)); - } else if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x", &r, &g, &b) == 3) { - return haspLogColor(LV_COLOR_MAKE(r, g, b)); - } default: // if(!strcmp_P(payload, PSTR("darkblue"))) return haspLogColor(LV_COLOR_MAKE(0, 51, 102)); // if(!strcmp_P(payload, PSTR("lightblue"))) return haspLogColor(LV_COLOR_MAKE(46, 203, @@ -98,6 +91,14 @@ static lv_color_t haspPayloadToColor(const char * payload) break; } + /* HEX format #rrggbb or #rrggbbaa */ + int r, g, b, a; + if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x%2x", &r, &g, &b, &a) == 4) { + return haspLogColor(LV_COLOR_MAKE(r, g, b)); + } else if(*payload == '#' && sscanf(payload + 1, "%2x%2x%2x", &r, &g, &b) == 3) { + return haspLogColor(LV_COLOR_MAKE(r, g, b)); + } + /* 16-bit RGB565 Color Scheme*/ if(only_digits(payload)) { uint16_t c = atoi(payload); @@ -582,23 +583,23 @@ static void hasp_process_obj_attribute_val(lv_obj_t * obj, const char * attr, co lv_dropdown_set_selected(obj, val); return; } else if(check_obj_type(objtype, LV_HASP_LMETER)) { - lv_linemeter_set_value(obj, intval); - return; + return update ? lv_linemeter_set_value(obj, intval) : hasp_out_int(obj, attr, lv_linemeter_get_value(obj)); } else if(check_obj_type(objtype, LV_HASP_SLIDER)) { - lv_slider_set_value(obj, intval, LV_ANIM_ON); - return; + return update ? lv_slider_set_value(obj, intval, LV_ANIM_ON) + : hasp_out_int(obj, attr, lv_slider_get_value(obj)); } else if(check_obj_type(objtype, LV_HASP_LED)) { - lv_led_set_bright(obj, (uint8_t)val); - return; + if(update) { + return is_true(payload) ? lv_led_on(obj) : lv_led_off(obj); + } else { + // return hasp_out_int(obj, attr, lv_led_get_state(obj)); + } } else if(check_obj_type(objtype, LV_HASP_GAUGE)) { - lv_gauge_set_value(obj, 0, intval); - return; + return update ? lv_gauge_set_value(obj, 0, intval) : hasp_out_int(obj, attr, lv_gauge_get_value(obj, 0)); } else if(check_obj_type(objtype, LV_HASP_ROLLER)) { lv_roller_set_selected(obj, val, LV_ANIM_ON); return; } else if(check_obj_type(objtype, LV_HASP_BAR)) { - lv_bar_set_value(obj, intval, LV_ANIM_OFF); - return; + return update ? lv_bar_set_value(obj, intval, LV_ANIM_ON) : hasp_out_int(obj, attr, lv_bar_get_value(obj)); } else if(check_obj_type(objtype, LV_HASP_CPICKER)) { return update ? (void)lv_cpicker_set_color(obj, haspPayloadToColor(payload)) : hasp_out_color(obj, attr, lv_cpicker_get_color(obj)); @@ -781,6 +782,16 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char } break; // not a options object + case ATTR_BRIGHTNESS: + if(check_obj_type(obj, LV_HASP_LED)) { + if(update) { + lv_led_set_bright(obj, (uint8_t)val); + } else { + hasp_out_int(obj, attr, lv_led_get_bright(obj)); + } + return; + } + // default: // hasp_local_style_attr(obj, attr, payload, update); } @@ -794,9 +805,10 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char * **************************/ static inline bool is_true(const char * s) { - return (!strcmp_P(s, PSTR("true")) || !strcmp_P(s, PSTR("TRUE")) || !strcmp_P(s, PSTR("1")) || + return (!strcmp_P(s, PSTR("true")) || !strcmp_P(s, PSTR("TRUE")) || !strcmp_P(s, PSTR("True")) || !strcmp_P(s, PSTR("on")) || !strcmp_P(s, PSTR("ON")) || !strcmp_P(s, PSTR("On")) || - !strcmp_P(s, PSTR("yes")) || !strcmp_P(s, PSTR("YES")) || !strcmp_P(s, PSTR("Yes"))); + !strcmp_P(s, PSTR("yes")) || !strcmp_P(s, PSTR("YES")) || !strcmp_P(s, PSTR("Yes")) || + !strcmp_P(s, PSTR("1"))); } static inline bool only_digits(const char * s) @@ -808,17 +820,17 @@ static inline bool only_digits(const char * s) return strlen(s) == digits; } -void hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val) +void inline hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val) { hasp_send_obj_attribute_int(obj, attr, val); } -void hasp_out_str(lv_obj_t * obj, const char * attr, const char * data) +void inline hasp_out_str(lv_obj_t * obj, const char * attr, const char * data) { hasp_send_obj_attribute_str(obj, attr, data); } -void hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color) +void inline hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color) { hasp_send_obj_attribute_color(obj, attr, color); } diff --git a/src/hasp_attribute.h b/src/hasp_attribute.h index 6171e1e3..e2fc932d 100644 --- a/src/hasp_attribute.h +++ b/src/hasp_attribute.h @@ -212,6 +212,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t) #define ATTR_Y 121 #define ATTR_W 119 #define ATTR_H 104 +#define ATTR_BRIGHTNESS 10 // LED #define ATTR_OPTIONS 29886 #define ATTR_ENABLED 28193 #define ATTR_OPACITY 10155 From bf4c8e975a363952c9091ff1af055fabd6282e37 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:22:29 +0200 Subject: [PATCH 20/23] Code clean-up --- src/hasp_debug.cpp | 6 +++--- src/hasp_dispatch.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp index 449c1e3b..8448eb98 100644 --- a/src/hasp_debug.cpp +++ b/src/hasp_debug.cpp @@ -232,8 +232,8 @@ static void debugPrintTimestamp(int level, Print * _logOutput) _logOutput->printf(PSTR("%03lu]"), millis() % 1000); } else */ { - //_logOutput->printf(PSTR("[%20.3f]"), (float)millis() / 1000); - _logOutput->printf(PSTR("[%20d]"), millis() ); + uint32_t msecs = millis(); + _logOutput->printf(PSTR("[%16d.%03d]"), msecs/1000, msecs%1000 ); } } @@ -333,7 +333,7 @@ void debugPreSetup(JsonObject settings) if(baudrate == 0) baudrate = SERIAL_SPEED; if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */ -#ifdef STM32_CORE_VERSION_MAJOR +#if defined(STM32F4xx) #ifndef STM32_SERIAL1 // Define what Serial port to use for log output Serial.setRx(PA3); // User Serial2 Serial.setTx(PA2); diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp index 43156964..132966f7 100644 --- a/src/hasp_dispatch.cpp +++ b/src/hasp_dispatch.cpp @@ -52,7 +52,7 @@ void dispatchOutput(int output, bool state) #if defined(ARDUINO_ARCH_ESP32) ledcWrite(99, state ? 1023 : 0); // ledChannel and value -#elif defined(STM32_CORE_VERSION) +#elif defined(STM32F4xx) digitalWrite(HASP_OUTPUT_PIN, state); #else analogWrite(pin, state ? 1023 : 0); @@ -98,7 +98,7 @@ void dispatchAttribute(String strTopic, const char * payload) { if(strTopic.startsWith("p[")) { dispatchButtonAttribute(strTopic, payload); - + } else if(strTopic == F("page")) { dispatchPage(payload); From c1996a5eaffc468257958f1308cc2899e1ca3957 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:23:13 +0200 Subject: [PATCH 21/23] Add eeprom support --- src/hasp_config.cpp | 116 +++++++++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 33 deletions(-) diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp index 8e4a0ada..3e62e41f 100644 --- a/src/hasp_config.cpp +++ b/src/hasp_config.cpp @@ -1,6 +1,7 @@ #include "Arduino.h" -#include "ArduinoJson.h" #include "ArduinoLog.h" +#include "ArduinoJson.h" +#include "StreamUtils.h" #include "hasp_config.h" #include "hasp_debug.h" @@ -13,13 +14,13 @@ #include "hasp_conf.h" -#if HASP_USE_SPIFFS>0 +#if HASP_USE_SPIFFS > 0 #include // Include the SPIFFS library #if defined(ARDUINO_ARCH_ESP32) #include "SPIFFS.h" #endif #endif -#if HASP_USE_EEPROM>0 +#if HASP_USE_EEPROM > 0 #include "EEPROM.h" #endif @@ -72,13 +73,17 @@ void configStartDebug(bool setupdebug, String & configFile) { if(setupdebug) { debugStart(); // Debug started, now we can use it; HASP header sent +#if HASP_USE_SPIFFS > 0 Log.notice(F("FILE: [SUCCESS] SPI flash FS mounted")); -#if HASP_USE_SPIFFS>0 spiffsInfo(); spiffsList(); #endif } +#if HASP_USE_SPIFFS > 0 Log.notice(F("CONF: Loading %s"), configFile.c_str()); +#else + Log.notice(F("CONF: reading EEPROM")); +#endif } void configGetConfig(JsonDocument & settings, bool setupdebug = false) @@ -86,9 +91,10 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false) String configFile((char *)0); configFile.reserve(128); configFile = String(FPSTR(HASP_CONFIG_FILE)); + DeserializationError error; -#if HASP_USE_SPIFFS>0 - File file = SPIFFS.open(configFile, "r"); +#if HASP_USE_SPIFFS > 0 + File file = SPIFFS.open(configFile, "r"); if(file) { size_t size = file.size(); @@ -97,7 +103,7 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false) return; } - DeserializationError error = deserializeJson(settings, file); + error = deserializeJson(settings, file); if(!error) { file.close(); @@ -121,17 +127,26 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false) return; } } +#else + +#if HASP_USE_EEPROM > 0 + EepromStream eepromStream(0, 1024); + error = deserializeJson(settings, eepromStream); +#endif + #endif // File does not exist or error reading file if(setupdebug) { debugPreSetup(settings[F("debug")]); } - configStartDebug(setupdebug, configFile); - Log.error(F("CONF: Failed to load %s"), configFile.c_str()); -} +#if HASP_USE_SPIFFS > 0 + Log.error(F("CONF: Failed to load %s"), configFile.c_str()); +#endif +} +/* void configBackupToEeprom() { #if HASP_USE_SPIFFS>0 @@ -160,10 +175,9 @@ void configBackupToEeprom() } #endif } - +*/ void configWriteConfig() { -#if HASP_USE_SPIFFS>0 String configFile((char *)0); configFile.reserve(128); configFile = String(FPSTR(HASP_CONFIG_FILE)); @@ -253,6 +267,7 @@ void configWriteConfig() // changed |= otaGetConfig(settings[F("ota")].as()); if(writefile) { +#if HASP_USE_SPIFFS > 0 File file = SPIFFS.open(configFile, "w"); if(file) { Log.notice(F("CONF: Writing %s"), configFile.c_str()); @@ -260,36 +275,70 @@ void configWriteConfig() file.close(); if(size > 0) { Log.verbose(F("CONF: [SUCCESS] Saved %s"), configFile.c_str()); - configBackupToEeprom(); - return; + // configBackupToEeprom(); + } else { + Log.error(F("CONF: Failed to write %s"), configFile.c_str()); } + } else { + Log.error(F("CONF: Failed to write %s"), configFile.c_str()); } +#endif - Log.error(F("CONF: Failed to write %s"), configFile.c_str()); + // Method 1 + // Log.verbose(F("CONF: Writing to EEPROM")); + // EepromStream eepromStream(0, 1024); + // WriteBufferingStream bufferedWifiClient{eepromStream, 512}; + // serializeJson(doc, bufferedWifiClient); + // bufferedWifiClient.flush(); // <- OPTIONAL + // eepromStream.flush(); // (for ESP) + +#if defined(STM32F4xx) + // Method 2 + Log.verbose(F("CONF: Writing to EEPROM")); + char buffer[1024 + 128]; + size_t size = serializeJson(doc, buffer, sizeof(buffer)); + if(size > 0) { + uint16_t i; + for(i = 0; i < size; i++) eeprom_buffered_write_byte(i, buffer[i]); + eeprom_buffered_write_byte(i, 0); + eeprom_buffer_flush(); + Log.verbose(F("CONF: [SUCCESS] Saved EEPROM")); + } else { + Log.error(F("CONF: Failed to save config to EEPROM")); + } +#endif } else { - Log.notice(F("CONF: Configuration was not changed")); + Log.notice(F("CONF: Configuration did not change")); } -#endif } void configSetup() { -#if HASP_USE_SPIFFS>0 - if(!SPIFFS.begin()) { -#endif - -#if HASP_USE_SPIFFS>0 - } else { -#endif - DynamicJsonDocument settings(1024 + 128); - Serial.print(__FILE__); - Serial.println(__LINE__); + DynamicJsonDocument settings(1024 + 128); - configGetConfig(settings, true); + for(uint8_t i = 0; i < 2; i++) { + Serial.print(__FILE__); + Serial.println(__LINE__); - Log.error(F("FILE: SPI flash init failed. Unable to mount FS: Using default settings...")); -#if HASP_USE_SPIFFS>0 + if(i == 0) { +#if HASP_USE_SPIFFS > 0 + EepromStream eepromStream(0, 2048); + DeserializationError error = deserializeJson(settings, eepromStream); +#else + continue; +#endif + } else { +#if HASP_USE_SPIFFS > 0 + if(!SPIFFS.begin()) { + Log.error(F("FILE: SPI flash init failed. Unable to mount FS: Using default settings...")); + return; + } +#endif + configGetConfig(settings, true); + } + + //#if HASP_USE_SPIFFS > 0 Log.verbose(F("Loading debug settings")); debugSetConfig(settings[F("debug")]); Log.verbose(F("Loading GUI settings")); @@ -317,10 +366,11 @@ void configSetup() Log.verbose(F("Loading HTTP settings")); httpSetConfig(settings[F("http")]); #endif -#endif +#endif // Wifi + // } + Log.notice(F("User configuration loaded")); } - Log.notice(F("User configuration loaded")); -#endif + //#endif } void configOutput(const JsonObject & settings) From 233edece248978e3787f39736c696e6445d2bc92 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:53:18 +0200 Subject: [PATCH 22/23] Code clean-up --- src/hasp_tft.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hasp_tft.cpp b/src/hasp_tft.cpp index b8f07ed0..ba8f74f8 100644 --- a/src/hasp_tft.cpp +++ b/src/hasp_tft.cpp @@ -98,6 +98,7 @@ void tftShowConfig(TFT_eSPI & tft) #if defined(ARDUINO_ARCH_ESP8266) Log.verbose(F("TFT: SPI overlap : %s"), (tftSetup.overlap == 1) ? PSTR("Yes") : PSTR("No")); #endif + if(tftSetup.tft_driver != 0xE9D) // For ePaper displays the size is defined in the sketch { Log.verbose(F("TFT: Driver : %s"), tftDriverName().c_str()); // tftSetup.tft_driver); From 51f34ae3ebaa5c0abeee70dd8e5ded3e547ecb38 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 2 May 2020 00:53:59 +0200 Subject: [PATCH 23/23] Add StreamUtils and TasmotaSlave --- platformio.ini | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index 3c9bec90..3fe9fa11 100644 --- a/platformio.ini +++ b/platformio.ini @@ -47,11 +47,13 @@ lib_deps = ;TFT_eSPI@^1.4.20 ; Tft SPI drivers PubSubClient@^2.7.0 ; MQTT client ArduinoJson@^6.15.1,>6.15.0 ; needs at least 6.15.0 + StreamUtils@^1.4.0 Syslog@^2.0.0 AceButton@^1.4.0 ;AsyncTCP ;https://github.com/me-no-dev/ESPAsyncWebServer/archive/master.zip ;https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip + https://github.com/andrethomas/TasmotaSlave.git lib_ignore = https://github.com/littlevgl/lvgl.git @@ -67,6 +69,7 @@ build_flags = -D SPIFFS_TEMPORAL_FD_CACHE ; speedup opening recent files -D ARDUINOJSON_DECODE_UNICODE=1 ; for utf-8 symbols -D ARDUINOJSON_ENABLE_PROGMEM=1 ; for PROGMEM arguments + -D STREAMUTILS_ENABLE_EEPROM=1 ; for STM32, it also supports EEPROM ;-D DISABLE_LOGGING -I include ; include lv_conf.h and hasp_conf.h ${override.build_flags} @@ -89,6 +92,7 @@ stm32_flags= ${env.build_flags} -D IRAM_ATTR= ; No IRAM_ATTR available on STM32 -D STM32 + -D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed ; -- By default there are no ${override.build_flags} set ; -- to use it, copy platformio_override.ini from the template @@ -145,8 +149,9 @@ build_flags = -D TFT_BCKL=-1 ;None, configurable via web UI (e.g. 2 for D4) -D TOUCH_CS=PC4 ;NC -D TFT_RST=-1 ;D4 - -D HASP_OUTPUT_PIN=PA1 ; User LED D2 on DevEBox board - -D HASP_INPUT_PIN=PA0 ; User Button K1 on DevEBox board + -D HASP_OUTPUT_PIN=PE0 ; User LED D2 on DevEBox board + -D HASP_INPUT_PIN=PD15 ; User Button K1 on DevEBox board + -D STM32_SERIAL1 ; Set this option to use Serial1 as default sersial port, leave out if using Serial2 lib_deps = ${env.lib_deps}