Merge pull request #2 from fvanroie/0.1.0-dev

0.1.0 dev
This commit is contained in:
arovak 2020-05-06 20:08:42 +02:00 committed by GitHub
commit ae52a5f746
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1285 additions and 1310 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
.git .git
.pio .pio
data/* data/*
src/user_setups/active/*
src/user_config_override.h src/user_config_override.h
platformio_override.ini platformio_override.ini
user_setups/active/* user_setups/active/*

View File

@ -19,14 +19,14 @@ This version also adds ESP32 and STM32 support to take advantage of the addition
| SPI display | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes | SPI display | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| Parallel display | :x: no | :white_check_mark: yes | :white_check_mark: yes | Parallel display | :x: no | :white_check_mark: yes | :white_check_mark: yes
| PWM Screen dimming | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes | PWM Screen dimming | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| Maximum Page Count | 4 | 12 | | Maximum Page Count | 4 | 12 | 12
| Object Types / Widgets | 14 | 15 | 15 | Object Types / Widgets | 14 | 15 | 15
| Dynamic Objects | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes | Dynamic Objects | :white_check_mark: yes | :white_check_mark: yes | :white_check_mark: yes
| [Lvgl Theme Support][3] | basic only | all themes | tbd | [Lvgl Theme Support][3] | basic only | all themes | tbd
| [Custom .zi V5 font][4] | :white_check_mark: yes (latin1) | :white_check_mark: yes (latin1) | no | [Custom .zi V5 font][4] | :white_check_mark: yes (latin1) | :white_check_mark: yes (latin1) | no
| [FontAwesome Icons][5] | :white_check_mark: 1300+ | :white_check_mark: 1300+ | no | [FontAwesome Icons][5] | :white_check_mark: 1300+ | :white_check_mark: 1300+ | no
| PNG images | :x: no | :grey_question: tbd | :grey_question: tbd | PNG images | :x: no | :grey_question: tbd | :grey_question: tbd
| Network | :white_check_mark: Wifi | :white_check_mark: Wifi | :grey_question: tbd | Network | :white_check_mark: Wifi | :white_check_mark: Wifi | :white_check_mark: Ethernet
## Cloning ## Cloning

View File

@ -7,40 +7,82 @@
#define HASP_USE_APP 1 #define HASP_USE_APP 1
/* Network */ /* Network Services */
#define HASP_HAS_NETWORK (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0) #define HASP_HAS_NETWORK (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
#ifndef HASP_USE_OTA
#define HASP_USE_OTA (HASP_HAS_NETWORK) #define HASP_USE_OTA (HASP_HAS_NETWORK)
#define HASP_USE_WIFI (HASP_HAS_NETWORK)
#define HASP_USE_MQTT (HASP_HAS_NETWORK)
#define HASP_USE_HTTP (HASP_HAS_NETWORK)
#define HASP_USE_MDNS (HASP_HAS_NETWORK)
#define HASP_USE_SYSLOG (HASP_HAS_NETWORK)
#define HASP_USE_TELNET (HASP_HAS_NETWORK)
/* Filesystem */
#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32>0 || ARDUINO_ARCH_ESP8266>0)
#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
#define HASP_USE_EEPROM 1
#define HASP_USE_SDCARD 0
#define HASP_USE_GPIO 1
#define HASP_USE_QRCODE 1
#define HASP_USE_PNGDECODE 0
#define HASP_NUM_INPUTS 3 // Buttons
#define HASP_NUM_OUTPUTS 3
#if defined(ARDUINO_ARCH_ESP32)
#define HASP_NUM_PAGES 12
#else
#define HASP_NUM_PAGES 4
#endif #endif
#ifndef HASP_USE_WIFI
#define HASP_USE_WIFI (HASP_HAS_NETWORK)
#endif
#if HASP_USE_SPIFFS>0 #ifndef HASP_USE_MQTT
#define HASP_USE_MQTT 1
#endif
#ifndef HASP_USE_HTTP
#define HASP_USE_HTTP 1
#endif
#ifndef HASP_USE_MDNS
#define HASP_USE_MDNS (HASP_HAS_NETWORK)
#endif
#ifndef HASP_USE_SYSLOG
#define HASP_USE_SYSLOG (HASP_HAS_NETWORK)
#endif
#ifndef HASP_USE_TELNET
#define HASP_USE_TELNET 0
#endif
/* Filesystem */
#define HASP_HAS_FILESYSTEM (ARDUINO_ARCH_ESP32 > 0 || ARDUINO_ARCH_ESP8266 > 0)
#ifndef HASP_USE_SPIFFS
#define HASP_USE_SPIFFS (HASP_HAS_FILESYSTEM)
#endif
#ifndef HASP_USE_EEPROM
#define HASP_USE_EEPROM 1
#endif
#ifndef HASP_USE_SDCARD
#define HASP_USE_SDCARD 0
#endif
#ifndef HASP_USE_GPIO
#define HASP_USE_GPIO 1
#endif
#ifndef HASP_USE_QRCODE
#define HASP_USE_QRCODE 1
#endif
#ifndef HASP_USE_PNGDECODE
#define HASP_USE_PNGDECODE 0
#endif
#ifndef HASP_NUM_INPUTS
#define HASP_NUM_INPUTS 3 // Buttons
#endif
#ifndef HASP_NUM_OUTPUTS
#define HASP_NUM_OUTPUTS 3
#endif
#ifndef HASP_NUM_PAGES
#if defined(ARDUINO_ARCH_ESP8266)
#define HASP_NUM_PAGES 4
#else
#define HASP_NUM_PAGES 12
#endif
#endif
/* Includes */
#if HASP_USE_SPIFFS > 0
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h" #include "SPIFFS.h"
#endif #endif
@ -48,52 +90,56 @@
#include "hasp_spiffs.h" #include "hasp_spiffs.h"
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
// #include "lv_zifont.h" #include "lv_zifont.h"
#endif
#endif #endif
#endif // SPIFFS
#if HASP_USE_EEPROM>0 #if HASP_USE_EEPROM > 0
#include "hasp_eeprom.h" #include "hasp_eeprom.h"
#endif #endif
#if HASP_USE_WIFI>0 #if HASP_USE_WIFI > 0
#include "hasp_wifi.h" #include "hasp_wifi.h"
#endif #endif
#if HASP_USE_MQTT>0 #if HASP_USE_MQTT > 0
#include "hasp_mqtt.h" #include "hasp_mqtt.h"
#endif #endif
#if HASP_USE_HTTP>0 #if HASP_USE_HTTP > 0
#include "hasp_http.h" #include "hasp_http.h"
#endif #endif
#if HASP_USE_TELNET>0 #if HASP_USE_TELNET > 0
#include "hasp_telnet.h" #include "hasp_telnet.h"
#endif #endif
#if HASP_USE_MDNS>0 #if HASP_USE_MDNS > 0
#include "hasp_mdns.h" #include "hasp_mdns.h"
#endif #endif
#if HASP_USE_BUTTON>0 #if HASP_USE_BUTTON > 0
#include "hasp_button.h" #include "hasp_button.h"
#endif #endif
#if HASP_USE_OTA>0 #if HASP_USE_OTA > 0
#include "hasp_ota.h" #include "hasp_ota.h"
#endif #endif
#if HASP_USE_TASMOTA_SLAVE>0 #if HASP_USE_TASMOTA_SLAVE > 0
#include "hasp_slave.h" #include "hasp_slave.h"
#endif #endif
#if HASP_USE_ETHERNET>0 #if HASP_USE_ETHERNET > 0
#include "hasp_ethernet.h" #include "hasp_ethernet.h"
#endif #endif
#endif
#ifndef FPSTR #ifndef FPSTR
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer)) #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#endif #endif
#ifndef PGM_P
#define PGM_P const char *
#endif
#endif // HASP_CONF_H

