From fe2c50a5cb0a99a06fa9ef4654af842c4c5f1626 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sun, 2 Feb 2020 13:24:27 +0100 Subject: [PATCH] Implement snapshot --- include/lv_conf.h | 11 ++++- src/hasp_dispatch.cpp | 5 +++ src/hasp_gui.cpp | 96 ++++++++++++++++++++++++++++++++++++------- src/hasp_gui.h | 1 + src/main.cpp | 8 ++-- 5 files changed, 101 insertions(+), 20 deletions(-) diff --git a/include/lv_conf.h b/include/lv_conf.h index 4ebdb107..abb66403 100644 --- a/include/lv_conf.h +++ b/include/lv_conf.h @@ -164,6 +164,15 @@ typedef void * lv_group_user_data_t; #if LV_USE_FILESYSTEM /*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ typedef void * lv_fs_drv_user_data_t; + +/*File system interface*/ +#define LV_USE_FS_IF 1 +#if LV_USE_FS_IF +# define LV_FS_IF_FATFS '\0' +# define LV_FS_IF_PC '\0' +# define LV_FS_IF_SPIFFS 'F' +#endif /*LV_USE_FS_IF*/ + #endif /*1: Add a `user_data` to drivers and objects*/ @@ -329,7 +338,7 @@ typedef void * lv_indev_drv_user_data_t; /*Type of user data in the i * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ * LV_FONT_DECLARE(my_font_2) */ -#define LV_FONT_CUSTOM_DECLARE static lv_font_t *my_font; +#define LV_FONT_CUSTOM_DECLARE static lv_font_t *my_font[5]; /*Always set a default font from the built-in fonts*/ #define LV_FONT_DEFAULT &lv_font_unscii_8 diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp index 7e4a61e3..a31538a2 100644 --- a/src/hasp_dispatch.cpp +++ b/src/hasp_dispatch.cpp @@ -57,6 +57,11 @@ void dispatchCommand(String cmnd) return; } + if(cmnd == F("screenshot")) { + guiTakeScreenshot("/screenhot.bmp"); + return; + } + if(cmnd == F("reboot") || cmnd == F("restart")) { haspReboot(true); return; diff --git a/src/hasp_gui.cpp b/src/hasp_gui.cpp index 90abdd1c..5619c7ab 100644 --- a/src/hasp_gui.cpp +++ b/src/hasp_gui.cpp @@ -18,6 +18,13 @@ #include "hasp_gui.h" #include "hasp.h" +#if LV_USE_HASP_SPIFFS +#if defined(ARDUINO_ARCH_ESP32) +#include "SPIFFS.h" +#endif +#include // Include the SPIFFS library +#endif + #define LVGL_TICK_PERIOD 30 // 30 uint16_t guiSleepTime = 150; // 0.1 second resolution @@ -28,12 +35,19 @@ TFT_eSPI tft = TFT_eSPI(); /* TFT instance */ uint16_t calData[5] = {0, 65535, 0, 65535, 0}; bool guiAutoCalibrate = true; +static File pFileOut; +static bool bSnapshot; +static uint32_t DISP_IMPL_lvgl_formatPixel(lv_color_t color); + bool IRAM_ATTR guiCheckSleep() { bool shouldSleep = lv_disp_get_inactive_time(NULL) > guiSleepTime * 100; if(shouldSleep && !guiSleeping) { dispatchIdle(F("LONG")); guiSleeping = true; + } else if(!shouldSleep && guiSleeping) { + dispatchIdle(F("OFF")); + guiSleeping = false; } return shouldSleep; } @@ -53,17 +67,40 @@ void tft_espi_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * c { uint16_t c; - tft.startWrite(); /* Start new TFT transaction */ - tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), - (area->y2 - area->y1 + 1)); /* set the working window */ - for(int y = area->y1; y <= area->y2; y++) { - for(int x = area->x1; x <= area->x2; x++) { - c = color_p->full; - tft.writeColor(c, 1); - color_p++; + if(bSnapshot == true) { + // uint32_t data; + uint8_t pixel[4]; + pixel[3] = 0xFF; + + for(int y = area->y1; y <= area->y2; y++) { + for(int x = area->x1; x <= area->x2; x++) { + /* Function for converting LittlevGL pixel format to RGB888 */ + // data = DISP_IMPL_lvgl_formatPixel(*color_p); + + pixel[0] = (LV_COLOR_GET_B(*color_p) * 263 + 7) >> 5; + pixel[1] = (LV_COLOR_GET_G(*color_p) * 259 + 3) >> 6; + pixel[2] = (LV_COLOR_GET_R(*color_p) * 263 + 7) >> 5; + pixel[3] = 0xFF; + + pFileOut.write(pixel, sizeof(pixel)); + color_p++; + } } + + } else { + + tft.startWrite(); /* Start new TFT transaction */ + tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), + (area->y2 - area->y1 + 1)); /* set the working window */ + for(int y = area->y1; y <= area->y2; y++) { + for(int x = area->x1; x <= area->x2; x++) { + c = color_p->full; + tft.writeColor(c, 1); + color_p++; + } + } + tft.endWrite(); /* terminate TFT transaction */ } - tft.endWrite(); /* terminate TFT transaction */ lv_disp_flush_ready(disp); /* tell lvgl that flushing is done */ } @@ -106,10 +143,6 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) } bool shouldSleep = guiCheckSleep(); - if(!shouldSleep && guiSleeping) { - dispatchIdle(F("OFF")); - guiSleeping = false; - } // Ignore first press? @@ -333,4 +366,39 @@ bool guiSetConfig(const JsonObject & settings) Serial.println(); return changed; -} \ No newline at end of file +} + +/** Flush buffer. + * + * Flush buffer into a binary file. + * + * @note: data pixel should be formated to uint32_t RGBA. Imagemagick requirements. + * + * @param[in] pFileName Output binary file name. + * + */ +void guiTakeScreenshot(const char * pFileName) +{ + pFileOut = SPIFFS.open(pFileName, "w"); + + uint8_t bmpheader[138] = {0x42, 0x4D, 0x8A, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x7C, + 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xC0, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x20, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x42, 0x47, 0x52, 0x73}; + + pFileOut.write(bmpheader, sizeof(bmpheader)); + + if(pFileOut == NULL) { + printf(("[Display] error: %s cannot be opened", pFileName)); + return; + } + + bSnapshot = true; + lv_obj_invalidate(lv_scr_act()); + lv_refr_now(NULL); /* Will call our disp_drv.disp_flush function */ + bSnapshot = false; + + pFileOut.close(); + printf(("[Display] data flushed to %s", pFileName)); +} diff --git a/src/hasp_gui.h b/src/hasp_gui.h index 0261f804..6a3b58de 100644 --- a/src/hasp_gui.h +++ b/src/hasp_gui.h @@ -11,6 +11,7 @@ void guiLoop(void); void guiStop(void); void guiCalibrate(); +void guiTakeScreenshot(const char * pFileName); bool guiGetConfig(const JsonObject & settings); bool guiSetConfig(const JsonObject & settings); diff --git a/src/main.cpp b/src/main.cpp index efe3eaa6..1f2558ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,8 +44,6 @@ void setup() /* Read Config File */ DynamicJsonDocument settings(1024); - // configGetConfig(doc); - // JsonObject settings = doc.as(); configSetup(settings); if(!settings[F("pins")][F("TFT_BCKL")].isNull()) { @@ -102,7 +100,7 @@ void loop() // sdcardLoop(); #endif - configLoop(); + // configLoop(); /* Graphics Loops */ // tftLoop(); @@ -127,8 +125,8 @@ void loop() mdnsLoop(wifiIsConnected); #endif - // otaLoop(); + // otaLoop(wifiIsConnected); #endif - delay(5); + delay(1); } \ No newline at end of file