From 76b9be4d9795c54743760f36a2476d483b2d075f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 6 Feb 2024 19:53:58 +0100 Subject: [PATCH] Add Win32Drv GDI port --- include/hasp_conf.h | 2 + include/lv_drv_conf.h | 6 +- src/dev/win32/hasp_win32.cpp | 10 +- src/dev/win32/hasp_win32.h | 2 + src/drv/tft/tft_driver.h | 3 + src/drv/tft/tft_driver_win32drv.cpp | 109 +++++++++++++++++++ src/drv/tft/tft_driver_win32drv.h | 44 ++++++++ src/main_pc.cpp | 20 +++- user_setups/win32/windows_gdi_64bits.ini | 131 +++++++++++++++++++++++ 9 files changed, 321 insertions(+), 6 deletions(-) create mode 100644 src/drv/tft/tft_driver_win32drv.cpp create mode 100644 src/drv/tft/tft_driver_win32drv.h create mode 100644 user_setups/win32/windows_gdi_64bits.ini diff --git a/include/hasp_conf.h b/include/hasp_conf.h index ef832b69..a5619c46 100644 --- a/include/hasp_conf.h +++ b/include/hasp_conf.h @@ -384,6 +384,8 @@ static WiFiSpiClass WiFi; #define halRestartMcu() #if USE_MONITOR #define millis SDL_GetTicks +#elif USE_WIN32DRV +#define millis Win32Millis #endif #define DEC 10 diff --git a/include/lv_drv_conf.h b/include/lv_drv_conf.h index cb5bd603..3afc0d92 100644 --- a/include/lv_drv_conf.h +++ b/include/lv_drv_conf.h @@ -125,7 +125,11 @@ #define USE_WINDOWS 0 #endif -#if USE_WINDOWS +#ifndef USE_WIN32DRV +#define USE_WINDOWS 0 +#endif + +#if USE_WINDOWS || USE_WIN32DRV #define WINDOW_HOR_RES 480 #define WINDOW_VER_RES 320 #endif diff --git a/src/dev/win32/hasp_win32.cpp b/src/dev/win32/hasp_win32.cpp index f089307c..46051804 100644 --- a/src/dev/win32/hasp_win32.cpp +++ b/src/dev/win32/hasp_win32.cpp @@ -13,6 +13,8 @@ #if USE_MONITOR #include "display/monitor.h" +#elif USE_WIN32DRV +#include "win32drv/win32drv.h" #endif namespace dev { @@ -52,7 +54,8 @@ void Win32Device::set_hostname(const char* hostname) _hostname = hostname; #if USE_MONITOR monitor_title(hostname); - // SDL_SetWindowTitle(monitor.window, hostname); +#elif USE_WIN32DRV + lv_win32_set_title(hostname); #endif } const char* Win32Device::get_core_version() @@ -156,6 +159,11 @@ long Win32Device::get_uptime() } // namespace dev +long Win32Millis() +{ + return GetTickCount64(); +} + dev::Win32Device haspDevice; #endif // WINDOWS diff --git a/src/dev/win32/hasp_win32.h b/src/dev/win32/hasp_win32.h index 0c64e1f9..5e59ea73 100644 --- a/src/dev/win32/hasp_win32.h +++ b/src/dev/win32/hasp_win32.h @@ -91,6 +91,8 @@ class Win32Device : public BaseDevice { } // namespace dev +extern long Win32Millis(); + using dev::Win32Device; extern dev::Win32Device haspDevice; diff --git a/src/drv/tft/tft_driver.h b/src/drv/tft/tft_driver.h index 0c0d5814..18eaa756 100644 --- a/src/drv/tft/tft_driver.h +++ b/src/drv/tft/tft_driver.h @@ -80,6 +80,9 @@ class BaseTft { #elif USE_MONITOR && (defined(WINDOWS) || defined(POSIX)) // #warning Building for SDL2 #include "tft_driver_sdl2.h" +#elif USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX)) +// #warning Building for Win32Drv +#include "tft_driver_win32drv.h" #else // #warning Building for Generic Tfts using dev::BaseTft; diff --git a/src/drv/tft/tft_driver_win32drv.cpp b/src/drv/tft/tft_driver_win32drv.cpp new file mode 100644 index 00000000..709ed054 --- /dev/null +++ b/src/drv/tft/tft_driver_win32drv.cpp @@ -0,0 +1,109 @@ +/* MIT License - Copyright (c) 2019-2022 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#if USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX)) + +#include "hasplib.h" +#include "lvgl.h" + +#include "win32drv/win32drv.h" + +#include "drv/tft/tft_driver.h" +#include "tft_driver_win32drv.h" + +#include "dev/device.h" +#include "hasp_debug.h" + +#ifdef HASP_CUSTOMIZE_BOOTLOGO +#include "custom/bootlogo.h" // Sketch tab header for xbm images +#else +#include "custom/bootlogo_template.h" // Sketch tab header for xbm images +#endif + +namespace dev { + +/** + * A task to measure the elapsed time for LittlevGL + * @param data unused + * @return never return + */ +static DWORD tick_thread(void* data) +{ + (void)data; + + while(1) { + Sleep(5); /*Sleep for 5 millisecond*/ + lv_tick_inc(5); /*Tell LittelvGL that 5 milliseconds were elapsed*/ + } + + return 0; +} + +int32_t TftWin32Drv::width() +{ + return _width; +} +int32_t TftWin32Drv::height() +{ + return _height; +} + +void TftWin32Drv::init(int32_t w, int h) +{ + _width = w; + _height = h; + + /* Add a display + * Use the 'win32drv' driver which creates window on PC's monitor to simulate a display + * The following input devices are handled: mouse, keyboard, mousewheel */ + lv_win32_init(0, SW_SHOWNORMAL, w, h, 0); + lv_win32_set_title(haspDevice.get_hostname()); + + /* Tick init. + * You have to call 'lv_tick_inc()' in periodically to inform LittelvGL about how much time were elapsed + * Create a Windows thread to do this*/ + CreateThread(NULL, 0, tick_thread, NULL, 0, NULL); +} +void TftWin32Drv::show_info() +{ + splashscreen(); + + unsigned long version = GetVersion(); + unsigned long major = LOBYTE(LOWORD(version)); + unsigned long minor = HIBYTE(LOWORD(version)); + unsigned long build = 0; + if(version < 0x80000000) build = HIWORD(version); + LOG_VERBOSE(TAG_TFT, F("Driver : Win32Drv")); + LOG_VERBOSE(TAG_TFT, F("Windows Version: %d.%d.%d"), major, minor, build); +} + +void TftWin32Drv::splashscreen() +{ + uint8_t fg[] = logoFgColor; + uint8_t bg[] = logoBgColor; + lv_color_t fgColor = lv_color_make(fg[0], fg[1], fg[2]); + lv_color_t bgColor = lv_color_make(bg[0], bg[1], bg[2]); + lv_win32_splashscreen(logoImage, logoWidth, logoHeight, lv_color_to32(fgColor), lv_color_to32(bgColor)); +} +void TftWin32Drv::set_rotation(uint8_t rotation) +{} +void TftWin32Drv::set_invert(bool invert) +{} +void TftWin32Drv::flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p) +{ + lv_disp_flush_ready(disp); +} +bool TftWin32Drv::is_driver_pin(uint8_t pin) +{ + return false; +} +const char* TftWin32Drv::get_tft_model() +{ + return "Win32Drv"; +} + +} // namespace dev + +dev::TftWin32Drv haspTft; + +#endif // WINDOWS || POSIX diff --git a/src/drv/tft/tft_driver_win32drv.h b/src/drv/tft/tft_driver_win32drv.h new file mode 100644 index 00000000..89dd4223 --- /dev/null +++ b/src/drv/tft/tft_driver_win32drv.h @@ -0,0 +1,44 @@ +/* MIT License - Copyright (c) 2019-2022 Francis Van Roie + For full license information read the LICENSE file in the project folder */ + +#ifndef HASP_WIN32DRV_DRIVER_H +#define HASP_WIN32DRV_DRIVER_H + +#include "tft_driver.h" + +#if USE_WIN32DRV && (defined(WINDOWS) || defined(POSIX)) +// #warning Building H driver WIN32DRV + +#include "lvgl.h" + +namespace dev { + +class TftWin32Drv : BaseTft { + public: + void init(int w, int h); + void show_info(); + void splashscreen(); + + void set_rotation(uint8_t rotation); + void set_invert(bool invert); + + void flush_pixels(lv_disp_drv_t* disp, const lv_area_t* area, lv_color_t* color_p); + bool is_driver_pin(uint8_t pin); + + const char* get_tft_model(); + + int32_t width(); + int32_t height(); + + private: + int32_t _width, _height; +}; + +} // namespace dev + +using dev::TftWin32Drv; +extern dev::TftWin32Drv haspTft; + +#endif // defined(WINDOWS) || defined(POSIX) + +#endif // HASP_SDL2_DRIVER_H diff --git a/src/main_pc.cpp b/src/main_pc.cpp index ff155bcb..322fb24b 100644 --- a/src/main_pc.cpp +++ b/src/main_pc.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include // MSDN recommends against using getcwd & chdir names #define cwd _getcwd #define cd _chdir @@ -35,7 +37,6 @@ #include "dev/device.h" bool isConnected; -bool isRunning = 1; uint8_t mainLoopCounter = 0; unsigned long mainLastLoopTime = 0; @@ -268,6 +269,12 @@ int main(int argc, char* argv[]) SDL_Init(0); // Needs to be initialized for GetPerfPath cd(SDL_GetPrefPath("hasp", "hasp")); SDL_Quit(); // We'll properly init later +#elif USE_WIN32DRV + if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, buf))) { + PathAppendA(buf, "hasp"); + PathAppendA(buf, "hasp"); + cd(buf); + } #endif std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl; @@ -377,11 +384,16 @@ int main(int argc, char* argv[]) setup(); - LOG_TRACE(TAG_MAIN, "loop started"); - while(isRunning) { +#if USE_MONITOR + while(1) { loop(); } - LOG_TRACE(TAG_MAIN, "main loop completed"); +#elif USE_WIN32DRV + extern bool lv_win32_quit_signal; + while(!lv_win32_quit_signal) { + loop(); + } +#endif #if defined(WINDOWS) WriteConsole(std_out, "bye\n\n", 3, NULL, NULL); diff --git a/user_setups/win32/windows_gdi_64bits.ini b/user_setups/win32/windows_gdi_64bits.ini new file mode 100644 index 00000000..38d8b4c3 --- /dev/null +++ b/user_setups/win32/windows_gdi_64bits.ini @@ -0,0 +1,131 @@ +[env:windows_gdi_64bits] +platform = native@^1.1.4 +extra_scripts = + tools/sdl2_build_extra.py + tools/windows_build_extra.py +build_flags = + ${env.build_flags} + -D HASP_MODEL="Windows App" + + ; ----- Monitor + -D TFT_WIDTH=240 + -D TFT_HEIGHT=320 + ; SDL drivers options + ;-D LV_LVGL_H_INCLUDE_SIMPLE + ;-D LV_DRV_NO_CONF + -D USE_WIN32DRV + ; ----- ArduinoJson + -D ARDUINOJSON_DECODE_UNICODE=1 + -D HASP_NUM_PAGES=12 + -D HASP_USE_SPIFFS=0 + -D HASP_USE_LITTLEFS=0 + -D HASP_USE_EEPROM=0 + -D HASP_USE_GPIO=1 + -D HASP_USE_CONFIG=0 ; Standalone application, as library + -D HASP_USE_DEBUG=1 + -D HASP_USE_PNGDECODE=1 + -D HASP_USE_BMPDECODE=1 + -D HASP_USE_GIFDECODE=0 + -D HASP_USE_JPGDECODE=0 + -D HASP_USE_MQTT=1 + -D HASP_USE_SYSLOG=0 + -D MQTT_MAX_PACKET_SIZE=2048 + -D HASP_ATTRIBUTE_FAST_MEM= + -D IRAM_ATTR= ; No IRAM_ATTR available + -D PROGMEM= ; No PROGMEM available + + ; -- FreeType build options ------------------------ + -D LV_USE_FT_CACHE_MANAGER=1 ; crashes without cache + -D LVGL_FREETYPE_MAX_FACES=64 ; max number of FreeType faces in cache + -D LVGL_FREETYPE_MAX_SIZES=4 ; max number of sizes in cache + -D LVGL_FREETYPE_MAX_BYTES=16384 ; max bytes in cache + -D LVGL_FREETYPE_MAX_BYTES_PSRAM=65536 ; max bytes in cache when using PSRAM + + ;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO + ;-D LV_LOG_PRINTF=1 + ; Add recursive dirs for hal headers search + -D _WIN64 + -D WINDOWS ; We add this ourselves for code branching in hasp + -D WIN32_LEAN_AND_MEAN ; exclude a bunch of Windows header files from windows.h + -D PAHO_MQTT_STATIC + -DPAHO_WITH_SSL=TRUE + -DPAHO_BUILD_DOCUMENTATION=FALSE + -DPAHO_BUILD_SAMPLES=FALSE + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_VERBOSE_MAKEFILE=TRUE + ;-D NO_PERSISTENCE + -I.pio/libdeps/windows_gdi_64bits/paho/src + -I.pio/libdeps/windows_gdi_64bits/ArduinoJson/src + -I lib/lv_fs_if + -I lib/lv_datetime + -mconsole + ; ----- Statically linked libraries -------------------- + -l"ws2_32" ;windsock2 + -lrpcrt4 + -lcrypt32 + -lmingw32 + -mwindows + -lm + -ldinput8 + ;-ldxguid + ;-ldxerr8 + ;-luser32 + ;-lgdi32 + -lwinmm + -limm32 + -lole32 + -loleaut32 + ;-lshell32 + -lversion + ;-luuid + -lsetupapi + -lshlwapi + ;-lhid + +lib_deps = + ${env.lib_deps} + ;lv_drivers@~7.9.0 + ;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip + https://github.com/eclipse/paho.mqtt.c.git + bblanchon/ArduinoJson@^6.21.4 ; Json(l) parser + https://github.com/fvanroie/lv_drivers + +lib_ignore = + paho + AXP192 + ArduinoLog + lv_lib_qrcode + ETHSPI + +build_src_filter = + +<*> + -<*.h> + +<../hal/sdl2> + +<../.pio/libdeps/windows_gdi_64bits/paho/src/*.c> + +<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTClient.c> + -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsync.c> + -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTAsyncUtils.c> + -<../.pio/libdeps/windows_gdi_64bits/paho/src/MQTTVersion.c> + -<../.pio/libdeps/windows_gdi_64bits/paho/src/SSLSocket.c> + + + - + - + - + - + - + + + - + + + - + + + + + - + - + - + + + + + + + - + + + +<../.pio/libdeps/windows_gdi_64bits/ArduinoJson/src/ArduinoJson.h> + +