View File

@ -0,0 +1,13 @@
/* Include the normal default core configuration */
#include "stm32f4xx_hal_conf_default.h"
/* Remove the default PHY address */
#ifdef LAN8742A_PHY_ADDRESS
#undef LAN8742A_PHY_ADDRESS
#endif
/* Section 2: PHY configuration section */
/* Redefine LAN8742A PHY Address*/
#ifndef LAN8742A_PHY_ADDRESS
#define LAN8742A_PHY_ADDRESS 0x01U //HASP_PHY_ADDRESS
#endif

@ -1 +1 @@
Subproject commit 1cf1721aa3e693ae37ea1809b7b7656b7c0cf85b Subproject commit 5f739643f4b22254f5742504fcda3b7de50fb88b

View File

@ -24,6 +24,8 @@ extra_configs =
default_envs = default_envs =
; Uncomment the needed environments in platformio_override.ini ; Uncomment the needed environments in platformio_override.ini
; You can also create new environments in in platformio_override.ini ; You can also create new environments in in platformio_override.ini
DevEBox_STM32F4xx
black_f407vg
${override.extra_default_envs} ${override.extra_default_envs}
; -- Location of the configuration files ; -- Location of the configuration files
@ -95,6 +97,7 @@ stm32_flags=
-D IRAM_ATTR= ; No IRAM_ATTR available on STM32 -D IRAM_ATTR= ; No IRAM_ATTR available on STM32
-D STM32 -D STM32
-D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed -D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages
; -- By default there are no ${override.build_flags} set ; -- By default there are no ${override.build_flags} set
; -- to use it, copy platformio_override.ini from the template ; -- to use it, copy platformio_override.ini from the template

View File

