mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
commit
0e7448fb07
@ -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 <FS.h> // Include the SPIFFS library
|
||||
#include "hasp_spiffs.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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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__);
|
||||
|
@ -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}
|
||||
@ -88,6 +91,8 @@ esp32_flags=
|
||||
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
|
||||
@ -144,7 +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 STM32
|
||||
-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}
|
||||
|
@ -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);
|
||||
@ -101,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*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -1,75 +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;
|
||||
}
|
||||
dispatch_button(button->getId(), buffer);
|
||||
}
|
||||
|
||||
void buttonSetup(void)
|
||||
{
|
||||
button[0] = new AceButton(HASP_INPUT_PIN, LOW, 0);
|
||||
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);
|
||||
|
||||
// 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 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();
|
||||
}
|
||||
}
|
@ -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
|
@ -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,21 +14,16 @@
|
||||
|
||||
#include "hasp_conf.h"
|
||||
|
||||
#if HASP_USE_SPIFFS>0
|
||||
#if HASP_USE_SPIFFS > 0
|
||||
#include <FS.h> // 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
|
||||
|
||||
#ifndef FPSTR
|
||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
||||
#endif
|
||||
|
||||
|
||||
void confDebugSet(const char * name)
|
||||
{
|
||||
/*char buffer[128];
|
||||
@ -77,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)
|
||||
@ -91,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();
|
||||
@ -102,7 +103,7 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
|
||||
return;
|
||||
}
|
||||
|
||||
DeserializationError error = deserializeJson(settings, file);
|
||||
error = deserializeJson(settings, file);
|
||||
if(!error) {
|
||||
file.close();
|
||||
|
||||
@ -126,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
|
||||
@ -165,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));
|
||||
@ -258,6 +267,7 @@ void configWriteConfig()
|
||||
// changed |= otaGetConfig(settings[F("ota")].as<JsonObject>());
|
||||
|
||||
if(writefile) {
|
||||
#if HASP_USE_SPIFFS > 0
|
||||
File file = SPIFFS.open(configFile, "w");
|
||||
if(file) {
|
||||
Log.notice(F("CONF: Writing %s"), configFile.c_str());
|
||||
@ -265,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"));
|
||||
@ -322,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)
|
||||
|
@ -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 */
|
||||
{
|
||||
uint32_t msecs = millis();
|
||||
_logOutput->printf(PSTR("[%16d.%03d]"), msecs/1000, msecs%1000 );
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,9 +331,9 @@ void debugPreSetup(JsonObject settings)
|
||||
|
||||
uint32_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as<uint32_t>() * 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
|
||||
#if defined(STM32F4xx)
|
||||
#ifndef STM32_SERIAL1 // Define what Serial port to use for log output
|
||||
Serial.setRx(PA3); // User Serial2
|
||||
Serial.setTx(PA2);
|
||||
@ -338,7 +341,7 @@ void debugPreSetup(JsonObject settings)
|
||||
#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);
|
||||
|
@ -48,10 +48,11 @@ 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
|
||||
#elif defined(STM32_CORE_VERSION)
|
||||
#elif defined(STM32F4xx)
|
||||
digitalWrite(HASP_OUTPUT_PIN, state);
|
||||
#else
|
||||
analogWrite(pin, state ? 1023 : 0);
|
||||
@ -97,6 +98,7 @@ void dispatchAttribute(String strTopic, const char * payload)
|
||||
{
|
||||
if(strTopic.startsWith("p[")) {
|
||||
dispatchButtonAttribute(strTopic, payload);
|
||||
|
||||
} else if(strTopic == F("page")) {
|
||||
dispatchPage(payload);
|
||||
|
||||
@ -192,7 +194,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());
|
||||
@ -303,6 +305,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
|
||||
#if HASP_USE_TASMOTA_SLAVE
|
||||
slave_send_input(id, event);
|
||||
|
@ -1,49 +1,17 @@
|
||||
#include <Arduino.h>
|
||||
#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);
|
||||
}
|
||||
{}
|
@ -1,14 +1,166 @@
|
||||
#include <Arduino.h>
|
||||
#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_PULLDOWN);
|
||||
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
|
||||
*/
|
||||
}
|
@ -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
|
@ -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)
|
||||
{
|
||||
@ -628,6 +620,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 +672,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);
|
||||
@ -811,10 +815,10 @@ void guiSetup()
|
||||
|
||||
void IRAM_ATTR guiLoop()
|
||||
{
|
||||
#ifdef STM32_CORE_VERSION_MAJOR
|
||||
#if defined(STM32F4xx)
|
||||
tick.update();
|
||||
|
||||
while(Serial.available()) {
|
||||
while(Serial.available()) {
|
||||
char ch = Serial.read();
|
||||
Serial.print(ch);
|
||||
if (ch == 13 ||ch == 10) {
|
||||
@ -992,6 +996,7 @@ bool guiSetConfig(const JsonObject & settings)
|
||||
Log.notice(F("First Touch Calibration enabled"));
|
||||
oobeSetAutoCalibrate(true);
|
||||
}
|
||||
|
||||
if (status) tft.setTouch(calData);
|
||||
changed |= status;
|
||||
}
|
||||
|
140
src/hasp_hal.cpp
140
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<char*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************/
|
||||
/* Memory Management Functions */
|
||||
|
||||
#if defined(STM32F4xx)
|
||||
#include <malloc.h> // for mallinfo()
|
||||
#include <unistd.h> // for sbrk()
|
||||
|
||||
int freeHighMemory()
|
||||
{
|
||||
char top;
|
||||
#ifdef __arm__
|
||||
return &top - reinterpret_cast<char *>(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
|
||||
}
|
||||
|
@ -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);
|
||||
|
62
src/main.cpp
62
src/main.cpp
@ -1,12 +1,11 @@
|
||||
#include "hasp_conf.h" // load first
|
||||
#include <Arduino.h>
|
||||
|
||||
#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();
|
||||
@ -106,9 +110,9 @@ void loop()
|
||||
/* Application Loops */
|
||||
// haspLoop();
|
||||
|
||||
#if HASP_USE_BUTTON
|
||||
buttonLoop();
|
||||
#endif // BUTTON
|
||||
#if HASP_USE_GPIO
|
||||
gpioLoop();
|
||||
#endif
|
||||
|
||||
/* Network Services Loops */
|
||||
#if HASP_USE_WIFI
|
||||
@ -139,7 +143,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
|
||||
@ -148,27 +154,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user