Merge branch '0.1.0-fsmc' of https://github.com/fvanroie/hasp-lvgl into 0.1.0-fsmc

This commit is contained in:
arovak 2020-05-29 14:38:44 +02:00
commit 12bc9fda1e
21 changed files with 501 additions and 216 deletions

45
include/bootscreen.h Normal file
View File

@ -0,0 +1,45 @@
// Images can be converted to XBM format by using the online converter here:
// https://www.online-utility.org/image/convert/to/XBM
// The output must be pasted in a header file, renamed and adjusted to appear
// as as a const unsigned char array in PROGMEM (FLASH program memory).
// The xbm format adds padding to pixel rows so they are a whole number of bytes
// In this example 50 pixel width means 56 bits = 7 bytes
// the 50 height then means array uses 50 x 7 = 350 bytes of FLASH
// The library ignores the padding bits when drawing the image on the display.
// The NetWize logo uses the MaterialDesign icons font, released under the OFL license
#include <pgmspace.h> // PROGMEM support header
#define logoWidth 148
#define logoHeight 24
// Image is stored in this array
PROGMEM const unsigned char bootscreen[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x0F, 0xC0, 0xFF, 0x03, 0xF8, 0x7F, 0x00, 0x0F, 0x00, 0x0F, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x1F, 0x0F, 0xC0, 0xFF, 0x03, 0xF8, 0x7F, 0x00, 0x0F, 0x00, 0x0F, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x1F, 0x0F, 0xC0, 0xFF, 0x03, 0xF8, 0x7F, 0x00, 0x0F, 0x0F, 0x0F, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x1F, 0x0F, 0xC0, 0xFF, 0x03, 0xF8, 0x7F, 0x00, 0x0F, 0x0F, 0x0F, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x3F, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x0F, 0x00,
0x3F, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00,
0x7F, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x00,
0x7F, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x00,
0xFF, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0xC0, 0x03, 0x00, 0xFF, 0x0F,
0xFF, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0xFF, 0x0F,
0xFF, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0xFF, 0x0F,
0xFF, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0xF0, 0x00, 0x00, 0xFF, 0x0F,
0xEF, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00,
0xEF, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x78, 0x00, 0x00, 0x0F, 0x00,
0xCF, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x00, 0x0F, 0x00,
0xCF, 0x0F, 0xC0, 0x03, 0x00, 0x80, 0x07, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 0x1E, 0x00, 0x1E, 0x00, 0x00, 0x0F, 0x00,
0x8F, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0xFF, 0xFF, 0x0F, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x8F, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0xFF, 0xFF, 0x0F, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x8F, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0xFE, 0xFF, 0x07, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x0F, 0x0F, 0xC0, 0xFF, 0x03, 0x80, 0x07, 0x00, 0xFC, 0xFF, 0x03, 0x80, 0x7F, 0x00, 0xFE, 0x1F, 0x00, 0xFF, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@ -69,6 +69,10 @@
#define HASP_USE_PNGDECODE 0
#endif
#ifndef HASP_NUM_GPIO_CONFIG
#define HASP_NUM_GPIO_CONFIG 5
#endif
#ifndef HASP_NUM_INPUTS
#define HASP_NUM_INPUTS 3 // Buttons
#endif

View File

@ -77,7 +77,7 @@ typedef int16_t lv_coord_t;
#if LV_MEM_CUSTOM == 0
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
#ifdef ESP8266
# define LV_MEM_SIZE (12 * 1024U) // 12KB
# define LV_MEM_SIZE (10 * 1024U) // 12KB
#endif
#ifndef LV_MEM_SIZE
# define LV_MEM_SIZE (20 * 1024U) // 48KB

View File

@ -48,6 +48,8 @@ TFT_Class tft(io, controller, TFT_WIDTH, TFT_HEIGHT);
#include <GxCTRL/GxCTRL_ILI9341/GxCTRL_ILI9341.h> // 240x320
#include "GxReadRegisters.h"
#include "bootscreen.h" // Sketch tab header for xbm images
/*********************
* DEFINES
*********************/
@ -76,18 +78,35 @@ TFT_Class tft(io, controller, TFT_WIDTH, TFT_HEIGHT);
**********************/
/**
* Initialize the R61581 display controller
* @return HW_RES_OK or any error from hw_res_t enum
* Initialize the ILI9341 display controller
*/
void fsmc_ili9341_init(uint8_t rotation)
{
tft.init();
tft.setRotation(rotation);
// tft.fillScreen(BLUE);
tft.setRotation(rotation);
tft.fillScreen(TFT_DARKCYAN);
int x = (tft.width() - logoWidth) / 2;
int y = (tft.height() - logoHeight) / 2;
// tft.drawBitmap(x, y, bootscreen, logoWidth, logoHeight, TFT_WHITE);
io.startTransaction();
int32_t i, j, byteWidth = (logoWidth + 7) / 8;
for(j = 0; j < logoHeight; j++) {
for(i = 0; i < logoWidth; i++) {
if(pgm_read_byte(bootscreen + j * byteWidth + i / 8) & (1 << (i & 7))) {
tft.drawPixel(x + i, y + j, TFT_WHITE);
}
}
}
io.endTransaction();
delay(800);
}
/* GxTFT::pushColors only supports writing up to 255 at a time */
/* This local function circumvents this artificial limit */
/* This *local* function circumvents this artificial limititaion */
static inline void pushColors(uint16_t * data, uint32_t len)
{
io.startTransaction();
@ -103,21 +122,9 @@ void fsmc_ili9341_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color
tft.setWindow(x1, y1, x2, y2);
size_t len = (x2 - x1 + 1) * (y2 - y1 + 1); /* Number of pixels */
#if 1
#if 1 // use local version instead
pushColors((uint16_t *)color_p, len);
#else
// tft.init();
// Serial.print("flush ");
// Serial.print(x1);
// Serial.print(" ");
// Serial.print(y1);
// Serial.print(" ");
// Serial.print(x2);
// Serial.print(" ");
// Serial.print(y2);
// Serial.print(" ");
// Serial.println(len);
/* Update TFT */
while(len > 255) {
tft.pushColors((uint16_t *)color_p, 255);

View File

@ -16,6 +16,7 @@
#include LV_DRV_DISP_INCLUDE
#include LV_DRV_DELAY_INCLUDE
#include "../../../src/hasp_tft.h"
#include "bootscreen.h" // Sketch tab header for xbm images
/*********************
* DEFINES
@ -53,6 +54,9 @@ void tft_espi_init(uint8_t rotation)
tft.setSwapBytes(true); /* set endianess */
tft.setRotation(rotation);
tft.fillScreen(TFT_DARKCYAN);
int x = (tft.width() - logoWidth) / 2;
int y = (tft.height() - logoHeight) / 2;
tft.drawXBitmap(x, y, bootscreen, logoWidth, logoHeight, TFT_WHITE);
#ifdef USE_DMA_TO_TFT
// DMA - should work with STM32F2xx/F4xx/F7xx processors

View File

@ -20,7 +20,7 @@ extra_configs =
platformio_override.ini
; -- Put active [env] files in this dir to be included in the build menu
user_setups/active/*.ini
user_setups/*/*.ini
; user_setups/*/*.ini
default_envs =
; Uncomment the needed environments in platformio_override.ini
@ -115,6 +115,7 @@ esp32_flags=
stm32_flags=
${env.build_flags}
-D IRAM_ATTR= ; No IRAM_ATTR available on STM32
-D ICACHE_RAM_ATTR=
-D STM32
-D STREAMUTILS_USE_EEPROM_UPDATE=1 ; update cell only when changed
-D MQTT_MAX_PACKET_SIZE=2048 ; longer PubSubClient messages

View File

@ -173,7 +173,7 @@ void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const c
uint8_t objid;
if(FindIdFromObj(obj, &pageid, &objid)) {
dispatch_obj_attribute_str(pageid, objid, attribute, data);
dispatch_send_obj_attribute_str(pageid, objid, attribute, data);
}
}
@ -301,25 +301,47 @@ void haspReconnect()
lv_obj_set_hidden(obj, true);*/
}
void haspProgress(uint8_t val, char * msg)
String progress_str((char *)0);
void haspProgressVal(uint8_t val)
{
lv_obj_t * layer = lv_disp_get_layer_sys(NULL);
lv_obj_t * bar = hasp_find_obj_from_id(255, 10);
if(val == 255) {
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
if(bar) {
lv_obj_set_hidden(bar, true);
}
} else {
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100);
if(bar) {
lv_obj_set_hidden(bar, false);
if(layer && bar) {
if(val == 255) {
if(!lv_obj_get_hidden(bar)) {
lv_obj_set_hidden(bar, true);
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, "");
#if defined(ARCH_ARDUINO_ESP32) || defined(ARCH_ARDUINO_ESP8266)
progress_str.clear();
#endif
}
} else {
if(lv_obj_get_hidden(bar)) {
lv_obj_set_hidden(bar, false);
lv_obj_set_style_local_bg_opa(layer, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100);
}
lv_bar_set_value(bar, val, LV_ANIM_OFF);
lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, msg);
}
lv_task_handler(); /* let the GUI do its work */
}
lv_tick_inc(30);
}
void haspProgressMsg(const char * msg)
{
lv_obj_t * bar = hasp_find_obj_from_id(255, 10);
if(bar) {
progress_str.reserve(64);
progress_str = msg;
lv_obj_set_style_local_value_str(bar, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, progress_str.c_str());
lv_task_handler(); /* let the GUI do its work */
}
}
void haspProgressMsg(const __FlashStringHelper * msg)
{
haspProgressMsg(String(msg).c_str());
}
/**
@ -546,27 +568,34 @@ void hasp_background(uint16_t pageid, uint16_t imageid)
*/
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
{
uint8_t eventid;
char buffer[64];
snprintf(buffer, sizeof(buffer), PSTR("HASP: "));
switch(event) {
case LV_EVENT_PRESSED:
eventid = HASP_EVENT_DOWN;
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
break;
case LV_EVENT_CLICKED:
// UP = the same object was release then was pressed and press was not lost!
eventid = HASP_EVENT_UP;
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
break;
case LV_EVENT_SHORT_CLICKED:
eventid = HASP_EVENT_SHORT;
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
break;
case LV_EVENT_LONG_PRESSED:
eventid = HASP_EVENT_LONG;
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
eventid = HASP_EVENT_HOLD;
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
break;
case LV_EVENT_PRESS_LOST:
eventid = HASP_EVENT_LOST;
memcpy_P(buffer, PSTR("LOST"), sizeof(buffer));
break;
case LV_EVENT_PRESSING:
@ -585,7 +614,7 @@ void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
Log.notice(buffer, event);
return;
default:
strcat_P(buffer, PSTR("HASP : Unknown Event % d occured"));
strcat_P(buffer, PSTR("HASP : Unknown Event occured"));
Log.warning(buffer, event);
return;
}
@ -595,7 +624,8 @@ void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
mqtt_send_state(F("wakeuptouch"), buffer);
#endif
} else {
hasp_send_obj_attribute_event(obj, buffer);
// hasp_send_obj_attribute_event(obj, buffer);
dispatch_send_object_event(current_page, (uint8_t)obj->user_data, eventid);
}
}
@ -697,6 +727,20 @@ void haspSetPage(uint8_t pageid)
}
}
void hasp_set_group_objects(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj)
{
bool state = dispatch_get_event_state(eventid);
for(uint8_t page = 0; page < HASP_NUM_PAGES; page++) {
uint8_t startid = 100 + groupid * 10; // groups start at id 100
for(uint8_t objid = startid; objid < (startid + 10); objid++) {
lv_obj_t * obj = hasp_find_obj_from_id(page, objid);
if(obj && obj != src_obj) { // skip source object, if set
lv_obj_set_state(obj, state ? LV_STATE_PRESSED | LV_STATE_CHECKED : LV_STATE_DEFAULT);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id)

View File

@ -19,7 +19,7 @@ extern "C" {
* INCLUDES
*********************/
#if HASP_USE_APP>0
#if HASP_USE_APP > 0
/*********************
* DEFINES
@ -29,6 +29,19 @@ extern "C" {
* TYPEDEFS
**********************/
enum hasp_event_t { // even = released, odd = pressed
HASP_EVENT_OFF = 0,
HASP_EVENT_ON = 1,
HASP_EVENT_UP = 2,
HASP_EVENT_DOWN = 3,
HASP_EVENT_SHORT = 4,
HASP_EVENT_LONG = 5,
HASP_EVENT_LOST = 6,
HASP_EVENT_HOLD = 7,
HASP_EVENT_DOUBLE = 8
};
enum lv_hasp_obj_type_t {
LV_HASP_BUTTON = 10,
LV_HASP_CHECKBOX = 11,
@ -51,12 +64,12 @@ enum lv_hasp_obj_type_t {
LV_HASP_IMAGE = 60,
LV_HASP_TABVIEW = 70,
LV_HASP_TABVIEW = 70,
LV_HASP_TILEVIEW = 71,
LV_HASP_CONTAINER = 90,
LV_HASP_OBJECT = 91,
LV_HASP_PAGE = 92,
LV_HASP_OBJECT = 91,
LV_HASP_PAGE = 92,
};
/**********************
@ -80,13 +93,14 @@ void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const c
void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t val);
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 hasp_set_group_objects(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj);
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id);
void haspReconnect(void);
void haspDisconnect(void);
void haspWakeUp(void);
void haspProgress(uint8_t val, char * msg);
void haspProgressVal(uint8_t val);
bool haspGetConfig(const JsonObject & settings);
bool haspSetConfig(const JsonObject & settings);
@ -106,4 +120,7 @@ void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);
} /* extern "C" */
#endif
void haspProgressMsg(const char * msg);
void haspProgressMsg(const __FlashStringHelper * msg);
#endif /*HASP_H*/

View File

@ -199,7 +199,7 @@ void configWriteConfig()
bool writefile = false;
bool changed = false;
#if HASP_USE_WIFI>0
#if HASP_USE_WIFI > 0
if(settings[F("wifi")].as<JsonObject>().isNull()) settings.createNestedObject(F("wifi"));
changed = wifiGetConfig(settings[F("wifi")]);
if(changed) {
@ -207,7 +207,7 @@ void configWriteConfig()
writefile = true;
}
#endif
#if HASP_USE_MQTT>0
#if HASP_USE_MQTT > 0
if(settings[F("mqtt")].as<JsonObject>().isNull()) settings.createNestedObject(F("mqtt"));
changed = mqttGetConfig(settings[F("mqtt")]);
if(changed) {
@ -216,7 +216,7 @@ void configWriteConfig()
writefile = true;
}
#endif
#if HASP_USE_TELNET>0
#if HASP_USE_TELNET > 0
if(settings[F("telnet")].as<JsonObject>().isNull()) settings.createNestedObject(F("telnet"));
changed = telnetGetConfig(settings[F("telnet")]);
if(changed) {
@ -225,7 +225,7 @@ void configWriteConfig()
writefile = true;
}
#endif
#if HASP_USE_MDNS>0
#if HASP_USE_MDNS > 0
if(settings[F("mdns")].as<JsonObject>().isNull()) settings.createNestedObject(F("mdns"));
changed = mdnsGetConfig(settings[F("mdns")]);
if(changed) {
@ -233,7 +233,7 @@ void configWriteConfig()
writefile = true;
}
#endif
#if HASP_USE_HTTP>0
#if HASP_USE_HTTP > 0
if(settings[F("http")].as<JsonObject>().isNull()) settings.createNestedObject(F("http"));
changed = httpGetConfig(settings[F("http")]);
if(changed) {
@ -325,7 +325,7 @@ void configSetup()
if(i == 0) {
#if HASP_USE_SPIFFS > 0
EepromStream eepromStream(0, 2048);
DeserializationError error = deserializeJson(settings, eepromStream);
DeserializationError err = deserializeJson(settings, eepromStream);
#else
continue;
#endif
@ -348,23 +348,23 @@ void configSetup()
haspSetConfig(settings[F("hasp")]);
// otaGetConfig(settings[F("ota")]);
#if HASP_USE_WIFI>0
#if HASP_USE_WIFI > 0
Log.verbose(F("Loading WiFi settings"));
wifiSetConfig(settings[F("wifi")]);
#endif
#if HASP_USE_MQTT>0
#if HASP_USE_MQTT > 0
Log.verbose(F("Loading MQTT settings"));
mqttSetConfig(settings[F("mqtt")]);
#endif
#if HASP_USE_TELNET>0
#if HASP_USE_TELNET > 0
Log.verbose(F("Loading Telnet settings"));
telnetSetConfig(settings[F("telnet")]);
#endif
#if HASP_USE_MDNS>0
#if HASP_USE_MDNS > 0
Log.verbose(F("Loading MDNS settings"));
mdnsSetConfig(settings[F("mdns")]);
#endif
#if HASP_USE_HTTP>0
#if HASP_USE_HTTP > 0
Log.verbose(F("Loading HTTP settings"));
httpSetConfig(settings[F("http")]);
#endif

View File

@ -6,6 +6,7 @@
#include "hasp_dispatch.h"
#include "hasp_config.h"
#include "hasp_debug.h"
#include "hasp_gpio.h"
#include "hasp_gui.h"
#include "hasp_hal.h"
#include "hasp.h"
@ -38,7 +39,7 @@ void dispatchLoop()
void dispatchStatusUpdate()
{
#if HASP_USE_MQTT>0
#if HASP_USE_MQTT > 0
mqtt_send_statusupdate();
#endif
}
@ -48,7 +49,7 @@ void dispatchOutput(int output, bool state)
int pin = 0;
if(pin >= 0) {
Log.notice(F("PIN OUTPUT STATE %d"),state);
Log.notice(F("PIN OUTPUT STATE %d"), state);
#if defined(ARDUINO_ARCH_ESP32)
ledcWrite(99, state ? 1023 : 0); // ledChannel and value
@ -189,7 +190,6 @@ void dispatchBacklight(String strPayload)
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_state(F("light"), strPayload.c_str());
#endif
}
void dispatchCommand(String cmnd)
@ -312,12 +312,97 @@ void dispatch_button(uint8_t id, const char * event)
#if HASP_USE_MQTT > 0
mqtt_send_input(id, event);
#endif
#if HASP_USE_TASMOTA_SLAVE>0
#if HASP_USE_TASMOTA_SLAVE > 0
slave_send_input(id, event);
#endif
#endif
}
// Map events to either ON or OFF (UP or DOWN)
bool dispatch_get_event_state(uint8_t eventid)
{
switch(eventid) {
case HASP_EVENT_ON:
case HASP_EVENT_DOWN:
case HASP_EVENT_LONG:
case HASP_EVENT_HOLD:
return true;
case HASP_EVENT_OFF:
case HASP_EVENT_UP:
case HASP_EVENT_SHORT:
case HASP_EVENT_DOUBLE:
case HASP_EVENT_LOST:
default:
return false;
}
}
// Map events to their description string
void dispatch_get_event_name(uint8_t eventid, char * buffer, size_t size)
{
switch(eventid) {
case HASP_EVENT_ON:
memcpy_P(buffer, PSTR("ON"), size);
break;
case HASP_EVENT_OFF:
memcpy_P(buffer, PSTR("OFF"), size);
break;
case HASP_EVENT_UP:
memcpy_P(buffer, PSTR("UP"), size);
break;
case HASP_EVENT_DOWN:
memcpy_P(buffer, PSTR("DOWN"), size);
break;
case HASP_EVENT_SHORT:
memcpy_P(buffer, PSTR("SHORT"), size);
break;
case HASP_EVENT_LONG:
memcpy_P(buffer, PSTR("LONG"), size);
break;
case HASP_EVENT_HOLD:
memcpy_P(buffer, PSTR("HOLD"), size);
break;
case HASP_EVENT_LOST:
memcpy_P(buffer, PSTR("LOST"), size);
break;
default:
memcpy_P(buffer, PSTR("UNKNOWN"), size);
}
}
void dispatch_send_group_event(uint8_t groupid, uint8_t eventid, bool update_hasp)
{
// update outputs
gpio_set_group_outputs(groupid, eventid);
// send out value
#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: group%d = %s"), groupid, eventid);
#else
#if HASP_USE_MQTT > 0
// mqtt_send_input(id, event);
#endif
#if HASP_USE_TASMOTA_SLAVE > 0
// slave_send_input(id, event);
#endif
#endif
// update objects, except src_obj
if(update_hasp) hasp_set_group_objects(groupid, eventid, NULL);
}
void dispatch_send_object_event(uint8_t pageid, uint8_t objid, uint8_t eventid)
{
if(objid < 100) {
char eventname[16];
dispatch_get_event_name(eventid, eventname, sizeof(eventname));
dispatch_send_obj_attribute_str(pageid, objid, "event", eventname); /* Literal String */
} else {
uint8_t groupid = (objid - 100) / 10;
dispatch_send_group_event(groupid, eventid, true);
}
}
void dispatchWebUpdate(const char * espOtaUrl)
{
#if HASP_USE_OTA > 0
@ -326,7 +411,7 @@ void dispatchWebUpdate(const char * espOtaUrl)
#endif
}
void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data)
{
#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: json = {\"p[%u].b[%u].%s\":\"%s\"}"), pageid, btnid, attribute, data);
@ -425,7 +510,7 @@ void dispatchConfig(const char * topic, const char * payload)
settings.remove(F("pass")); // hide password in output
size_t size = serializeJson(doc, buffer, sizeof(buffer));
#if !defined(HASP_USE_MQTT) && !defined(HASP_USE_TASMOTA_SLAVE)
Log.notice(F("OUT: config %s = %s"),topic,buffer);
Log.notice(F("OUT: config %s = %s"), topic, buffer);
#else
#if HASP_USE_MQTT > 0
mqtt_send_state(F("config"), buffer);

View File

@ -26,6 +26,11 @@ void dispatchStatusUpdate(void);
void dispatch_button(uint8_t id, const char * event);
void IRAM_ATTR dispatch_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute, const char * data);
void dispatch_send_object_event(uint8_t pageid, uint8_t objid, uint8_t eventid);
void dispatch_send_group_event(uint8_t groupid, uint8_t eventid, bool update_hasp);
bool dispatch_get_event_state(uint8_t eventid);
void IRAM_ATTR dispatch_send_obj_attribute_str(uint8_t pageid, uint8_t btnid, const char * attribute,
const char * data);
#endif

View File

@ -7,28 +7,22 @@
#include "hasp_conf.h"
#include "hasp_gpio.h"
#include "hasp_dispatch.h"
#define HASP_NUM_GPIO_CONFIG 5
#include "hasp.h"
uint8_t gpioUsedInputCount = 0;
uint16_t gpioConfig[HASP_NUM_GPIO_CONFIG];
using namespace ace_button;
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;
uint8_t pin; // pin number
uint8_t group; // groupid
uint8_t type; // switch, button, ...
uint8_t gpio_function; // INPUT, OUTPUT, PULLUP, etc
};
// 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},
};
hasp_gpio_config_t gpioConfig[HASP_NUM_GPIO_CONFIG];
#if defined(ARDUINO_ARCH_ESP32)
class TouchConfig : public ButtonConfig {
@ -53,39 +47,48 @@ class TouchConfig : public ButtonConfig {
TouchConfig touchConfig();
#endif
static void gpio_event_cb(AceButton * button, uint8_t eventType, uint8_t buttonState)
static void gpio_event_handler(AceButton * button, uint8_t eventType, uint8_t buttonState)
{
uint8_t eventid;
char buffer[16];
switch(eventType) {
case 0: // AceButton::kEventPressed:
case AceButton::kEventPressed:
eventid = HASP_EVENT_DOWN;
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
break;
case 2: // AceButton::kEventClicked:
eventid = HASP_EVENT_SHORT;
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
break;
case AceButton::kEventDoubleClicked:
eventid = HASP_EVENT_DOUBLE;
memcpy_P(buffer, PSTR("DOUBLE"), sizeof(buffer));
break;
case 4: // AceButton::kEventLongPressed:
case AceButton::kEventLongPressed:
eventid = HASP_EVENT_LONG;
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
break;
case 5: // AceButton::kEventRepeatPressed:
case AceButton::kEventRepeatPressed:
// return; // Fix needed for switches
eventid = HASP_EVENT_HOLD;
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
break;
case 1: // AceButton::kEventReleased:
case AceButton::kEventReleased:
eventid = HASP_EVENT_UP;
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
break;
default:
eventid = HASP_EVENT_LOST;
memcpy_P(buffer, PSTR("UNKNOWN"), sizeof(buffer));
}
dispatch_button(button->getId(), buffer);
dispatch_send_group_event(gpioConfig[button->getId()].group, eventid, true);
}
void aceButtonSetup(void)
{
ButtonConfig * buttonConfig = ButtonConfig::getSystemButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setEventHandler(gpio_event_handler);
// Features
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
@ -110,21 +113,20 @@ 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 index)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
button[i] = new AceButton(pin, default_state, channel);
// button[i]->init(pin, default_state, channel);
button[i] = new AceButton(pin, default_state, index);
// button[i]->init(pin, default_state, index);
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setEventHandler(gpio_event_handler);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
@ -132,30 +134,30 @@ void gpioAddButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8
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,
Log.verbose(F("GPIO: Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index,
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);
Log.error(F("GPIO: Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, index,
HASP_NUM_INPUTS);
}
void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t channel)
void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state, uint8_t index)
{
uint8_t i;
for(i = 0; i < HASP_NUM_INPUTS; i++) {
if(!button[i]) {
button[i] = new AceButton();
button[i] = new AceButton(pin, default_state, index);
if(button[i]) {
pinMode(pin, input_mode);
ButtonConfig * buttonConfig = button[i]->getButtonConfig();
buttonConfig->setEventHandler(gpio_event_cb);
buttonConfig->setEventHandler(gpio_event_handler);
buttonConfig->setFeature(ButtonConfig::kFeatureClick);
buttonConfig->clearFeature(ButtonConfig::kFeatureDoubleClick);
buttonConfig->setFeature(ButtonConfig::kFeatureLongPress);
@ -163,83 +165,39 @@ void gpioAddTouchButton(uint8_t pin, uint8_t input_mode, uint8_t default_state,
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,
Log.verbose(F("GPIO: Button%d created on pin %d (index %d) mode %d default %d"), i, pin, index,
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);
Log.error(F("GPIO: Failed to create Button%d pin %d (index %d). All %d slots available are in use!"), i, pin, index,
HASP_NUM_INPUTS);
}
void gpioSetup()
{
aceButtonSetup();
return;
// return;
// gpioConfig[0] = PD15 * 256 + 5 + (INPUT << 3);
#if defined(ARDUINO_ARCH_ESP8266)
gpioAddButton(D2, INPUT_PULLUP, HIGH, 1);
//pinMode(D1, OUTPUT);
gpioConfig[0] = {D2, 7, HASP_GPIO_BUTTON, INPUT_PULLUP};
gpioConfig[1] = {D1, 7, HASP_GPIO_LED, OUTPUT};
// gpioAddButton(D2, INPUT_PULLUP, HIGH, 1);
// pinMode(D1, OUTPUT);
#endif
#if defined(ARDUINO_ARCH_ESP32)
// gpioAddButton(D2, INPUT, HIGH, 1);
// pinMode(D1, OUTPUT);
// gpioConfig[0] = {D2, 0, HASP_GPIO_SWITCH, INPUT};
// gpioConfig[1] = {D1, 1, HASP_GPIO_RELAY, OUTPUT};
// gpioAddButton(D2, INPUT, HIGH, 1);
// pinMode(D1, OUTPUT);
#endif
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 input_mode = gpioConfig[i].io_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;
#ifndef ARDUINO_ARCH_ESP8266
case 3:
input_mode = INPUT_PULLDOWN;
break;
#endif
default:
input_mode = INPUT;
}
switch(gpiotype) {
case HASP_GPIO_SWITCH:
case HASP_GPIO_BUTTON:
// gpioAddButton(gpioConfig[i].io_mode.pin, input_mode, gpioConfig[i].default_state,
// gpioConfig[i].group);
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);
@ -250,4 +208,88 @@ void gpioSetup()
pinMode(HASP_INPUT_PIN, INPUT);
#endif
*/
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
uint8_t input_mode;
switch(gpioConfig[i].gpio_function) {
case OUTPUT:
input_mode = OUTPUT;
break;
case INPUT_PULLUP:
input_mode = INPUT_PULLUP;
break;
#ifndef ARDUINO_ARCH_ESP8266
case INPUT_PULLDOWN:
input_mode = INPUT_PULLDOWN;
break;
#endif
default:
input_mode = INPUT;
}
switch(gpioConfig[i].type) {
case HASP_GPIO_SWITCH:
case HASP_GPIO_BUTTON:
gpioAddButton(gpioConfig[i].pin, input_mode, HIGH, i);
break;
case HASP_GPIO_SWITCH_INVERTED:
case HASP_GPIO_INPUT_BUTTON_INVERTED:
gpioAddButton(gpioConfig[i].pin, input_mode, LOW, i);
break;
case HASP_GPIO_RELAY:
case HASP_GPIO_RELAY_INVERTED:
case HASP_GPIO_LED:
case HASP_GPIO_LED_INVERTED:
pinMode(gpioConfig[i].pin, OUTPUT);
break;
case HASP_GPIO_PWM:
case HASP_GPIO_PWM_INVERTED:
// case HASP_GPIO_BACKLIGHT:
pinMode(gpioConfig[i].pin, OUTPUT);
#if defined(ARDUINO_ARCH_ESP32)
// configure LED PWM functionalitites
ledcSetup(gpioConfig[i].group, 20000, 10);
// attach the channel to the GPIO to be controlled
ledcAttachPin(gpioConfig[i].pin, gpioConfig[i].group);
#endif
break;
}
}
}
void gpio_set_group_outputs(uint8_t groupid, uint8_t eventid)
{
bool state = dispatch_get_event_state(eventid);
for(uint8_t i = 0; i < HASP_NUM_GPIO_CONFIG; i++) {
if(gpioConfig[i].group == groupid) {
switch(gpioConfig[i].type) {
case HASP_GPIO_RELAY:
case HASP_GPIO_LED:
digitalWrite(gpioConfig[i].pin, state ? HIGH : LOW);
break;
case HASP_GPIO_RELAY_INVERTED:
case HASP_GPIO_LED_INVERTED:
digitalWrite(gpioConfig[i].pin, state ? LOW : HIGH);
break;
#if defined(ARDUINO_ARCH_ESP32)
case HASP_GPIO_PWM:
ledcWrite(groupid, map(state, 0, 1, 0, 1023)); // ledChannel and value
break;
case HASP_GPIO_PWM_INVERTED:
ledcWrite(groupid, map(!state, 0, 1, 0, 1023)); // ledChannel and value
break;
#else
case HASP_GPIO_PWM:
analogWrite(gpioConfig[i].pin, map(state, 0, 1, 0, 1023));
break;
case HASP_GPIO_PWM_INVERTED:
analogWrite(gpioConfig[i].pin, map(!state, 0, 1, 0, 1023));
break;
#endif
default:;
}
}
}
}

View File

@ -9,14 +9,27 @@ extern "C" {
void gpioSetup(void);
void IRAM_ATTR gpioLoop(void);
void gpio_set_group_outputs(uint8_t groupid, uint8_t eventid);
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,
};
#define HASP_GPIO_FREE 0x00
#define HASP_GPIO_USED 0x01
#define HASP_GPIO_SWITCH 0x02
#define HASP_GPIO_SWITCH_INVERTED 0x03
#define HASP_GPIO_BUTTON 0x04
#define HASP_GPIO_INPUT_BUTTON_INVERTED 0x05
#define HASP_GPIO_COUNTER 0x06
#define HASP_GPIO_COUNTER_INVERTED 0x07
#define HASP_GPIO_ADC 0x08
#define HASP_GPIO_ADC_INVERTED 0x09
#define HASP_GPIO_RELAY 0x0A
#define HASP_GPIO_RELAY_INVERTED 0x0B
#define HASP_GPIO_LED 0x0C
#define HASP_GPIO_LED_INVERTED 0x0D
#define HASP_GPIO_PWM 0x0E
#define HASP_GPIO_PWM_INVERTED 0x0F
#define HASP_GPIO_DAC 0x10
#define HASP_GPIO_DAC_INVERTED 0x11
#define HASP_GPIO_USER 0xFF
#ifdef __cplusplus
} /* extern "C" */

View File

@ -52,7 +52,7 @@
File pFileOut;
#endif
// #define LVGL_TICK_PERIOD 30
#define LVGL_TICK_PERIOD 20
#ifndef TFT_BCKL
#define TFT_BCKL -1 // No Backlight Control
@ -75,7 +75,7 @@ static uint8_t guiRotation = TFT_ROTATION;
#if ESP32 > 0 || ESP8266 > 0
static Ticker tick; /* timer for interrupt handler */
#else
static Ticker tick(lv_tick_handler, guiTickPeriod);
static Ticker tick(lv_tick_handler, LVGL_TICK_PERIOD); // guiTickPeriod);
#endif
// static TFT_eSPI tft; // = TFT_eSPI(); /* TFT instance */
static uint16_t calData[5] = {0, 65535, 0, 65535, 0};
@ -132,10 +132,10 @@ static void IRAM_ATTR my_flush_cb(lv_disp_drv_t * disp, const lv_area_t * area,
}
/* Interrupt driven periodic handler */
static void IRAM_ATTR lv_tick_handler(void)
static void ICACHE_RAM_ATTR lv_tick_handler(void)
{
// Serial.print(".");
lv_tick_inc(guiTickPeriod);
lv_tick_inc(LVGL_TICK_PERIOD);
}
/* Reading input device (simulated encoder here) */
@ -388,7 +388,7 @@ bool IRAM_ATTR my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t *
uint16_t touchX, touchY;
bool touched;
#if TOUCH_DRIVER == 0
touched = tft_espi_get_touch(&touchX, &touchY, 600);
touched = tft_espi_get_touch(&touchX, &touchY, 300);
#elif TOUCH_DRIVER == 1
// return false;
touched = GT911_getXY(&touchX, &touchY, true);
@ -486,7 +486,7 @@ void guiSetup()
#elif defined(ARDUINO_ARCH_ESP8266)
/* allocate on heap */
static lv_disp_buf_t disp_buf;
static lv_color_t guiVdbBuffer1[5 * 512u]; // 5 KBytes
static lv_color_t guiVdbBuffer1[4 * 512u]; // 4 KBytes
// static lv_color_t guiVdbBuffer2[3 * 1024u]; // 6 KBytes
guiVDBsize = sizeof(guiVdbBuffer1) / sizeof(guiVdbBuffer1[0]);
lv_disp_buf_init(&disp_buf, guiVdbBuffer1, NULL, guiVDBsize);
@ -564,6 +564,7 @@ void guiSetup()
disp_drv.ver_res = TFT_WIDTH;
}
lv_disp_drv_register(&disp_drv);
guiStart();
/* Initialize Global progress bar*/
lv_obj_t * bar = lv_bar_create(lv_layer_sys(), NULL);
@ -580,14 +581,6 @@ void guiSetup()
lv_obj_set_style_local_bg_color(lv_layer_sys(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
lv_obj_set_style_local_bg_opa(lv_layer_sys(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
/*Initialize the graphics library's tick*/
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
tick.attach_ms(guiTickPeriod, lv_tick_handler);
#else
tick.start();
#endif
lv_tick_handler();
/*Initialize the touch pad*/
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
@ -639,34 +632,6 @@ void guiSetup()
lv_obj_set_click(cursor, false); // don't click on the cursor
lv_indev_set_cursor(mouse_indev, cursor);
// }*/
/*Initialize the graphics library's tick*/
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
#else
/*
#if defined(TIM1)
TIM_TypeDef * Instance = TIM1;
#else
TIM_TypeDef * Instance = TIM2;
#endif
*/
// Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup()
// function is finished.
/* static HardwareTimer * MyTim = new HardwareTimer(Instance);
MyTim->pause();
MyTim->setPrescaleFactor(1);
MyTim->setMode(0, TIMER_OUTPUT_COMPARE, NC);
MyTim->setOverflow(1000 * guiTickPeriod, MICROSEC_FORMAT); // MicroSec
MyTim->setCount(0,MICROSEC_FORMAT);
MyTim->refresh();
MyTim->detachInterrupt();
MyTim->attachInterrupt((void (*)(HardwareTimer *))lv_tick_handler);
MyTim->detachInterrupt(0);
MyTim->attachInterrupt(0,(void (*)(HardwareTimer *))lv_tick_handler);
MyTim->resume();*/
tick.start();
#endif
}
void IRAM_ATTR guiLoop()
@ -675,8 +640,8 @@ void IRAM_ATTR guiLoop()
tick.update();
#endif
// lv_tick_handler();
lv_task_handler(); /* let the GUI do its work */
lv_task_handler();
guiCheckSleep();
#if TOUCH_DRIVER == 1
@ -684,8 +649,25 @@ void IRAM_ATTR guiLoop()
#endif
}
void guiStart()
{
/*Initialize the graphics library's tick*/
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
tick.attach_ms(LVGL_TICK_PERIOD, lv_tick_handler);
#else
tick.start();
#endif
}
void guiStop()
{}
{
/*Deinitialize the graphics library's tick*/
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
tick.detach();
#else
tick.stop();
#endif
}
bool guiGetBacklight()
{

View File

@ -19,6 +19,7 @@
void guiTakeScreenshot();
void guiSetup();
void guiStart(void);
void guiLoop(void);
void guiStop(void);

View File

@ -45,7 +45,7 @@ char httpUser[32] = "";
char httpPassword[32] = "";
#define HTTP_PAGE_SIZE (6 * 256)
#if defined(STM32F4xx) && HASP_USE_ETHERNET>0
#if defined(STM32F4xx) && HASP_USE_ETHERNET > 0
#include <EthernetWebServer_STM32.h>
EthernetWebServer webServer(80);
#endif
@ -621,10 +621,13 @@ String getContentType(String filename)
static unsigned long htppLastLoopTime = 0;
void webUploadProgress()
{
long t = webServer.header("Content-Length").toInt();
if(millis() - htppLastLoopTime >= 1250) {
Log.verbose(F(" * Uploaded %u bytes"), upload->totalSize + upload->currentSize);
Log.verbose(F(" * Uploaded %u bytes / %d"), upload->totalSize + upload->currentSize, t);
htppLastLoopTime = millis();
}
if(t > 0) t = (upload->totalSize + upload->currentSize) * 100 / t;
haspProgressVal(t);
}
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
@ -635,6 +638,7 @@ void webUpdatePrintError()
StringStream stream((String &)output);
Update.printError(stream);
Log.error(F("HTTP: %s"), output.c_str());
haspProgressMsg(output.c_str());
}
void webUpdateReboot()
@ -666,6 +670,7 @@ void webHandleFirmwareUpdate()
if(upload->status == UPLOAD_FILE_START) {
if(!httpIsAuthenticated(F("update"))) return;
Log.notice(F("Update: %s"), upload->filename.c_str());
haspProgressMsg(upload->filename.c_str());
// WiFiUDP::stopAll();
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
// if(!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max available size
@ -722,6 +727,7 @@ void handleFileUpload()
upload = &webServer.upload();
if(upload->status == UPLOAD_FILE_START) {
if(!httpIsAuthenticated(F("fileupload"))) return;
Log.verbose(F("Total size: %s"), webServer.headerName(0).c_str());
String filename((char *)0);
filename.reserve(128);
filename = upload->filename;
@ -732,6 +738,7 @@ void handleFileUpload()
if(filename.length() < 32) {
fsUploadFile = filesystem->open(filename, "w");
Log.notice(F("handleFileUpload Name: %s"), filename.c_str());
haspProgressMsg(fsUploadFile.name());
} else {
Log.error(F("Filename %s is too long"), filename.c_str());
}
@ -749,6 +756,7 @@ void handleFileUpload()
Log.verbose(F("Uploaded %s (%u bytes)"), fsUploadFile.name(), upload->totalSize);
fsUploadFile.close();
}
haspProgressVal(255);
// Redirect to /config/hasp page. This flushes the web buffer and frees the memory
webServer.sendHeader(String(F("Location")), String(F("/config/hasp")), true);
@ -1638,7 +1646,12 @@ void httpSetup()
// first callback is called after the request has ended with all parsed arguments
// second callback handles file uploads at that location
webServer.on(
F("/edit"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, handleFileUpload);
F("/edit"), HTTP_POST,
[]() {
webServer.send(200, "text/plain", "");
Log.verbose(F("Headers: %d"), webServer.headers());
},
handleFileUpload);
#endif
// get heap status, analog input value and all GPIO statuses in one json call
@ -1680,7 +1693,12 @@ void httpSetup()
webServer.on(F("/firmware"), webHandleFirmware);
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
webServer.on(
F("/update"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, webHandleFirmwareUpdate);
F("/update"), HTTP_POST,
[]() {
webServer.send(200, "text/plain", "");
Log.verbose(F("Total size: %s"), webServer.hostHeader().c_str());
},
webHandleFirmwareUpdate);
webServer.on(F("/espfirmware"), httpHandleEspFirmware);
#endif
webServer.on(F("/reboot"), httpHandleReboot);
@ -1696,6 +1714,11 @@ void httpSetup()
webServer.on(F("/config"), webHandleConfig);
webServer.onNotFound(httpHandleNotFound);
// ask server to track these headers
const char * headerkeys[] = {"Content-Length"}; // "Authentication"
size_t headerkeyssize = sizeof(headerkeys) / sizeof(char *);
webServer.collectHeaders(headerkeys, headerkeyssize);
Log.verbose(F("HTTP: Setup Complete"));
webStart();
}

View File

@ -7,14 +7,15 @@
#include "hasp_debug.h"
#include "hasp_dispatch.h"
#include "hasp_ota.h"
#include "hasp.h"
#include "hasp_conf.h"
#if HASP_USE_MQTT>0
#if HASP_USE_MQTT > 0
#include "hasp_mqtt.h"
#endif
#if HASP_USE_MDNS>0
#if HASP_USE_MDNS > 0
#include "hasp_mdns.h"
#endif
@ -56,20 +57,28 @@ void otaSetup()
}
Log.notice(F("OTA: Start update"));
haspProgressVal(0);
haspProgressMsg(F("OTA: Firmware Update"));
// dispatchPage("0");
otaPrecentageComplete = 0;
// haspSetAttr("p[0].b[1].txt", "\"ESP OTA Update\"");
});
ArduinoOTA.onEnd([]() {
otaPrecentageComplete = 100;
haspProgressMsg(F("Applying Firmware & Reboot"));
haspProgressVal(100);
otaProgress();
otaPrecentageComplete = -1;
// dispatchPage("0");
// haspSetAttr("p[0].b[1].txt", "\"ESP OTA Update\\rComplete!\"");
dispatchReboot(true);
setup();
//dispatchReboot(true);
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
if(total != 0) otaPrecentageComplete = progress * 100 / total;
if(total != 0) {
otaPrecentageComplete = progress * 100 / total;
haspProgressVal(otaPrecentageComplete);
}
// haspSetAttr("p[0].b[1].txt", "\"ESP OTA Update\\rProgress: " + String(progress / (total / 100)) + "%\"");
});
@ -87,7 +96,7 @@ void otaSetup()
else if(error == OTA_END_ERROR)
Log.error(F("OTA: ERROR - End Failed"));
// haspSetAttr("p[0].b[1].txt", "\"ESP OTA FAILED\"");
delay(5000);
// delay(5000);
// haspSendCmd("page " + String(nextionActivePage));
});
@ -107,7 +116,7 @@ void otaSetup()
#endif
// ArduinoOTA.setTimeout(1000);
#endif
ArduinoOTA.setRebootOnSuccess(true);
ArduinoOTA.setRebootOnSuccess(false); // We do that
ArduinoOTA.begin();
Log.notice(F("OTA: Over the Air firmware update ready"));

View File

@ -4,7 +4,7 @@
#include "hasp_conf.h"
#if HASP_USE_WIFI>0
#if HASP_USE_WIFI > 0
#include "hasp_debug.h"
#include "hasp_config.h"
@ -57,6 +57,7 @@ void wifiConnected(IPAddress ipaddress)
Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str());
#endif
Log.verbose(F("WIFI: Connected = %s"), WiFi.status() == WL_CONNECTED ? PSTR("yes") : PSTR("no"));
haspProgressVal(255);
// if(isConnected) {
// mqttReconnect();
@ -69,7 +70,9 @@ void wifiConnected(IPAddress ipaddress)
void wifiDisconnected(const char * ssid, uint8_t reason)
{
wifiReconnectCounter++;
if(wifiReconnectCounter > 45) {
haspProgressVal(wifiReconnectCounter * 3);
haspProgressMsg(F("Wifi Disconnected"));
if(wifiReconnectCounter > 33) {
Log.error(F("WIFI: Retries exceed %u: Rebooting..."), wifiReconnectCounter);
dispatchReboot(false);
}

View File

@ -183,5 +183,5 @@ void loop()
mainLastLoopTime += 1000;
}
delay(3);
delay(1);
}

View File

@ -8,8 +8,8 @@
[env:d1mini32-lolintft24]
platform = espressif32@^1.12.0
board = wemos_d1_mini32
upload_port = COM5 ; To change the port, use platform_override.ini
monitor_port = COM5 ; To change the port, use platform_override.ini
;upload_port = COM5 ; To change the port, use platform_override.ini
;monitor_port = COM5 ; To change the port, use platform_override.ini
board_build.partitions = esp32_partition_app1280k_spiffs1472k.csv
build_flags =

View File

@ -8,8 +8,8 @@
[env:d1mini-lolintft24]
platform = espressif8266@^2.4.0 ;@2.3.2
board = d1_mini
upload_port = COM7 ; To change the port, use platform_override.ini
monitor_port = COM7 ; To change the port, use platform_override.ini
;upload_port = COM7 ; To change the port, use platform_override.ini
;monitor_port = COM7 ; To change the port, use platform_override.ini
board_build.f_flash = 40000000L
board_build.flash_mode = dout
board_build.ldscript = eagle.flash.4m2m.ld ; 2Mb Spiffs