@ -3,8 +3,9 @@
*********************/ *********************/
#include "hasp_conf.h" #include "hasp_conf.h"
#include <Arduino.h> #include <Arduino.h>
#include "ArduinoJson.h"
#include "ArduinoLog.h" #include "ArduinoLog.h"
#include "ArduinoJson.h"
#include "StreamUtils.h"
#include "lvgl.h" #include "lvgl.h"
#include "lv_conf.h" #include "lv_conf.h"
@ -24,6 +25,8 @@
#include "hasp_attribute.h" #include "hasp_attribute.h"
#include "hasp.h" #include "hasp.h"
#include "EEPROM.h"
//#if LV_USE_HASP //#if LV_USE_HASP
/********************* /*********************
@ -955,6 +958,15 @@ void haspLoadPage(const char * pages)
file.close(); file.close();
Log.notice(F("HASP: File %s loaded"), pages); Log.notice(F("HASP: File %s loaded"), pages);
#else
#if HASP_USE_EEPROM > 0
Log.notice(F("HASP: Loading jsonl from EEPROM..."));
EepromStream eepromStream(4096, 1024);
dispatchJsonl(eepromStream);
Log.notice(F("HASP: Loaded jsonl from EEPROM"));
#endif
#endif #endif
} }

View File

@ -206,6 +206,7 @@ void configWriteConfig()
Log.verbose(F("WIFI: Settings changed")); Log.verbose(F("WIFI: Settings changed"));
writefile = true; writefile = true;
} }
#endif
#if HASP_USE_MQTT #if HASP_USE_MQTT
if(settings[F("mqtt")].as<JsonObject>().isNull()) settings.createNestedObject(F("mqtt")); if(settings[F("mqtt")].as<JsonObject>().isNull()) settings.createNestedObject(F("mqtt"));
changed = mqttGetConfig(settings[F("mqtt")]); changed = mqttGetConfig(settings[F("mqtt")]);
@ -240,7 +241,6 @@ void configWriteConfig()
configOutput(settings[F("http")]); configOutput(settings[F("http")]);
writefile = true; writefile = true;
} }
#endif
#endif #endif
if(settings[F("debug")].as<JsonObject>().isNull()) settings.createNestedObject(F("debug")); if(settings[F("debug")].as<JsonObject>().isNull()) settings.createNestedObject(F("debug"));
@ -350,6 +350,7 @@ void configSetup()
#if HASP_USE_WIFI #if HASP_USE_WIFI
Log.verbose(F("Loading WiFi settings")); Log.verbose(F("Loading WiFi settings"));
wifiSetConfig(settings[F("wifi")]); wifiSetConfig(settings[F("wifi")]);
#endif
#if HASP_USE_MQTT #if HASP_USE_MQTT
Log.verbose(F("Loading MQTT settings")); Log.verbose(F("Loading MQTT settings"));
mqttSetConfig(settings[F("mqtt")]); mqttSetConfig(settings[F("mqtt")]);
@ -366,8 +367,7 @@ void configSetup()
Log.verbose(F("Loading HTTP settings")); Log.verbose(F("Loading HTTP settings"));
httpSetConfig(settings[F("http")]); httpSetConfig(settings[F("http")]);
#endif #endif
#endif // Wifi // }
// }
Log.notice(F("User configuration loaded")); Log.notice(F("User configuration loaded"));
} }
//#endif //#endif

View File

@ -71,6 +71,8 @@ Syslog * syslog;
#endif // USE_SYSLOG #endif // USE_SYSLOG
// Serial Settings // Serial Settings
uint8_t serialInputIndex = 0; // Empty buffer
char serialInputBuffer[1024];
uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10 uint16_t debugSerialBaud = SERIAL_SPEED / 10; // Multiplied by 10
bool debugSerialStarted = false; bool debugSerialStarted = false;
bool debugAnsiCodes = true; bool debugAnsiCodes = true;
@ -96,10 +98,10 @@ String debugHaspHeader()
header.reserve(256); header.reserve(256);
if(debugAnsiCodes) header += TERM_COLOR_YELLOW; if(debugAnsiCodes) header += TERM_COLOR_YELLOW;
header += F(" _____ _____ _____ _____\r\n" header += F(" _____ _____ _____ _____\r\n"
" | | | _ | __| _ |\r\n" " | | | _ | __| _ |\r\n"
" | | |__ | __|\r\n" " | | |__ | __|\r\n"
" |__|__|__|__|_____|__|\r\n" " |__|__|__|__|_____|__|\r\n"
" Home Automation Switch Plate\r\n"); " Home Automation Switch Plate\r\n");
char buffer[128]; char buffer[128];
snprintf(buffer, sizeof(buffer), PSTR(" Open Hardware edition v%u.%u.%u\r\n"), HASP_VERSION_MAJOR, snprintf(buffer, sizeof(buffer), PSTR(" Open Hardware edition v%u.%u.%u\r\n"), HASP_VERSION_MAJOR,
HASP_VERSION_MINOR, HASP_VERSION_REVISION); HASP_VERSION_MINOR, HASP_VERSION_REVISION);
@ -232,8 +234,8 @@ static void debugPrintTimestamp(int level, Print * _logOutput)
_logOutput->printf(PSTR("%03lu]"), millis() % 1000); _logOutput->printf(PSTR("%03lu]"), millis() % 1000);
} else */ } else */
{ {
uint32_t msecs = millis(); uint32_t msecs = millis();
_logOutput->printf(PSTR("[%16d.%03d]"), msecs/1000, msecs%1000 ); _logOutput->printf(PSTR("[%16d.%03d]"), msecs / 1000, msecs % 1000);
} }
} }
@ -334,10 +336,10 @@ void debugPreSetup(JsonObject settings)
if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */ if(baudrate >= 9600u) { /* the baudrates are stored divided by 10 */
#if defined(STM32F4xx) #if defined(STM32F4xx)
#ifndef STM32_SERIAL1 // Define what Serial port to use for log output #ifndef STM32_SERIAL1 // Define what Serial port to use for log output
Serial.setRx(PA3); // User Serial2 Serial.setRx(PA3); // User Serial2
Serial.setTx(PA2); Serial.setTx(PA2);
#endif #endif
#endif #endif
Serial.begin(baudrate); /* prepare for possible serial debug */ Serial.begin(baudrate); /* prepare for possible serial debug */
delay(10); delay(10);
@ -378,7 +380,26 @@ void debugLvgl(lv_log_level_t level, const char * file, uint32_t line, const cha
#endif #endif
void debugLoop() void debugLoop()
{} {
while(Serial.available()) {
char ch = Serial.read();
Serial.print(ch);
if(ch == 13 || ch == 10) {
serialInputBuffer[serialInputIndex] = 0;
if(serialInputIndex > 0) dispatchCommand(serialInputBuffer);
serialInputIndex = 0;
} else {
if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
serialInputBuffer[serialInputIndex++] = ch;
}
serialInputBuffer[serialInputIndex] = 0;
if(strcmp(serialInputBuffer, "jsonl=") == 0) {
dispatchJsonl(Serial);
serialInputIndex = 0;
}
}
}
}
/*void printLocalTime() /*void printLocalTime()
{ {

View File

@ -161,14 +161,13 @@ void dispatchDim(String strDimLevel)
// Set the current state // Set the current state
if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt()); if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt());
dispatchPrintln(F("DIM"), strDimLevel); dispatchPrintln(F("DIM"), strDimLevel);
char buffer[8];
#if HASP_USE_MQTT > 0 #if HASP_USE_MQTT > 0
char buffer[8];
itoa(guiGetDim(), buffer, DEC); itoa(guiGetDim(), buffer, DEC);
mqtt_send_state(F("dim"), buffer); mqtt_send_state(F("dim"), buffer);
#endif #endif
#if HASP_USE_TASMOTA_SLAVE > 0 #if HASP_USE_TASMOTA_SLAVE > 0
char buffer[8];
itoa(guiGetDim(), buffer, DEC); itoa(guiGetDim(), buffer, DEC);
slave_send_state(F("dim"), buffer); slave_send_state(F("dim"), buffer);
#endif #endif

View File

@ -6,6 +6,12 @@ void eepromSetup()
#if defined(STM32Fxx) #if defined(STM32Fxx)
eeprom_buffer_fill(); eeprom_buffer_fill();
char buffer[] = "{\"objid\":10,\"id\":1,\"page\":0,\"x\":10,\"y\":45,\"w\":220,\"h\":55,\"toggle\":\"TRUE\",\"txt\":\"Toggle Me\"}";
uint size = strlen(buffer);
uint16_t i;
for(i = 0; i < size; i++) eeprom_buffered_write_byte(i+4096, buffer[i]);
eeprom_buffered_write_byte(i+4096, 0);
// eeprom_buffer_flush();
#endif #endif
// ESP8266 // Don't start at boot, only at write // ESP8266 // Don't start at boot, only at write

View File

@ -50,7 +50,11 @@ void ethernetSetup()
ip = Ethernet.localIP(); ip = Ethernet.localIP();
Log.notice(F("ETH: DHCP Success got IP=%d.%d.%d.%d"),ip[0], ip[1], ip[2], ip[3]); Log.notice(F("ETH: DHCP Success got IP=%d.%d.%d.%d"),ip[0], ip[1], ip[2], ip[3]);
} }
#endif
uint8_t *mac;
mac = Ethernet.MACAddress();
Log.notice(F("ETH: MAC Address %x:%x:%x:%x:%x:%x"),*mac,*(mac+1),*(mac+2),*(mac+3),*(mac+4),*(mac+5));
} }
void ethernetLoop(void) void ethernetLoop(void)

View File

@ -16,6 +16,46 @@ uint16_t gpioConfig[HASP_NUM_GPIO_CONFIG];
using namespace ace_button; using namespace ace_button;
static AceButton * button[HASP_NUM_INPUTS]; static AceButton * button[HASP_NUM_INPUTS];
struct hasp_gpio_config_t {
const uint8_t pin;
const uint8_t group;
const uint8_t io_mode;
bool default_state;
};
// An array of button pins, led pins, and the led states. Cannot be const
// because ledState is mutable.
hasp_gpio_config_t gpioConfig2[HASP_NUM_GPIO_CONFIG] = {
{2, 8, INPUT, LOW},
{3, 9, OUTPUT, LOW},
{4, 10, INPUT, HIGH},
{5, 11, OUTPUT, LOW},
{6, 12, INPUT, LOW},
};
#if defined(ARDUINO_ARCH_ESP32)
class TouchConfig : public ButtonConfig {
public:
TouchConfig();
protected:
// Number of iterations to sample the capacitive switch. Higher number
// provides better smoothing but increases the time taken for a single read.
static const uint8_t kSamples = 10;
// The threshold value which is considered to be a "touch" on the switch.
static const long kTouchThreshold = 70;
int readButton(uint8_t pin) override
{
// long total = mSensor.capacitiveSensor(kSamples);
return (touchRead(pin) > kTouchThreshold) ? LOW : HIGH;
}
};
TouchConfig touchConfig();
#endif
static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState) static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
{ {
char buffer[16]; char buffer[16];
@ -73,13 +113,16 @@ void IRAM_ATTR gpioLoop(void)
} }
} }
void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel) void gpioAddButton( uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
{ {
uint8_t i; uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) { for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) { if(!button[i]) {
button[i] = new AceButton(pin, default_state, channel); button[i] = new AceButton(pin, default_state, channel);
// button[i]->init(pin, default_state, channel);
if(button[i]) { if(button[i]) {
pinMode(pin, input_mode); pinMode(pin, input_mode);
@ -90,9 +133,42 @@ void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick); buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress); buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress); buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->clearFeature(ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
Log.verbose(F("GPIO: Button%d created on pin %d (channel %d) mode %d default %d"), i, pin, channel, input_mode,default_state); 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 gpioAddTouchButton( 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();
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
buttonConfig->clearFeature(ButtonConfig::kFeatureRepeatPress);
buttonConfig->clearFeature(
ButtonConfig::kFeatureSuppressClickBeforeDoubleClick); // Causes annoying pauses
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; gpioUsedInputCount = i + 1;
return; return;
} }
@ -106,18 +182,24 @@ void gpioSetup()
{ {
aceButtonSetup(); aceButtonSetup();
//gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3); // gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3);
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
gpioAddButton(D2, INPUT_PULLUP, HIGH, 1); gpioAddButton( D2, INPUT_PULLUP, HIGH, 1);
pinMode(D1, OUTPUT);
#endif
#if defined(ARDUINO_ARCH_ESP32)
gpioAddButton( D2, INPUT, HIGH, 1);
pinMode(D1, OUTPUT); pinMode(D1, OUTPUT);
#endif #endif
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) { for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint8_t pin = (gpioConfig[i] >> 8) & 0xFF; uint8_t pin = (gpioConfig[i] >> 8) & 0xFF;
uint8_t channel = gpioConfig[i] & 0b111; // 3bit uint8_t channel = gpioConfig[i] & 0b111; // 3bit
uint8_t input_mode = (gpioConfig[i] >> 3) & 0b11; // 2bit gpio mode uint8_t input_mode = (gpioConfig[i] >> 3) & 0b11; // 2bit gpio mode
uint8_t gpiotype = (gpioConfig[i] >> 5) & 0b111; // 3bit //uint8_t input_mode = gpioConfig[i].io_mode
uint8_t default_state = gpioConfig[i] & 0b1; // 1bit: 0=LOW, 1=HIGH uint8_t gpiotype = (gpioConfig[i] >> 5) & 0b111; // 3bit
uint8_t default_state = gpioConfig[i] & 0b1; // 1bit: 0=LOW, 1=HIGH
switch(input_mode) { switch(input_mode) {
case 1: case 1:
@ -138,7 +220,7 @@ void gpioSetup()
switch(gpiotype) { switch(gpiotype) {
case HASP_GPIO_SWITCH: case HASP_GPIO_SWITCH:
case HASP_GPIO_BUTTON: case HASP_GPIO_BUTTON:
// gpioAddButton(pin, input_mode, default_state, channel); // gpioAddButton(gpioConfig[i].io_mode.pin, input_mode, gpioConfig[i].default_state, gpioConfig[i].group);
break; break;
case HASP_GPIO_RELAY: case HASP_GPIO_RELAY:

View File

@ -41,6 +41,11 @@ File pFileOut;
#endif #endif
uint8_t guiSnapshot = 0; uint8_t guiSnapshot = 0;
#if defined(STM32F4xx)
//#include <EthernetWebServer_STM32.h>
// EthernetWebServer * webClient(0);
#endif
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
ESP8266WebServer * webClient; // for snatshot ESP8266WebServer * webClient; // for snatshot
@ -75,10 +80,7 @@ static uint8_t guiRotation = TFT_ROTATION;
#if ESP32 > 0 || ESP8266 > 0 #if ESP32 > 0 || ESP8266 > 0
static Ticker tick; /* timer for interrupt handler */ static Ticker tick; /* timer for interrupt handler */
#else #else
static Ticker tick(lv_tick_handler,guiTickPeriod); static Ticker tick(lv_tick_handler, guiTickPeriod);
uint8_t serialInputIndex = 0; // Empty buffer
char serialInputBuffer[1024];
#endif #endif
static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */ static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */
static uint16_t calData[5] = {0, 65535, 0, 65535, 0}; static uint16_t calData[5] = {0, 65535, 0, 65535, 0};
@ -174,14 +176,15 @@ static bool guiCheckSleep()
/* Flush VDB bytes to a stream */ /* Flush VDB bytes to a stream */
static void gui_take_screenshot(uint8_t * data_p, size_t len) static void gui_take_screenshot(uint8_t * data_p, size_t len)
{ {
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
size_t res = 0; size_t res = 0;
switch(guiSnapshot) { switch(guiSnapshot) {
#if HASP_USE_SPIFFS > 0
case 1: case 1:
res = pFileOut.write(data_p, len); res = pFileOut.write(data_p, len);
break; break;
#endif
case 2: case 2:
res = webClient->client().write(data_p, len); res = httpClientWrite(data_p, len);
break; break;
default: default:
res = 0; // nothing to do res = 0; // nothing to do
@ -189,7 +192,6 @@ static void gui_take_screenshot(uint8_t * data_p, size_t len)
if(res != len) { if(res != len) {
Log.warning(F("GUI: Pixelbuffer not completely sent")); Log.warning(F("GUI: Pixelbuffer not completely sent"));
} }
#endif
} }
/* Experimetnal Display flushing */ /* Experimetnal Display flushing */
@ -200,7 +202,6 @@ static void IRAM_ATTR tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * are
/* Update TFT */ /* Update TFT */
tft.startWrite(); /* Start new TFT transaction */ tft.startWrite(); /* Start new TFT transaction */
tft.setWindow(area->x1, area->y1, area->x2, area->y2); /* set the working window */ tft.setWindow(area->x1, area->y1, area->x2, area->y2); /* set the working window */
tft.setSwapBytes(true); /* set endianess */
tft.pushPixels((uint16_t *)color_p, len); /* Write words at once */ tft.pushPixels((uint16_t *)color_p, len); /* Write words at once */
tft.endWrite(); /* terminate TFT transaction */ tft.endWrite(); /* terminate TFT transaction */
@ -620,11 +621,12 @@ void guiSetup()
{ {
/* TFT init */ /* TFT init */
tft.begin(); tft.begin();
tft.setSwapBytes(true); /* set endianess */
#ifdef USE_DMA_TO_TFT #ifdef USE_DMA_TO_TFT
// DMA - should work with STM32F2xx/F4xx/F7xx processors // DMA - should work with STM32F2xx/F4xx/F7xx processors
// NOTE: >>>>>> DMA IS FOR SPI DISPLAYS ONLY <<<<<< // NOTE: >>>>>> DMA IS FOR SPI DISPLAYS ONLY <<<<<<
tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767) tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767)
#endif #endif
tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */ tft.setRotation(guiRotation); /* 1/3=Landscape or 0/2=Portrait orientation */
@ -655,10 +657,10 @@ tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767
#else #else
static lv_disp_buf_t disp_buf; static lv_disp_buf_t disp_buf;
static lv_color_t guiVdbBuffer1[16 * 512u]; // 16 KBytes static lv_color_t guiVdbBuffer1[16 * 512u]; // 16 KBytes
static lv_color_t guiVdbBuffer2[16 * 512u]; // 16 KBytes // static lv_color_t guiVdbBuffer2[16 * 512u]; // 16 KBytes
guiVDBsize = sizeof(guiVdbBuffer1) / sizeof(guiVdbBuffer1[0]); guiVDBsize = sizeof(guiVdbBuffer1) / sizeof(guiVdbBuffer1[0]);
lv_disp_buf_init(&disp_buf, guiVdbBuffer1, guiVdbBuffer2, guiVDBsize); // lv_disp_buf_init(&disp_buf, guiVdbBuffer1, guiVdbBuffer2, guiVDBsize);
//lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize); lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize);
#endif #endif
/* Initialize PNG decoder */ /* Initialize PNG decoder */
@ -784,27 +786,27 @@ tft.initDMA(); // Initialise the DMA engine (tested with STM32F446 and STM32F767
tick.attach_ms(guiTickPeriod, lv_tick_handler); tick.attach_ms(guiTickPeriod, lv_tick_handler);
#else #else
/* /*
#if defined(TIM1) #if defined(TIM1)
TIM_TypeDef * Instance = TIM1; TIM_TypeDef * Instance = TIM1;
#else #else
TIM_TypeDef * Instance = TIM2; TIM_TypeDef * Instance = TIM2;
#endif #endif
*/ */
// Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup() // Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup()
// function is finished. // function is finished.
/* static HardwareTimer * MyTim = new HardwareTimer(Instance); /* static HardwareTimer * MyTim = new HardwareTimer(Instance);
MyTim->pause(); MyTim->pause();
MyTim->setPrescaleFactor(1); MyTim->setPrescaleFactor(1);
MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC); MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC);
MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec
MyTim->setCount(0,MICROSEC_FORMAT); MyTim->setCount(0,MICROSEC_FORMAT);
MyTim->refresh(); MyTim->refresh();
MyTim->detachInterrupt(); MyTim->detachInterrupt();
MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler); MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler);
MyTim->detachInterrupt(0); MyTim->detachInterrupt(0);
MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler); MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler);
MyTim->resume();*/ MyTim->resume();*/
tick.start(); tick.start();
#endif #endif
@ -817,34 +819,15 @@ void IRAM_ATTR guiLoop()
{ {
#if defined(STM32F4xx) #if defined(STM32F4xx)
tick.update(); tick.update();
while(Serial.available()) {
char ch = Serial.read();
Serial.print(ch);
if (ch == 13 ||ch == 10) {
serialInputBuffer[serialInputIndex] = 0;
if (serialInputIndex>0) dispatchCommand(serialInputBuffer);
serialInputIndex=0;
}else{
if(serialInputIndex < sizeof(serialInputBuffer) - 1) {
serialInputBuffer[serialInputIndex++] = ch;
}
serialInputBuffer[serialInputIndex] = 0;
if (strcmp(serialInputBuffer,"jsonl=")==0){
dispatchJsonl(Serial);
serialInputIndex=0;
}
}
}
#endif #endif
//lv_tick_handler();
// lv_tick_handler();
lv_task_handler(); /* let the GUI do its work */ lv_task_handler(); /* let the GUI do its work */
guiCheckSleep(); guiCheckSleep();
#if TOUCH_DRIVER == 1 #if TOUCH_DRIVER == 1
touch.loop(); touch.loop();
#endif #endif
} }
void guiStop() void guiStop()
@ -990,14 +973,15 @@ bool guiSetConfig(const JsonObject & settings)
} }
if(calData[0] != 0 || calData[1] != 65535 || calData[2] != 0 || calData[3] != 65535) { if(calData[0] != 0 || calData[1] != 65535 || calData[2] != 0 || calData[3] != 65535) {
Log.trace(F("calData set [%u, %u, %u, %u, %u]"), calData[0], calData[1], calData[2], calData[3],calData[4]); Log.trace(F("calData set [%u, %u, %u, %u, %u]"), calData[0], calData[1], calData[2], calData[3],
calData[4]);
oobeSetAutoCalibrate(false); oobeSetAutoCalibrate(false);
} else { } else {
Log.notice(F("First Touch Calibration enabled")); Log.notice(F("First Touch Calibration enabled"));
oobeSetAutoCalibrate(true); oobeSetAutoCalibrate(true);
} }
if (status) tft.setTouch(calData); if(status) tft.setTouch(calData);
changed |= status; changed |= status;
} }
@ -1012,23 +996,15 @@ static void guiSetBmpHeader(uint8_t * buffer_p, int32_t data)
*buffer_p++ = (data >> 24) & 0xFF; *buffer_p++ = (data >> 24) & 0xFF;
} }
#if defined(ARDUINO_ARCH_ESP8266)
static void guiSendBmpHeader(); static void guiSendBmpHeader();
void guiTakeScreenshot(ESP8266WebServer & client) void guiTakeScreenshot()
#endif
#if defined(ARDUINO_ARCH_ESP32)
static void guiSendBmpHeader();
void guiTakeScreenshot(WebServer & client)
#endif // ESP32{
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
{ {
webClient = &client; // webClient = &client;
lv_disp_t * disp = lv_disp_get_default(); // lv_disp_t * disp = lv_disp_get_default();
webClient->setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t)); // webClient->setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t));
webClient->send(200, PSTR("image/bmp"), ""); // webClient->send(200, PSTR("image/bmp"), "");
guiSnapshot = 2; guiSnapshot = 2;
guiSendBmpHeader(); guiSendBmpHeader();
@ -1089,15 +1065,17 @@ static void guiSendBmpHeader()
buffer[70 + 0] = 0x20; buffer[70 + 0] = 0x20;
if(guiSnapshot == 1) { if(guiSnapshot == 1) {
#if HASP_USE_SPIFFS > 0
size_t len = pFileOut.write(buffer, 122); size_t len = pFileOut.write(buffer, 122);
if(len != sizeof(buffer)) { if(len != sizeof(buffer)) {
Log.warning(F("GUI: Data written does not match header size")); Log.warning(F("GUI: Data written does not match header size"));
} else { } else {
Log.verbose(F("GUI: Bitmap header written")); Log.verbose(F("GUI: Bitmap header written"));
} }
#endif
} else if(guiSnapshot == 2) { } else if(guiSnapshot == 2) {
if(webClient->client().write(buffer, 122) != 122) { if(httpClientWrite(buffer, 122) != 122) {
Log.warning(F("GUI: Data sent does not match header size")); Log.warning(F("GUI: Data sent does not match header size"));
} else { } else {
Log.verbose(F("GUI: Bitmap header sent")); Log.verbose(F("GUI: Bitmap header sent"));
@ -1114,6 +1092,7 @@ static void guiSendBmpHeader()
* @param[in] pFileName Output binary file name. * @param[in] pFileName Output binary file name.
* *
**/ **/
#if HASP_USE_SPIFFS > 0
void guiTakeScreenshot(const char * pFileName) void guiTakeScreenshot(const char * pFileName)
{ {
pFileOut = SPIFFS.open(pFileName, "w"); pFileOut = SPIFFS.open(pFileName, "w");

View File

@ -6,15 +6,17 @@
#include "lvgl.h" #include "lvgl.h"
#if defined(ARDUINO_ARCH_ESP8266) // #if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WebServer.h> // #include <ESP8266WebServer.h>
void guiTakeScreenshot(ESP8266WebServer & client); // void guiTakeScreenshot(ESP8266WebServer & client);
#endif // #endif
#if defined(ARDUINO_ARCH_ESP32) // #if defined(ARDUINO_ARCH_ESP32)
#include <WebServer.h> // #include <WebServer.h>
void guiTakeScreenshot(WebServer & client); // void guiTakeScreenshot(WebServer & client);
#endif // ESP32 // #endif // ESP32
void guiTakeScreenshot();
void guiSetup(); void guiSetup();
void guiLoop(void); void guiLoop(void);

View File

@ -1,10 +1,17 @@
#if defined(ESP32) || defined(ESP8266) #if defined(STM32F4xx)
#include <ESP.h> #include <Stm32Ethernet.h>
#endif #endif
#include "hasp_hal.h" #include "hasp_hal.h"
#if ESP32 #if defined(ESP8266)
#include <ESP.h>
#include <ESP8266WiFi.h>
#endif
#if defined(ESP32)
#include <ESP.h>
#include <Wifi.h>
#include "esp_system.h" #include "esp_system.h"
#endif #endif
@ -107,8 +114,6 @@ String halGetResetInfo()
#endif #endif
} }
String halGetCoreVersion() String halGetCoreVersion()
{ {
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
@ -155,13 +160,12 @@ String halGetChipModel()
return model; return model;
} }
/*******************************/ /*******************************/
/* Memory Management Functions */ /* Memory Management Functions */
#if defined(STM32F4xx) #if defined(STM32F4xx)
#include <malloc.h> // for mallinfo() #include <malloc.h> // for mallinfo()
#include <unistd.h> // for sbrk() #include <unistd.h> // for sbrk()
int freeHighMemory() int freeHighMemory()
{ {
@ -177,29 +181,29 @@ int freeHighMemory()
#endif #endif
/* /*
extern char *fake_heap_end; // current heap start extern char *fake_heap_end; // current heap start
extern char *fake_heap_start; // current heap end extern char *fake_heap_start; // current heap end
char* getHeapStart() { char* getHeapStart() {
return fake_heap_start; 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 char* getHeapEnd() {
struct mallinfo mi = mallinfo(); return (char*)sbrk(0);
return mi.uordblks; }
}
int getMemFree() { // returns the amount of free memory in bytes char* getHeapLimit() {
struct mallinfo mi = mallinfo(); return fake_heap_end;
return mi.fordblks + freeHighMemory(); }
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() size_t halGetMaxFreeBlock()
@ -239,3 +243,57 @@ uint8_t halGetHeapFragmentation()
return (int8_t)(100.00f - (float)freeHighMemory() * 100.00f / (float)halGetFreeHeap()); return (int8_t)(100.00f - (float)freeHighMemory() * 100.00f / (float)halGetFreeHeap());
#endif #endif
} }
String halGetMacAddress(int start, const char * seperator)
{
byte mac[6];
#if defined(STM32F4xx)
uint8_t * mac_p;
mac_p = Ethernet.MACAddress();
for(uint8_t i = 0; i < 6; i++) mac[i] = *(mac_p + i);
#else
WiFi.macAddress(mac);
#endif
String cMac((char *)0);
cMac.reserve(32);
for(int i = start; i < 6; ++i) {
if(mac[i] < 0x10) cMac += "0";
cMac += String(mac[i], HEX);
if(i < 5) cMac += seperator;
}
cMac.toUpperCase();
return cMac;
}
uint16_t halGetCpuFreqMHz()
{
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32)
return ESP.getCpuFreqMHz();
#else
return (F_CPU / 1000 / 1000);
#endif
}
String halFormatBytes(size_t bytes)
{
String output((char *)0);
output.reserve(128);
if(bytes < 1024) {
output += bytes;
} else if(bytes < (1024 * 1024)) {
output += bytes / 1024.0;
output += "K";
} else if(bytes < (1024 * 1024 * 1024)) {
output += bytes / 1024.0 / 1024.0;
output += "M";
} else {
output += bytes / 1024.0 / 1024.0 / 1024.0;
output += "G";
}
output += "B";
return output;
}

View File

@ -10,5 +10,8 @@ size_t halGetMaxFreeBlock(void);
size_t halGetFreeHeap(void); size_t halGetFreeHeap(void);
String halGetCoreVersion(void); String halGetCoreVersion(void);
String halGetChipModel(); String halGetChipModel();
String halGetMacAddress(int start, const char * seperator);
uint16_t halGetCpuFreqMHz(void);
String halFormatBytes(size_t bytes);
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,8 @@ void httpLoop(void);
void httpEvery5Seconds(void); void httpEvery5Seconds(void);
void httpReconnect(void); void httpReconnect(void);
size_t httpClientWrite(const uint8_t *buf, size_t size); // Screenshot Write Data
bool httpGetConfig(const JsonObject & settings); bool httpGetConfig(const JsonObject & settings);
bool httpSetConfig(const JsonObject & settings); bool httpSetConfig(const JsonObject & settings);

View File

@ -11,10 +11,15 @@
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <Wifi.h> #include <Wifi.h>
#else WiFiClient mqttNetworkClient;
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <EEPROM.h> #include <EEPROM.h>
#include <ESP.h> #include <ESP.h>
WiFiClient mqttNetworkClient;
#else
#include <STM32Ethernet.h>
EthernetClient mqttNetworkClient;
#endif #endif
#include "hasp_hal.h" #include "hasp_hal.h"
@ -97,8 +102,7 @@ const String mqttLightSubscription = "hasp/" + String(haspGetNodename())
const String mqttLightBrightSubscription = "hasp/" + String(haspGetNodename()) + "/brightness/#"; const String mqttLightBrightSubscription = "hasp/" + String(haspGetNodename()) + "/brightness/#";
*/ */
WiFiClient mqttWifiClient; PubSubClient mqttClient(mqttNetworkClient);
PubSubClient mqttClient(mqttWifiClient);
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Send changed values OUT // Send changed values OUT
@ -179,11 +183,13 @@ void mqtt_send_statusupdate()
snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"), snprintf_P(data, sizeof(data), PSTR("{\"status\":\"available\",\"version\":\"%s\",\"uptime\":%lu,"),
haspGetVersion().c_str(), long(millis() / 1000)); haspGetVersion().c_str(), long(millis() / 1000));
strcat(buffer, data); strcat(buffer, data);
#if HASP_USE_WIFI
snprintf_P(buffer, sizeof(buffer), PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%s\","), WiFi.SSID().c_str(), snprintf_P(buffer, sizeof(buffer), PSTR("\"ssid\":\"%s\",\"rssi\":%i,\"ip\":\"%s\","), WiFi.SSID().c_str(),
WiFi.RSSI(), WiFi.localIP().toString().c_str()); WiFi.RSSI(), WiFi.localIP().toString().c_str());
strcat(data, buffer); strcat(data, buffer);
#endif
snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"espCore\":\"%s\","), snprintf_P(buffer, sizeof(buffer), PSTR("\"heapFree\":%u,\"heapFrag\":%u,\"espCore\":\"%s\","),
ESP.getFreeHeap(), halGetHeapFragmentation(), halGetCoreVersion().c_str()); halGetFreeHeap(), halGetHeapFragmentation(), halGetCoreVersion().c_str());
strcat(data, buffer); strcat(data, buffer);
snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"), snprintf_P(buffer, sizeof(buffer), PSTR("\"espCanUpdate\":\"false\",\"page\":%u,\"numPages\":%u,"),
haspGetPage(), (HASP_NUM_PAGES)); haspGetPage(), (HASP_NUM_PAGES));
@ -339,10 +345,18 @@ void mqttReconnect()
bool mqttFirstConnect = true; bool mqttFirstConnect = true;
{ {
#if HASP_USE_WIFI>0
byte mac[6]; byte mac[6];
WiFi.macAddress(mac); WiFi.macAddress(mac);
snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%2x%2x%2x"), mqttNodeName, mac[3], mac[4], mac[5]); snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%02x%02x%02x"), mqttNodeName, mac[3], mac[4], mac[5]);
#endif
#if HASP_USE_ETHERNET>0
uint8_t * mac;
mac = Ethernet.MACAddress();
snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%02x%02x%02x"), mqttNodeName, *(mac+3), *(mac+4), *(mac+5));
#endif
} }
Log.verbose(mqttClientId);
// Attempt to connect and set LWT and Clean Session // Attempt to connect and set LWT and Clean Session
snprintf_P(buffer, sizeof(buffer), PSTR("%sstatus"), mqttNodeTopic); snprintf_P(buffer, sizeof(buffer), PSTR("%sstatus"), mqttNodeTopic);
@ -537,7 +551,7 @@ bool mqttSetConfig(const JsonObject & settings)
} }
// Prefill node name // Prefill node name
if(strlen(mqttNodeName) == 0) { if(strlen(mqttNodeName) == 0) {
String mac = wifiGetMacAddress(3, ""); String mac = halGetMacAddress(3, "");
mac.toLowerCase(); mac.toLowerCase();
snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR("plate_%s"), mac.c_str()); snprintf_P(mqttNodeName, sizeof(mqttNodeName), PSTR("plate_%s"), mac.c_str());
changed = true; changed = true;

View File

@ -102,25 +102,4 @@ void spiffsSetup()
Log.verbose(F("FILE: SPI Flash FS mounted")); Log.verbose(F("FILE: SPI Flash FS mounted"));
} }
#endif #endif
}
String spiffsFormatBytes(size_t bytes)
{
String output((char *)0);
output.reserve(128);
if(bytes < 1024) {
output += bytes;
} else if(bytes < (1024 * 1024)) {
output += bytes / 1024.0;
output += "K";
} else if(bytes < (1024 * 1024 * 1024)) {
output += bytes / 1024.0 / 1024.0;
output += "M";
} else {
output += bytes / 1024.0 / 1024.0 / 1024.0;
output += "G";
}
output += "B";
return output;
} }

View File

@ -7,6 +7,5 @@ void spiffsSetup(void);
void spiffsList(); void spiffsList();
void spiffsInfo(); void spiffsInfo();
String spiffsFormatBytes(size_t bytes);
#endif #endif

View File

@ -12,8 +12,16 @@
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include <Wifi.h> #include <Wifi.h>
#else WiFiClient telnetClient;
static WiFiServer * telnetServer;
#elif defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
WiFiClient telnetClient;
static WiFiServer * telnetServer;
#else
#include <STM32Ethernet.h>
EthernetClient telnetClient;
static EthernetServer telnetServer(23);
#endif #endif
#define TELNET_UNAUTHENTICATED 0 #define TELNET_UNAUTHENTICATED 0
@ -21,12 +29,14 @@
#define TELNET_USERNAME_NOK 99 #define TELNET_USERNAME_NOK 99
#define TELNET_AUTHENTICATED 255 #define TELNET_AUTHENTICATED 255
#if HASP_USE_HTTP > 0
extern char httpUser[32]; extern char httpUser[32];
extern char httpPassword[32]; extern char httpPassword[32];
#endif
uint8_t telnetLoginState = TELNET_UNAUTHENTICATED; uint8_t telnetLoginState = TELNET_UNAUTHENTICATED;
WiFiClient telnetClient; // WiFiClient telnetClient;
static WiFiServer * telnetServer; // static WiFiServer * telnetServer;
uint16_t telnetPort = 23; uint16_t telnetPort = 23;
bool telnetInCommandMode = false; bool telnetInCommandMode = false;
uint8_t telnetEnabled = true; // Enable telnet debug output uint8_t telnetEnabled = true; // Enable telnet debug output
@ -36,7 +46,7 @@ char telnetInputBuffer[128];
void telnetClientDisconnect() void telnetClientDisconnect()
{ {
Log.notice(F("Closing session from %s"), telnetClient.remoteIP().toString().c_str()); // Log.notice(F("Closing session from %s"), telnetClient.remoteIP().toString().c_str());
telnetClient.stop(); telnetClient.stop();
Log.unregisterOutput(1); // telnetClient Log.unregisterOutput(1); // telnetClient
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
@ -51,7 +61,7 @@ void telnetClientLogon()
telnetLoginState = TELNET_AUTHENTICATED; // User and Pass are correct telnetLoginState = TELNET_AUTHENTICATED; // User and Pass are correct
telnetLoginAttempt = 0; // Reset attempt counter telnetLoginAttempt = 0; // Reset attempt counter
Log.registerOutput(1, &telnetClient, LOG_LEVEL_VERBOSE, true); Log.registerOutput(1, &telnetClient, LOG_LEVEL_VERBOSE, true);
Log.notice(F("Client login from %s"), telnetClient.remoteIP().toString().c_str()); // Log.notice(F("Client login from %s"), telnetClient.remoteIP().toString().c_str());
telnetClient.flush(); telnetClient.flush();
/* Echo locally as separate string */ /* Echo locally as separate string */
// telnetClient.print(F("TELNET: Client login from ")); // telnetClient.print(F("TELNET: Client login from "));
@ -66,17 +76,25 @@ void telnetAcceptClient()
telnetClient.stop(); // client disconnected telnetClient.stop(); // client disconnected
Log.unregisterOutput(1); // telnetClient Log.unregisterOutput(1); // telnetClient
} }
telnetClient = telnetServer->available(); // ready for new client telnetClient = telnetServer.available(); // ready for new client
Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str()); // Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
if(!telnetClient) {
Log.notice(F("Client NOT connected"));
return;
}
Log.notice(F("Client connected"));
/* Avoid a buffer here */ /* Avoid a buffer here */
telnetClient.print(0xFF); // DO TERMINAL-TYPE telnetClient.print(0xFF); // DO TERMINAL-TYPE
telnetClient.print(0xFD); telnetClient.print(0xFD);
telnetClient.print(0x1B); telnetClient.print(0x1B);
#if HASP_USE_HTTP > 0
if(strlen(httpUser) != 0 || strlen(httpPassword) != 0) { if(strlen(httpUser) != 0 || strlen(httpPassword) != 0) {
telnetClient.print(F("\r\nUsername: ")); telnetClient.print(F("\r\nUsername: "));
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
} else { } else
#endif
{
telnetClientLogon(); telnetClientLogon();
} }
telnetInputIndex = 0; // reset input buffer index telnetInputIndex = 0; // reset input buffer index
@ -100,6 +118,7 @@ static void telnetProcessLine()
switch(telnetLoginState) { switch(telnetLoginState) {
case TELNET_UNAUTHENTICATED: { case TELNET_UNAUTHENTICATED: {
telnetClient.printf(PSTR("Password: %c%c%c"), 0xFF, 0xFB, 0x01); // Hide characters telnetClient.printf(PSTR("Password: %c%c%c"), 0xFF, 0xFB, 0x01); // Hide characters
#if HASP_USE_HTTP > 0
telnetLoginState = strcmp(telnetInputBuffer, httpUser) == 0 ? TELNET_USERNAME_OK : TELNET_USERNAME_NOK; telnetLoginState = strcmp(telnetInputBuffer, httpUser) == 0 ? TELNET_USERNAME_OK : TELNET_USERNAME_NOK;
break; break;
} }
@ -112,13 +131,16 @@ static void telnetProcessLine()
telnetLoginState = TELNET_UNAUTHENTICATED; telnetLoginState = TELNET_UNAUTHENTICATED;
telnetLoginAttempt++; // Subsequent attempt telnetLoginAttempt++; // Subsequent attempt
telnetClient.println(F("Authorization failed!\r\n")); telnetClient.println(F("Authorization failed!\r\n"));
Log.warning(F("Incorrect login attempt from %s"), telnetClient.remoteIP().toString().c_str()); // Log.warning(F("Incorrect login attempt from %s"), telnetClient.remoteIP().toString().c_str());
if(telnetLoginAttempt >= 3) { if(telnetLoginAttempt >= 3) {
telnetClientDisconnect(); telnetClientDisconnect();
} else { } else {
telnetClient.print(F("Username: ")); telnetClient.print(F("Username: "));
} }
} }
#else
telnetClientLogon();
#endif
break; break;
} }
default: default:
@ -173,6 +195,15 @@ void telnetSetup()
// telnetSetConfig(settings); // telnetSetConfig(settings);
if(telnetEnabled) { // Setup telnet server for remote debug output if(telnetEnabled) { // Setup telnet server for remote debug output
#if defined(STM32F4xx)
// if(!telnetServer) telnetServer = new EthernetServer(telnetPort);
// if(telnetServer) {
telnetServer.begin();
Log.notice(F("Debug telnet console started"));
// } else {
// Log.error(F("Failed to start telnet server"));
//}
#else
if(!telnetServer) telnetServer = new WiFiServer(telnetPort); if(!telnetServer) telnetServer = new WiFiServer(telnetPort);
if(telnetServer) { if(telnetServer) {
telnetServer->setNoDelay(true); telnetServer->setNoDelay(true);
@ -189,12 +220,41 @@ void telnetSetup()
} else { } else {
Log.error(F("Failed to start telnet server")); Log.error(F("Failed to start telnet server"));
} }
#endif
} }
} }
void IRAM_ATTR telnetLoop() void IRAM_ATTR telnetLoop()
{ // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303 { // Basic telnet client handling code from: https://gist.github.com/tablatronix/4793677ca748f5f584c95ec4a2b10303
#if defined(STM32F4xx)
Ethernet.schedule();
// if(telnetServer)
{ // client is connected
EthernetClient client = telnetServer.available();
if(client) {
if(!telnetClient || !telnetClient.connected()) {
//telnetAcceptClient(client);
telnetClient = client; // ready for new client
// Log.notice(F("Client connected from %s"), telnetClient.remoteIP().toString().c_str());
if(!telnetClient) {
Log.notice(F("Client NOT connected"));
return;
}
Log.notice(F("Client connected"));
/* Avoid a buffer here */
// telnetClient.print(0xFF); // DO TERMINAL-TYPE
// telnetClient.print(0xFD);
// telnetClient.print(0x1B);
} else {
//client.stop(); // have client, block new connections
}
}
}
#else
if(telnetServer && telnetServer->hasClient()) { // client is connected if(telnetServer && telnetServer->hasClient()) { // client is connected
if(!telnetClient || !telnetClient.connected()) { if(!telnetClient || !telnetClient.connected()) {
telnetAcceptClient(); telnetAcceptClient();
@ -209,6 +269,7 @@ void IRAM_ATTR telnetLoop()
telnetProcessCharacter(telnetClient.read()); // client input processing telnetProcessCharacter(telnetClient.read()); // client input processing
} }
} }
#endif
} }
bool telnetGetConfig(const JsonObject & settings) bool telnetGetConfig(const JsonObject & settings)

View File

@ -3,6 +3,7 @@
#include "TFT_eSPI.h" #include "TFT_eSPI.h"
#include "hasp_tft.h" #include "hasp_tft.h"
#include "hasp_hal.h"
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
ADC_MODE(ADC_VCC); // tftShowConfig measures the voltage on the pin ADC_MODE(ADC_VCC); // tftShowConfig measures the voltage on the pin
@ -84,11 +85,10 @@ void tftShowConfig(TFT_eSPI & tft)
Log.verbose(F("TFT: TFT_eSPI : v%s"), tftSetup.version.c_str()); Log.verbose(F("TFT: TFT_eSPI : v%s"), tftSetup.version.c_str());
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32) #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_32)
Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp); Log.verbose(F("TFT: Processor : ESP%x"), tftSetup.esp);
Log.verbose(F("TFT: CPU freq. : %i MHz"), ESP.getCpuFreqMHz());
#else #else
Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp); Log.verbose(F("TFT: Processor : STM%x"), tftSetup.esp);
Log.verbose(F("TFT: CPU freq. : %i MHz"), F_CPU / 1000 / 1000);
#endif #endif
Log.verbose(F("TFT: CPU freq. : %i MHz"), halGetCpuFreqMHz());
#if defined(ARDUINO_ARCH_ESP8266) #if defined(ARDUINO_ARCH_ESP8266)
Log.verbose(F("TFT: Voltage : %2.2f V"), ESP.getVcc() / 918.0); // 918 empirically determined Log.verbose(F("TFT: Voltage : %2.2f V"), ESP.getVcc() / 918.0); // 918 empirically determined

View File

@ -41,22 +41,6 @@ uint8_t wifiReconnectCounter = 0;
// const byte DNS_PORT = 53; // const byte DNS_PORT = 53;
// DNSServer dnsServer; // DNSServer dnsServer;
String wifiGetMacAddress(int start, const char * seperator)
{
byte mac[6];
WiFi.macAddress(mac);
String cMac((char *)0);
cMac.reserve(32);
for(int i = start; i < 6; ++i) {
if(mac[i] < 0x10) cMac += "0";
cMac += String(mac[i], HEX);
if(i < 5) cMac += seperator;
}
cMac.toUpperCase();
return cMac;
}
void wifiConnected(IPAddress ipaddress) void wifiConnected(IPAddress ipaddress)
{ {
Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str()); Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str());

View File

@ -9,6 +9,10 @@
#include "hasp_oobe.h" #include "hasp_oobe.h"
#include "hasp_gpio.h" #include "hasp_gpio.h"
#if HASP_USE_ETHERNET > 0
#include <STM32Ethernet.h>
#endif
bool isConnected; bool isConnected;
uint8_t mainLoopCounter = 0; uint8_t mainLoopCounter = 0;
unsigned long mainLastLoopTime = 0; unsigned long mainLastLoopTime = 0;
@ -42,32 +46,19 @@ void setup()
* Apply User Configuration * Apply User Configuration
***************************/ ***************************/
debugSetup(); debugSetup();
gpioSetup();
#if HASP_USE_GPIO #if HASP_USE_GPIO
guiSetup(); gpioSetup();
#endif #endif
#if HASP_USE_WIFI #if HASP_USE_WIFI
wifiSetup(); wifiSetup();
#endif #endif
guiSetup();
oobeSetup(); oobeSetup();
haspSetup(); haspSetup();
#if HASP_USE_WIFI
#if HASP_USE_HTTP
httpSetup();
#endif
#if HASP_USE_MQTT
mqttSetup();
#endif
#if HASP_USE_TELNET
telnetSetup();
#endif
#if HASP_USE_MDNS #if HASP_USE_MDNS
mdnsSetup(); mdnsSetup();
#endif #endif
@ -76,12 +67,22 @@ void setup()
otaSetup(); otaSetup();
#endif #endif
#endif // WIFI #if HASP_USE_ETHERNET > 0
#if HASP_USE_ETHERNET
ethernetSetup(); ethernetSetup();
#endif #endif
#if HASP_USE_MQTT
mqttSetup();
#endif
#if HASP_USE_HTTP
httpSetup();
#endif
#if HASP_USE_TELNET > 0
telnetSetup();
#endif
#if HASP_USE_TASMOTA_SLAVE #if HASP_USE_TASMOTA_SLAVE
slaveSetup(); slaveSetup();
#endif #endif
@ -92,34 +93,37 @@ void setup()
void loop() void loop()
{ {
/* Storage Loops */ /* Storage Loops */
/* /*
#if HASP_USE_EEPROM #if HASP_USE_EEPROM
// eepromLoop(); // Not used // eepromLoop(); // Not used
#endif #endif
#if HASP_USE_SPIFFS #if HASP_USE_SPIFFS
// spiffsLoop(); // Not used // spiffsLoop(); // Not used
#endif #endif
#if HASP_USE_SDCARD #if HASP_USE_SDCARD
// sdcardLoop(); // Not used // sdcardLoop(); // Not used
#endif #endif
// configLoop(); // Not used // configLoop(); // Not used
*/ */
/* Graphics Loops */ /* Graphics Loops */
// tftLoop(); // tftLoop();
guiLoop(); guiLoop();
/* Application Loops */ /* Application Loops */
// haspLoop(); // haspLoop();
debugLoop();
#if HASP_USE_GPIO #if HASP_USE_GPIO
gpioLoop(); gpioLoop();
#endif #endif
/* Network Services Loops */ /* Network Services Loops */
#if HASP_USE_WIFI #if HASP_USE_ETHERNET > 0
ethernetLoop();
#endif
#if HASP_USE_MQTT #if HASP_USE_MQTT
mqttLoop(); mqttLoop();
@ -129,10 +133,6 @@ void loop()
httpLoop(); httpLoop();
#endif // HTTP #endif // HTTP
#if HASP_USE_TELNET
telnetLoop();
#endif // TELNET
#if HASP_USE_MDNS #if HASP_USE_MDNS
mdnsLoop(); mdnsLoop();
#endif // MDNS #endif // MDNS
@ -141,11 +141,9 @@ void loop()
otaLoop(); otaLoop();
#endif // OTA #endif // OTA
#endif // WIFI #if HASP_USE_TELNET > 0
telnetLoop();
#if HASP_USE_ETHERNET #endif // TELNET
ethernetLoop();
#endif
#if HASP_USE_TASMOTA_SLAVE #if HASP_USE_TASMOTA_SLAVE
slaveLoop(); slaveLoop();
@ -162,17 +160,24 @@ void loop()
debugEverySecond(); debugEverySecond();
/* Run Every 5 Seconds */ /* Run Every 5 Seconds */
#if HASP_USE_WIFI
if(mainLoopCounter == 0 || mainLoopCounter == 5) { if(mainLoopCounter == 0 || mainLoopCounter == 5) {
#if HASP_USE_WIFI > 0
isConnected = wifiEvery5Seconds(); isConnected = wifiEvery5Seconds();
#if HASP_USE_HTTP #endif
#if HASP_USE_ETHERNET > 0
isConnected = Ethernet.linkStatus() == LinkON;
Serial.print(Ethernet.linkStatus());
#endif
#if HASP_USE_HTTP > 0
httpEvery5Seconds(); httpEvery5Seconds();
#endif #endif
#if HASP_USE_MQTT
#if HASP_USE_MQTT > 0
mqttEvery5Seconds(isConnected); mqttEvery5Seconds(isConnected);
#endif #endif
} }
#endif // Wifi
/* Reset loop counter every 10 seconds */ /* Reset loop counter every 10 seconds */
if(mainLoopCounter >= 9) { if(mainLoopCounter >= 9) {