From 88c3c93ae89ae43d91fcbf140d18a9e5a0a30f48 Mon Sep 17 00:00:00 2001 From: Marc PASTEUR Date: Thu, 11 Dec 2025 18:51:22 +0100 Subject: [PATCH] work in qemu --- .vscode/c_cpp_properties.json | 2 +- .vscode/settings.json | 12 +- CMakeLists.txt | 83 +++--- Kconfig.projbuild | 7 + .../.vscode/c_cpp_properties.json | 37 +++ .../domotic_display/.vscode/launch.json | 20 ++ .../domotic_display/.vscode/settings.json | 9 + components/domotic_display/CMakeLists.txt | 27 +- components/domotic_display/idf_component.yml | 19 ++ components/domotic_display/ihm.c | 227 +++++++++-------- .../domotic_display/include/bsp/esp-bsp.h | 13 + components/domotic_display/include/ihm.h | 1 + components/domotic_display/include/model.h | 13 + components/domotic_display/model.c | 9 + .../test_host/.vscode/settings.json | 3 + .../domotic_display/test_host/CMakeLists.txt | 3 +- .../test_host/main/CMakeLists.txt | 3 +- .../domotic_display/test_host/main/test_ihm.c | 43 +++- .../test_host/sdkconfig.defaults | 2 +- components/eventsManager/eventsManager.c | 18 +- components/meteofrance/CMakeLists.txt | 14 +- components/meteofrance/include/meteofrance.h | 104 ++++---- dependencies.lock | 237 +----------------- main/CMakeLists.txt | 29 ++- main/Kconfig.projbuild | 12 +- main/idf_component.yml | 7 +- main/{ => include}/main.h | 4 +- main/{ => include}/obtain_time.h | 10 +- main/test_main.c | 167 ++++++++++++ sdkconfig.defaults | 15 +- 30 files changed, 656 insertions(+), 494 deletions(-) create mode 100644 Kconfig.projbuild create mode 100644 components/domotic_display/.vscode/c_cpp_properties.json create mode 100644 components/domotic_display/.vscode/launch.json create mode 100644 components/domotic_display/.vscode/settings.json create mode 100644 components/domotic_display/idf_component.yml create mode 100644 components/domotic_display/include/bsp/esp-bsp.h create mode 100644 components/domotic_display/include/model.h create mode 100644 components/domotic_display/model.c create mode 100644 components/domotic_display/test_host/.vscode/settings.json rename main/{ => include}/main.h (87%) rename main/{ => include}/obtain_time.h (95%) create mode 100644 main/test_main.c diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index b979dfe..b7af07a 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -2,7 +2,7 @@ "configurations": [ { "name": "ESP-IDF", - "compilerPath": "${config:idf.toolsPath}/tools/riscv32-esp-elf/esp-14.2.0_20240906/riscv32-esp-elf/bin/riscv32-esp-elf-gcc", + "compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc", "compileCommands": "${config:idf.buildPath}/compile_commands.json", "includePath": [ "${config:idf.espIdfPath}/components/**", diff --git a/.vscode/settings.json b/.vscode/settings.json index daed9bf..603b9a0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,12 +7,12 @@ "idf.customExtraVars": { "OPENOCD_SCRIPTS": "/home/marc/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240318/openocd-esp32/share/openocd/scripts", "ESP_ROM_ELF_DIR": "/home/marc/.espressif/tools/esp-rom-elfs/20240305/", - "IDF_TARGET": "esp32p4" + "IDF_TARGET": "esp32s3" }, "idf.gitPath": "git", "idf.adapterTargetName": "esp32s3", "idf.openOcdConfigs": [ - "board/esp32p4-ftdi.cfg" + "board/esp32s3-builtin.cfg" ], "idf.flashType": "UART", "idf.port": "/dev/ttyUSB0", @@ -108,5 +108,11 @@ "communication.h": "c", "mqtt_client.h": "c" }, - "idf.pythonInstallPath": "/usr/local/bin/python" + "idf.pythonInstallPath": "/usr/bin/python3", + "clangd.path": "/home/marc/.espressif/tools/esp-clang/esp-19.1.2_20250312/esp-clang/bin/clangd", + "clangd.arguments": [ + "--background-index", + "--query-driver=/home/marc/.espressif/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32s3-elf-gcc", + "--compile-commands-dir=/home/marc/domotic/build" + ] } diff --git a/CMakeLists.txt b/CMakeLists.txt index 835fafd..e8f42be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,51 +1,44 @@ -# The following lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) +option(SIMULATION_QEMU "Build for QEMU simulation" OFF) +message(STATUS "ROOT:: SIMULATION_QEMU = ${SIMULATION_QEMU}") +# ------------------------------------------------- +# CONFIGURATION AVANT project() : uniquement CMake pur +# ------------------------------------------------- - -if($ENV{IDF_TARGET} STREQUAL "esp32p4") - include($ENV{IDF_PATH}/tools/cmake/project.cmake) - # "Trim" the build. Include the minimal set of components, main and anything it depends on. - set(COMPONENTS main) - set(EXTRA_COMPONENT_DIRS - /home/marc/esp-dev-kits/examples/esp32-p4-function-ev-board/examples/common_components +if(SIMULATION_QEMU) + message(STATUS "SIMULATION_QEMU = ON") + option(SIMULATION_QEMU "Build for QEMU simulation" ON) + set(COMPONENTS + components/meteofrance + components/domotic_display + managed_components/lvgl_lvgl + main $ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs - ) - project(rgb_lcd) - add_link_options("-Wl,--disable-non-contiguous-regions") + ) + else() - # PROJECT_PLATFORM_LINUX - # PROJECT_PLATFORM_ESP32 - add_compile_definitions(PROJECT_PLATFORM_LINUX) - set(EXCLUDE_COMPONENTS main driver bh1750 espressif__bh1750 wifi_logger) - - set(EXTRA_COMPONENT_DIRS - $ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs - ${CMAKE_CURRENT_SOURCE_DIR}/FreeRTOS - "/home/marc/esp-protocols/common_components/linux_compat" - "/home/marc/esp-protocols/components/mdns/tests/host_test/components" - ) - project(rgb_lcd) - - add_executable(domotic_display - components/domotic_display/ihm.c - # ajoute d’autres fichiers si nécessaire - ) - - - # -- FreeRTOS config - add_library(freertos_config INTERFACE) - target_include_directories(freertos_config INTERFACE - ${CMAKE_CURRENT_SOURCE_DIR}/FreeRTOSConfig - ) - - add_subdirectory(FreeRTOS/FreeRTOS/Source) - add_subdirectory(components/meteofrance) - add_subdirectory(components/stateManagement) - add_subdirectory(managed_components/lvgl__lvgl) - target_include_directories(domotic_display PRIVATE components/domotic_display/include) - # --- Liens nécessaires --- - target_link_libraries(domotic_display PRIVATE freertos_kernel lvgl m pthread meteofrance) - + message(STATUS "SIMULATION_QEMU = OFF") + option(SIMULATION_QEMU "Build for QEMU simulation" OFF) endif() +# 🚨 Rien d'autre avant ces deux lignes ! +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(rgb_lcd) + +# ------------------------------------------------- +# APRÈS project() : maintenant CONFIG_SIMULATION_QEMU existe +# ------------------------------------------------- + +if(CONFIG_SIMULATION_QEMU) + message(STATUS "Compilation IHM (simulation)") + add_compile_definitions(CONFIG_SIMULATION_QEMU=1) + + #add_custom_target(run_ihm + # COMMAND ${CMAKE_COMMAND} -E echo "Building and launching IHM native..." + # COMMAND ${CMAKE_COMMAND} --build ${CMAKE_SOURCE_DIR}/components/ihm --target all + # COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_SOURCE_DIR}/components/ihm ./ihm_simulator + #) +else() + message(STATUS "Compilation standard") + add_link_options("-Wl,--disable-non-contiguous-regions") +endif() diff --git a/Kconfig.projbuild b/Kconfig.projbuild new file mode 100644 index 0000000..cc65281 --- /dev/null +++ b/Kconfig.projbuild @@ -0,0 +1,7 @@ +menu "Simulation options" + +config SIMULATION_QEMU + bool "Build with QEMU simulation stubs" + default n + +endmenu \ No newline at end of file diff --git a/components/domotic_display/.vscode/c_cpp_properties.json b/components/domotic_display/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..2770a22 --- /dev/null +++ b/components/domotic_display/.vscode/c_cpp_properties.json @@ -0,0 +1,37 @@ +{ + "configurations": [ + { + "name": "ESP-IDF", + "compilerPath": "${config:idf.toolsPath}/tools/xtensa-esp-elf/esp-14.2.0_20241119/xtensa-esp-elf/bin/xtensa-esp32-elf-gcc", + "compileCommands": [ + "${config:idf.buildPath}/compile_commands.json" + ], + "includePath": [ + "${config:idf.espIdfPath}/components/**", + "${config:idf.espIdfPathWin}/components/**", + "${workspaceFolder}/**" + ], + "defines": ["LV_CONF_SKIP"], + "browse": { + "path": [ + "${config:idf.espIdfPath}/components", + "${config:idf.espIdfPathWin}/components", + "${workspaceFolder}" + ], + "limitSymbolsToIncludedHeaders": true + } + }, + { + "name": "linux-host", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": ["LV_CONF_SKIP"], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/components/domotic_display/.vscode/launch.json b/components/domotic_display/.vscode/launch.json new file mode 100644 index 0000000..3d9c606 --- /dev/null +++ b/components/domotic_display/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "cppdbg", + "request": "launch", + "name": "Eclipse CDT GDB Adapter", + "program": "${workspaceFolder}/test_host/build/nvs_host_test.elf", + "cwd": "${workspaceFolder}/test_host", + "linux": { + "MIMode": "gdb", + "miDebuggerPath": "/usr/bin/gdb" + }, + } + ], + +} \ No newline at end of file diff --git a/components/domotic_display/.vscode/settings.json b/components/domotic_display/.vscode/settings.json new file mode 100644 index 0000000..6ef9404 --- /dev/null +++ b/components/domotic_display/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "idf.pythonInstallPath": "/usr/bin/python3", + "files.associations": { + "model.h": "c", + "lvgl.h": "c", + "lv_init.h": "c", + "lv_conf_internal.h": "c" + } +} \ No newline at end of file diff --git a/components/domotic_display/CMakeLists.txt b/components/domotic_display/CMakeLists.txt index 9f56ffa..401521a 100644 --- a/components/domotic_display/CMakeLists.txt +++ b/components/domotic_display/CMakeLists.txt @@ -2,23 +2,26 @@ function (make_font fontSize) execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size ${fontSize} --no-compress --font Montserrat-Medium.ttf --symbols "0123456789.°éèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o montserrat_medium_${fontSize}.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575) endfunction() -make_font(12) -make_font(18) -make_font(24) -execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 36 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_36.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575) -execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 72 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_72.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575) - -idf_component_register(SRC_DIRS . fonts - INCLUDE_DIRS "include" - REQUIRES meteofrance eventsManager lvgl esp32_p4_function_ev_board) +#make_font(12) +#make_font(18) +#make_font(24) +#execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 36 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_36.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575) +#execute_process(COMMAND podman run -v /home/marc/rgb_lcd/components/domotic_display/fonts:/app -w /app lvfontconv lv_font_conv --bpp 4 --size 72 --no-compress --font Roboto-Medium.ttf --symbols "0123456789.°àéèûCABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz %,'():ê/-" --format lvgl -o roboto_medium_72.c --font fa-solid-900.ttf --range 61461,0xf0c2,0xf575) -if(${IDF_TARGET} STREQUAL "esp32p4") + +#if(${IDF_TARGET} STREQUAL "esp32p4") + #esp32_p4_function_ev_board + idf_component_register(SRC_DIRS . fonts + INCLUDE_DIRS "include" + REQUIRES meteofrance eventsManager lvgl esp_lvgl_port) + target_compile_options(${COMPONENT_LIB} PUBLIC -DLV_LVGL_H_INCLUDE_SIMPLE) + lvgl_port_create_c_image("images/wifi_ok.png" "images/" "ARGB8888" "NONE") lvgl_port_create_c_image("images/wifi_ko.png" "images/" "ARGB8888" "NONE") lvgl_port_create_c_image("images/mqtt_ok.png" "images/" "AUTO" "NONE") lvgl_port_create_c_image("images/mqtt_ko.png" "images/" "ARGB8888" "NONE") lvgl_port_add_images(${COMPONENT_LIB} "images/") - littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT) -endif() + #littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT) +#endif() diff --git a/components/domotic_display/idf_component.yml b/components/domotic_display/idf_component.yml new file mode 100644 index 0000000..b9b6f6e --- /dev/null +++ b/components/domotic_display/idf_component.yml @@ -0,0 +1,19 @@ +## IDF Component Manager Manifest File +dependencies: + ## Required IDF version + idf: + version: '>=4.1.0' + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true + espressif/esp_lvgl_port: ^2.7.0 + espressif/esp_lcd_qemu_rgb: + version: ^1 \ No newline at end of file diff --git a/components/domotic_display/ihm.c b/components/domotic_display/ihm.c index 97ccd21..1d4db4a 100644 --- a/components/domotic_display/ihm.c +++ b/components/domotic_display/ihm.c @@ -7,6 +7,7 @@ #include "eventsManager.h" #include "bsp/esp-bsp.h" #include "lvgl_private.h" +#include "lv_examples.h" #define upEvent "monter" @@ -36,7 +37,7 @@ lv_subject_t meteoStatus; lv_obj_t *jour; static lv_style_t no_padding; -static const char *TAG = "IHM"; +//static const char *TAG = "IHM"; static lv_subject_t wifiStatus; LV_IMAGE_DECLARE(wifi_ok); @@ -92,17 +93,73 @@ lv_obj_t* myChart; lv_chart_series_t * ser; lv_obj_t *lblHauteurCuve; lv_obj_t* lblEtatMachine; +static lv_style_t style_lbvValue; +static lv_style_t style_btn; +/*Will be called when the styles of the base theme are already added + to add new styles*/ +static void new_theme_apply_cb(lv_theme_t *th, lv_obj_t *obj) +{ + LV_UNUSED(th); + + if (lv_obj_check_type(obj, &lv_button_class)) + { + lv_obj_add_style(obj, &style_btn, 0); + } +} + +lv_theme_t *lv_theme_create(void) +{ + lv_theme_t *theme = lv_zalloc(sizeof(*theme)); + LV_ASSERT_MALLOC(theme); + return theme; +} + +void lv_theme_copy(lv_theme_t *dst, const lv_theme_t *src) +{ + if (!dst || !src) + { + LV_LOG_WARN("Refusing to copy null themes"); + return; + } + lv_memcpy(dst, src, sizeof(*src)); +} + +LV_FONT_DECLARE(montserrat_medium_12); +LV_FONT_DECLARE(montserrat_medium_18); +LV_FONT_DECLARE(montserrat_medium_24); +LV_FONT_DECLARE(roboto_medium_36); +LV_FONT_DECLARE(roboto_medium_72); void drawIhm(void *xIHMEventQueueParam) { QueueHandle_t xIHMEventQueue = (QueueHandle_t)xIHMEventQueueParam; + display_lock("app_main"); init_display_ihm(); + /* Initialize the new theme with the current theme as its parent + * The user is responsible for freeing the theme when it's no longer needed */ + lv_theme_t *th_act = lv_display_get_theme(NULL); + lv_theme_t *th_new = lv_theme_create(); + lv_theme_copy(th_new, th_act); + th_new->font_small = &montserrat_medium_12; + th_new->font_normal = &montserrat_medium_18; + th_new->font_large = &roboto_medium_36; + // lv_theme_default_deinit(); + // lv_theme_default_init(display,lv_palette_main(LV_PALETTE_GREEN),lv_palette_darken(LV_PALETTE_GREEN,3),false,&montserrat_medium_12); + lv_theme_set_parent(th_new, th_act); + + /*Set the style apply callback for the new theme*/ + lv_theme_set_apply_cb(th_new, new_theme_apply_cb); + + /*Assign the new theme to the current display*/ + lv_display_set_theme(lv_display_get_default(), th_new); + lv_subject_init_int(&wifiStatus, 0); lv_subject_add_observer_obj(&wifiStatus, wifiStatus_obs_cb, NULL, NULL); - display_lock("app_main"); + + //lv_example_style_17(); app_main_display(); display_unlock("app_main"); @@ -295,6 +352,12 @@ void setOTAProgress(int value){ } } +static lv_style_t style_gradient; +static const lv_color_t grad_colors[2] = { + LV_COLOR_MAKE(0x9B, 0x18, 0x42), + LV_COLOR_MAKE(0x00, 0x00, 0x00), +}; + void app_main_display() { @@ -329,12 +392,7 @@ void app_main_display() lv_style_init(&no_padding); lv_style_set_pad_all(&no_padding, 0); - static const lv_color_t grad_colors[2] = { - LV_COLOR_MAKE(0x9B, 0x18, 0x42), - LV_COLOR_MAKE(0x00, 0x00, 0x00), - }; - static lv_style_t style_gradient; lv_style_init(&style_gradient); /*First define a color gradient. In this example we use a purple to black color map.*/ @@ -392,22 +450,23 @@ void app_main_display() lv_obj_set_width(label, lv_pct(100)); lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); lv_obj_set_style_text_font(label,lv_theme_get_font_large(label),0); - lv_label_set_text(label, LV_SYMBOL_BELL "Bienvenue sur DomoTIC !" LV_SYMBOL_BELL); + lv_obj_set_style_text_color(label, lv_color_make(255,255,255),0); + lv_label_set_text(label, "Bienvenue sur DomoTIC"); lv_obj_align(label, LV_ALIGN_CENTER, 0, 20); } bool display_lock(const char* TAG){ - //ESP_LOGI(TAG,"Obtention mutex"); + ESP_LOGI(TAG,"Obtention mutex"); if(bsp_display_lock(3000)){ - //ESP_LOGI(TAG, "Mutex obtenu"); + ESP_LOGI(TAG, "Mutex obtenu"); return true; }else{ - //ESP_LOGE(TAG, "Impossible d'obtenir le mutex"); + ESP_LOGE(TAG, "Impossible d'obtenir le mutex"); return false; } } void display_unlock(const char* TAG){ - //ESP_LOGI(TAG,"Libération mutexx"); + ESP_LOGI(TAG,"Libération mutexx"); bsp_display_unlock(); } @@ -508,6 +567,8 @@ void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr) free(result); } +static lv_style_t tempStyle; + // Ce fragment affiche une prévision journaliere (date,icone, min et max) static lv_obj_t* weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent) { @@ -553,7 +614,6 @@ static lv_obj_t* weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent) lv_obj_set_flex_flow(container2, LV_FLEX_FLOW_COLUMN); lv_obj_set_flex_align(container2, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START); - static lv_style_t tempStyle; lv_style_init(&tempStyle); // lv_style_set_text_font(&tempStyle,¬omedium16); @@ -574,6 +634,7 @@ static lv_obj_t* weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent) return container; } +static lv_style_t tempStyle; // Ce fragment affiche une prévision horaire (date,icone, temp moyenne) static lv_obj_t* weatherH_fragment_create_obj(int horaireNr, lv_obj_t *parent) @@ -595,8 +656,7 @@ static lv_obj_t* weatherH_fragment_create_obj(int horaireNr, lv_obj_t *parent) lv_obj_set_width(container, 150); lv_obj_set_height(container, LV_SIZE_CONTENT); - static lv_style_t tempStyle; - lv_style_init(&tempStyle); + //lv_style_init(&tempStyle); // lv_style_set_text_font(&tempStyle,¬omedium16); lv_obj_t *temp = lv_label_create(container); @@ -706,8 +766,6 @@ static void log_event_handler(lv_event_t * e) } } -static lv_style_t style_lbvValue; -static lv_style_t style_btn; #define MIN(a,b) ((a) < (b) ? (a) : (b)) static void draw_event_cb(lv_event_t * e) { @@ -1015,72 +1073,47 @@ void draw_tabVolets(lv_obj_t* parent) } } -/*Will be called when the styles of the base theme are already added - to add new styles*/ -static void new_theme_apply_cb(lv_theme_t * th, lv_obj_t * obj) + +static void time_observer_cb(lv_observer_t *observer, lv_subject_t *subject) { - LV_UNUSED(th); + LV_UNUSED(subject); + lv_obj_t *spangroup = lv_observer_get_target_obj(observer); - if(lv_obj_check_type(obj, &lv_button_class)) { - lv_obj_add_style(obj, &style_btn, 0); - } + char buf[16]; + + lv_snprintf(buf, sizeof(buf), "%02" LV_PRId32, lv_subject_get_int(&hourSubj)); + lv_span_set_text(lv_spangroup_get_child(spangroup, 0), buf); + + lv_snprintf(buf, sizeof(buf), ":%02" LV_PRId32, lv_subject_get_int(&minuteSubj)); + lv_span_set_text(lv_spangroup_get_child(spangroup, 1), buf); + + lv_spangroup_refresh(spangroup); } -lv_theme_t * lv_theme_create(void) -{ - lv_theme_t * theme = lv_zalloc(sizeof(*theme)); - LV_ASSERT_MALLOC(theme); - return theme; -} - -void lv_theme_copy(lv_theme_t * dst, const lv_theme_t * src) -{ - if(!dst || !src) { - LV_LOG_WARN("Refusing to copy null themes"); - return; - } - lv_memcpy(dst, src, sizeof(*src)); -} - - /* ------------------------------------------------------------ */ /* Dessin IHM */ /* ------------------------------------------------------------ */ -LV_FONT_DECLARE(montserrat_medium_12); -LV_FONT_DECLARE(montserrat_medium_18); -LV_FONT_DECLARE(montserrat_medium_24); -LV_FONT_DECLARE(roboto_medium_36); -LV_FONT_DECLARE(roboto_medium_72); + +lv_color_t base = LV_COLOR_MAKE(126, 94, 133); +lv_color_t accent = LV_COLOR_MAKE(204, 16, 16); +lv_color_t bgColor = LV_COLOR_MAKE(235, 199, 158); + +static lv_style_t objstyle; +static lv_style_t txtstyle; +static lv_style_t txtstyle_inv; +static lv_style_t no_padding; +static lv_style_t objstyle; +static lv_style_t txtstyle; + void draw_ihm() { - lv_display_t * display = lv_display_get_default(); - /*Initialize the styles*/ lv_style_init(&style_btn); //lv_style_set_bg_color(&style_btn, lv_palette_main(LV_PALETTE_GREEN)); //lv_style_set_border_color(&style_btn, lv_palette_darken(LV_PALETTE_GREEN, 3)); //lv_style_set_border_width(&style_btn, 3); - /* Initialize the new theme with the current theme as its parent - * The user is responsible for freeing the theme when it's no longer needed */ - lv_theme_t * th_act = lv_display_get_theme(NULL); - lv_theme_t * th_new = lv_theme_create(); - lv_theme_copy(th_new, th_act); - th_new->font_small=&montserrat_medium_12; - th_new->font_normal=&montserrat_medium_18; - th_new->font_large=&montserrat_medium_24; - //lv_theme_default_deinit(); - //lv_theme_default_init(display,lv_palette_main(LV_PALETTE_GREEN),lv_palette_darken(LV_PALETTE_GREEN,3),false,&montserrat_medium_12); - lv_theme_set_parent(th_new, th_act); - - /*Set the style apply callback for the new theme*/ - lv_theme_set_apply_cb(th_new, new_theme_apply_cb); - - /*Assign the new theme to the current display*/ - lv_display_set_theme(display, th_new); - - lv_subject_init_string(&tempExtSubj, tempExtStr, NULL, 6, "--"); lv_subject_init_string(&tempIntSubj, tempIntStr, NULL, 6, "--"); lv_subject_init_string(&hauteurCuveSubj, hauteurCuveStr, NULL, 9, "--"); @@ -1094,14 +1127,8 @@ void draw_ihm() lv_obj_set_size(bg_cont, LV_PCT(100), LV_PCT(100)); lv_obj_set_flex_flow(bg_cont, LV_FLEX_FLOW_COLUMN); lv_obj_set_style_pad_top(bg_cont, 5, 0); + lv_obj_set_style_bg_color(bg_cont, bgColor, 0); - lv_color_t base = LV_COLOR_MAKE(0xff, 0xff, 0xff); - lv_color_t accent = LV_COLOR_MAKE(0xcc, 0x00, 0x00); - lv_color_t new = LV_COLOR_MAKE(0xaa, 0xaa, 0xaa); - - lv_obj_set_style_bg_color(lv_scr_act(), new,0); - - static lv_style_t objstyle; lv_style_init(&objstyle); lv_style_set_bg_color(&objstyle, accent); lv_style_set_outline_color(&objstyle, accent); @@ -1131,36 +1158,32 @@ void draw_ihm() //lv_subject_add_observer_obj(&c->th, theme_observer_accent_span_cb, date, day_and_month); //lv_subject_add_observer_obj(&c->subject_groups.date.group, date_observer_cb, date, c); - - static lv_style_t txtstyle; - lv_style_init(&txtstyle); lv_style_set_text_color(&txtstyle, accent); lv_style_set_line_color(&txtstyle, accent); lv_style_set_text_font(&txtstyle, &roboto_medium_72); - static lv_style_t txtstyle_inv; - lv_style_init(&txtstyle_inv); lv_style_set_text_color(&txtstyle_inv, base); lv_style_set_line_color(&txtstyle_inv, base); lv_style_set_text_font(&txtstyle_inv, &roboto_medium_72); - lv_obj_t * time = lv_spangroup_create(date_and_time); lv_obj_add_style(time, &txtstyle, 0); lv_span_t * timeSpan = lv_spangroup_add_span(time); lv_span_set_text(timeSpan,"21"); - lv_span_t * minute = lv_spangroup_add_span(time); + lv_style_set_text_font(lv_span_get_style(timeSpan), &roboto_medium_72); + lv_span_t *minute = lv_spangroup_add_span(time); lv_span_set_text(minute,":56"); - lv_style_set_text_color(lv_span_get_style(minute),base); + lv_style_set_text_color(lv_span_get_style(minute), base); lv_style_set_line_color(lv_span_get_style(minute), accent); - //lv_subject_add_observer_obj(&c->th, theme_observer_accent_span_cb, time, minute); - //lv_subject_add_observer_obj(&c->subject_groups.time.group, time_observer_cb, time, c); + lv_style_set_text_font(lv_span_get_style(minute), &roboto_medium_72); + // lv_subject_add_observer_obj(&c->th, theme_observer_accent_span_cb, time, minute); + // lv_subject_add_observer_obj(&timeGroup, time_observer_cb, time, NULL); - lv_obj_t * apps = lv_obj_create(bg_cont); + lv_obj_t *apps = lv_obj_create(bg_cont); lv_obj_remove_style_all(apps); lv_obj_set_size(apps, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_style_pad_bottom(apps, 8, 0); @@ -1173,13 +1196,16 @@ void draw_ihm() lv_obj_set_flex_flow(apps, LV_FLEX_FLOW_ROW); lv_obj_set_style_pad_column(apps,6, 0); + create_card(apps, "Météo"); - create_card(apps,"Volets"); + + create_card(apps, "Volets"); create_card(apps,"Minuteur"); create_card(apps,"Messagerie"); - return; - //Create a Tab view object + return; + // *************************************************************************************************** + // Create a Tab view object tabview = lv_tabview_create(lv_screen_active()); lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT); lv_tabview_set_tab_bar_size(tabview, 80); @@ -1224,7 +1250,6 @@ void draw_ihm() lv_style_set_align(&style_container, LV_ALIGN_BOTTOM_LEFT); lv_style_set_flex_cross_place(&style_container, LV_FLEX_ALIGN_END); - static lv_style_t no_padding; lv_style_init(&no_padding); lv_style_set_pad_all(&no_padding, 0); @@ -1243,30 +1268,24 @@ void draw_ihm() lv_obj_set_flex_flow(tabMeteo, LV_FLEX_FLOW_COLUMN); } -void create_card(lv_obj_t * parent, char *lbl) +void create_card(lv_obj_t *parent, char *lbl) { - lv_color_t base = LV_COLOR_MAKE(0xff, 0xff, 0xff); - lv_color_t accent = LV_COLOR_MAKE(0xcc, 0x00, 0x00); + //lv_style_init(&objstyle); + //lv_style_init(&txtstyle); + lv_style_set_bg_color(&objstyle, base); + lv_style_set_outline_color(&objstyle, base); - static lv_style_t objstyle; - static lv_style_t txtstyle; - lv_style_init(&objstyle); - lv_style_init(&txtstyle); - lv_style_set_bg_color(&objstyle, accent); - lv_style_set_outline_color(&objstyle, accent); - - lv_style_set_text_color(&txtstyle, accent); + lv_style_set_text_color(&txtstyle, lv_color_white()); lv_style_set_line_color(&txtstyle, accent); - lv_style_set_text_font(&txtstyle, &roboto_medium_36); + lv_style_set_text_font(&txtstyle, lv_theme_get_font_large(parent)); // if(icon_img_dsc == NULL) return; lv_obj_t *app_card = lv_obj_create(parent); lv_obj_remove_style_all(app_card); lv_obj_set_size(app_card, 300, 180); lv_obj_set_style_radius(app_card, 20, 0); - lv_obj_set_style_bg_opa(app_card, 16 * 255 / 100, 0); - lv_obj_set_style_pad_all(app_card, 24, 0); + lv_obj_set_style_bg_opa(app_card, 50, 0); lv_obj_add_style(app_card, &objstyle, 0); - // lv_obj_add_event_cb(app_card, app_card_click_cb, LV_EVENT_CLICKED, (void *)((lv_uintptr_t)app_cb)); + //lv_obj_add_event_cb(app_card, app_card_click_cb, LV_EVENT_CLICKED, (void *)((lv_uintptr_t)app_cb)); lv_obj_t *label = lv_label_create(app_card); lv_label_set_text(label, lbl); diff --git a/components/domotic_display/include/bsp/esp-bsp.h b/components/domotic_display/include/bsp/esp-bsp.h new file mode 100644 index 0000000..cf7d483 --- /dev/null +++ b/components/domotic_display/include/bsp/esp-bsp.h @@ -0,0 +1,13 @@ +extern SemaphoreHandle_t lvgl_mux; +const char* TAG="bsp"; +bool bsp_display_lock(int timeout_ms) +{ + ESP_LOGI(TAG, "Obtention mutex"); + // Convert timeout in milliseconds to FreeRTOS ticks + // If `timeout_ms` is set to -1, the program will block until the condition is met + const TickType_t timeout_ticks = (timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms); + return xSemaphoreTakeRecursive(lvgl_mux, timeout_ticks) == pdTRUE; +} +void bsp_display_unlock() { + xSemaphoreGiveRecursive(lvgl_mux); +} diff --git a/components/domotic_display/include/ihm.h b/components/domotic_display/include/ihm.h index 1d31b14..fec63f4 100644 --- a/components/domotic_display/include/ihm.h +++ b/components/domotic_display/include/ihm.h @@ -1,6 +1,7 @@ #pragma once #include "meteofrance.h" #include "lvgl.h" +#include "model.h" void app_main_display(); void app_ota_display(); diff --git a/components/domotic_display/include/model.h b/components/domotic_display/include/model.h new file mode 100644 index 0000000..1123345 --- /dev/null +++ b/components/domotic_display/include/model.h @@ -0,0 +1,13 @@ +#pragma once +#include "lvgl.h" + +/* input subjects */ +/* int: the hour shown on clocks, e.g. 9 */ +extern lv_subject_t hourSubj; +/* int: the minute shown on clocks, e.g. 36 */ +extern lv_subject_t minuteSubj; +extern lv_subject_t timeGroup; + +extern lv_color_t base; +extern lv_color_t accent; +extern lv_color_t bgColor; diff --git a/components/domotic_display/model.c b/components/domotic_display/model.c new file mode 100644 index 0000000..5f03642 --- /dev/null +++ b/components/domotic_display/model.c @@ -0,0 +1,9 @@ +#include "model.h" +lv_subject_t hourSubj; +/* int: the minute shown on clocks, e.g. 36 */ +lv_subject_t minuteSubj; +lv_subject_t timeGroup; + +lv_color_t base = LV_COLOR_MAKE(126, 94, 133); +lv_color_t accent = LV_COLOR_MAKE(204, 16, 16); +lv_color_t bgColor = LV_COLOR_MAKE(235, 199, 158); diff --git a/components/domotic_display/test_host/.vscode/settings.json b/components/domotic_display/test_host/.vscode/settings.json new file mode 100644 index 0000000..1ad1dee --- /dev/null +++ b/components/domotic_display/test_host/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "idf.pythonInstallPath": "/usr/bin/python3" +} \ No newline at end of file diff --git a/components/domotic_display/test_host/CMakeLists.txt b/components/domotic_display/test_host/CMakeLists.txt index 8b72618..583cade 100644 --- a/components/domotic_display/test_host/CMakeLists.txt +++ b/components/domotic_display/test_host/CMakeLists.txt @@ -1,10 +1,11 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) + set(COMPONENTS main) # This test app doesn't require FreeRTOS, using mock instead list(APPEND EXTRA_COMPONENT_DIRS - "$ENV{IDF_PATH}/tools/mocks/freertos/" + # "$ENV{IDF_PATH}/tools/mocks/freertos/" "$ENV{IDF_PATH}/tools/mocks/esp_timer" ../../meteofrance ../../stateManagement diff --git a/components/domotic_display/test_host/main/CMakeLists.txt b/components/domotic_display/test_host/main/CMakeLists.txt index 9a46c11..d8ada2e 100644 --- a/components/domotic_display/test_host/main/CMakeLists.txt +++ b/components/domotic_display/test_host/main/CMakeLists.txt @@ -1,7 +1,8 @@ set(LV_BUILD_USE_KCONFIG ON) idf_component_register(SRCS "test_ihm.c" - "../../ihm.c" + "../../ihm.c" + "../../model.c" "driver_backends.c" "sdl.c" "../../fonts/montserrat_medium_12.c" diff --git a/components/domotic_display/test_host/main/test_ihm.c b/components/domotic_display/test_host/main/test_ihm.c index 312eeb4..ec56010 100644 --- a/components/domotic_display/test_host/main/test_ihm.c +++ b/components/domotic_display/test_host/main/test_ihm.c @@ -10,7 +10,7 @@ #include "driver_backends.h" #include "simulator_util.h" #include "simulator_settings.h" - +#include "esp_log.h" esp_mqtt_client_handle_t client; /* contains the name of the selected backend if user @@ -111,7 +111,30 @@ static void configure_simulator(int argc, char **argv) } } } -int main(int argc, char const *argv[]) + + + + static void + clock_timer_cb(lv_timer_t *t) +{ + /* slowly increment the time */ + int32_t minutes = lv_subject_get_int(&minuteSubj); + minutes += 1; + if (minutes > 59) + { + minutes = 0; + int32_t hour = lv_subject_get_int(&hourSubj); + hour += 1; + if (hour > 12) + { + hour = 1; + } + lv_subject_set_int(&hourSubj, hour); + } + lv_subject_set_int(&minuteSubj, minutes); +} + +int app_main(int argc, char *argv[]) { /* code */ printf("hello\n"); @@ -128,8 +151,20 @@ int main(int argc, char const *argv[]) lv_sdl_keyboard_create(); lv_sdl_mousewheel_create(); lv_sdl_mousewheel_create(); - draw_ihm(); - /* Enter the run loop of the selected backend */ + + size_t watermark = uxTaskGetStackHighWaterMark(NULL); + ESP_LOGI("STACK", "Remaining stack: %d bytes", watermark); + + lv_subject_init_int(&hourSubj, 9); + lv_subject_init_int(&minuteSubj, 36); + lv_subject_t *grp[2] = {&hourSubj, &minuteSubj}; + lv_subject_init_group(&timeGroup, grp,2); + + /*lv_timer_t *clock_timer = */lv_timer_create(clock_timer_cb, 1000, NULL); + + //draw_ihm(); + drawIhm(NULL); + /* Enter the run loop of the selected backend */ driver_backends_run_loop(); return 0; diff --git a/components/domotic_display/test_host/sdkconfig.defaults b/components/domotic_display/test_host/sdkconfig.defaults index ee58559..b9fa686 100644 --- a/components/domotic_display/test_host/sdkconfig.defaults +++ b/components/domotic_display/test_host/sdkconfig.defaults @@ -2,7 +2,7 @@ # Espressif IoT Development Framework (ESP-IDF) 5.5.1 Project Minimal Configuration # CONFIG_IDF_TARGET="linux" -CONFIG_LV_CONF_SKIP=n +CONFIG_ESP_MAIN_TASK_STACK_SIZE=12288 CONFIG_LV_USE_LOG=y CONFIG_LV_LOG_PRINTF=y CONFIG_LV_FONT_MONTSERRAT_40=y diff --git a/components/eventsManager/eventsManager.c b/components/eventsManager/eventsManager.c index 432a40a..6c8c2ef 100644 --- a/components/eventsManager/eventsManager.c +++ b/components/eventsManager/eventsManager.c @@ -6,7 +6,7 @@ EventGroupHandle_t domotic_event_group; QueueHandle_t ihm_queue; -extern esp_mqtt_client_handle_t client; +//extern esp_mqtt_client_handle_t client; static const char *TAG = "evtMgr"; @@ -62,7 +62,7 @@ void send_event(domo_events evt, void* pDatas) { break; case EVT_BTN_VOLET: - esp_mqtt_client_publish(client, "volets", pDatas, 0, 0, 0); + //esp_mqtt_client_publish(client, "volets", pDatas, 0, 0, 0); free(ihmEvt); // rien à envoyer à l'IHM return; @@ -115,11 +115,15 @@ void send_event(domo_events evt, void* pDatas) { return; } ESP_LOGE(TAG, "Envoi d'un evt %i a l'IHM", ihmEvt->eEventType); - if (ihmEvt && xQueueSendToFront(ihm_queue, &ihmEvt, pdMS_TO_TICKS(10)) != pdPASS) { - ESP_LOGE(TAG, "La queue est pleine"); - if (ihmEvt->bNeedToFreeData && ihmEvt->pvData) { - free(ihmEvt->pvData); + if( 0 && ihm_queue != NULL ){ + if (ihmEvt && xQueueSendToFront(ihm_queue, &ihmEvt, pdMS_TO_TICKS(10)) != pdPASS) + { + ESP_LOGE(TAG, "La queue est pleine"); + if (ihmEvt->bNeedToFreeData && ihmEvt->pvData) + { + free(ihmEvt->pvData); + } + free(ihmEvt); } - free(ihmEvt); } } diff --git a/components/meteofrance/CMakeLists.txt b/components/meteofrance/CMakeLists.txt index c6bb15f..9a806f0 100644 --- a/components/meteofrance/CMakeLists.txt +++ b/components/meteofrance/CMakeLists.txt @@ -1,11 +1,11 @@ -IF(ESP_PLATFORM) +#IF(ESP_PLATFORM) idf_component_register(SRCS "meteofrance.c" INCLUDE_DIRS "include" REQUIRES json esp_http_client esp-tls stateManagement eventsManager) -else() - add_library(meteofrance SHARED - meteofrance.c) - target_include_directories(meteofrance PUBLIC ./include) - target_link_libraries(meteofrance PRIVATE stateManagement FreeRTOS freertos_kernel) +#else() +# add_library(meteofrance SHARED +# meteofrance.c) +# target_include_directories(meteofrance PUBLIC ./include) +# target_link_libraries(meteofrance PRIVATE stateManagement FreeRTOS freertos_kernel) -endif() \ No newline at end of file +#endif() \ No newline at end of file diff --git a/components/meteofrance/include/meteofrance.h b/components/meteofrance/include/meteofrance.h index 02ddbae..862d571 100644 --- a/components/meteofrance/include/meteofrance.h +++ b/components/meteofrance/include/meteofrance.h @@ -3,62 +3,66 @@ #include "stdbool.h" #include "stateManagement.h" -/*struct node { - struct node *next; - int e; + /*struct node { + struct node *next; + int e; + }; + + struct Hashtable { + unsigned Tablesize; + struct node *Cells; + }; + */ + + struct dailyforecast_prev + { + float min; + float max; + char desc[25]; + char icon[9]; }; -struct Hashtable { - unsigned Tablesize; - struct node *Cells; + struct forecast_prev + { + float value; + char desc[25]; + char icon[9]; }; - */ -struct dailyforecast_prev{ - float min; - float max; - char desc[25]; - char icon[9]; -}; + typedef struct meteodailyforecast_data + { + time_t datetime; + bool isValid; + struct dailyforecast_prev previsions; + } meteodailyforecast_data; -struct forecast_prev{ - float value; - char desc[25]; - char icon[9]; -}; + typedef struct meteoforecast_data + { + time_t datetime; + bool isValid; + struct forecast_prev previsions; + } meteoforecast_data; -typedef struct meteodailyforecast_data{ - time_t datetime; - bool isValid; - struct dailyforecast_prev previsions; -} meteodailyforecast_data; + typedef void (*weather_data_callback)(struct meteodailyforecast_data *datas, struct meteoforecast_data *datasf); + typedef void (*weather_data_start_callback)(); -typedef struct meteoforecast_data{ - time_t datetime; - bool isValid; - struct forecast_prev previsions; -} meteoforecast_data; + typedef struct + { + unsigned int humidity; + float temperature; + float pressure; + unsigned long retreival_period; + weather_data_callback data_retreived_cb; + weather_data_start_callback data_retreived_cb_start; + } weather_data; -typedef void (*weather_data_callback)(struct meteodailyforecast_data *datas, struct meteoforecast_data *datasf); -typedef void (*weather_data_start_callback)(); - -typedef struct { - unsigned int humidity; - float temperature; - float pressure; - unsigned long retreival_period; - weather_data_callback data_retreived_cb; - weather_data_start_callback data_retreived_cb_start; -} weather_data; - -void printdftemp(struct dailyforecast_prev *tmp); -void printftemp(struct forecast_prev *tmp); -void printfdf(struct meteodailyforecast_data *tmp); -void dtToString(time_t, char *buffer); -void dtHToString(time_t, char *buffer); -void printff(struct meteoforecast_data *tmp); - -void on_weather_data_retrieval(weather_data_callback data_retreived_cb); -void on_weather_data_retrieval_start(weather_data_callback data_retreived_cb); -void initialise_weather_data_retrieval(unsigned long retreival_period, void* evtGroup); + void printdftemp(struct dailyforecast_prev * tmp); + void printftemp(struct forecast_prev * tmp); + void printfdf(struct meteodailyforecast_data * tmp); + void dtToString(time_t, char *buffer); + void dtHToString(time_t, char *buffer); + void printff(struct meteoforecast_data * tmp); + void on_weather_data_retrieval(weather_data_callback data_retreived_cb); + void on_weather_data_retrieval_start(weather_data_callback data_retreived_cb); + void initialise_weather_data_retrieval(unsigned long retreival_period, void *evtGroup); diff --git a/dependencies.lock b/dependencies.lock index 3dab1e6..b022ac2 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -1,182 +1,20 @@ dependencies: - chmorgan/esp-audio-player: - component_hash: c8ac1998e9af863bc41b57e592f88d1a5791a0f891485122336ddabbf7a65033 + espressif/esp_lcd_qemu_rgb: + component_hash: e8981dd7399504a5ab647ce28a4876f8467c03b759895f50c24f0cb6095faaa0 dependencies: - - name: chmorgan/esp-libhelix-mp3 - registry_url: https://components.espressif.com - require: private - version: '>=1.0.0,<2.0.0' - name: idf require: private - version: '>=5.0' + version: '>=5.3' source: registry_url: https://components.espressif.com/ type: service - version: 1.0.7 - chmorgan/esp-file-iterator: - component_hash: 327091394b9ef5c2cd395a960ab70ae64479e0a8831cbd9925e38895fad93719 - dependencies: - - name: idf - require: private - version: '>=4.1.0' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.0.0 - chmorgan/esp-libhelix-mp3: - component_hash: cbb76089dc2c5749f7b470e2e70aedc44c9da519e04eb9a67d4c7ec275229e53 - dependencies: - - name: idf - require: private - version: '>=4.1.0' - source: - registry_url: https://components.espressif.com - type: service - version: 1.0.3 - espressif/bh1750: - dependencies: [] - source: - path: /home/marc/rgb_lcd/components/espressif__bh1750 - type: local - version: 1.0.3 - espressif/cmake_utilities: - component_hash: 351350613ceafba240b761b4ea991e0f231ac7a9f59a9ee901f751bddc0bb18f - dependencies: - - name: idf - require: private - version: '>=4.1' - source: - registry_url: https://components.espressif.com - type: service - version: 0.5.3 - espressif/eppp_link: - component_hash: 41f6519edda527ec6a0553c872ebaf8fc6d3812523c9d4c8d1660ad21c720abe - dependencies: - - name: espressif/esp_serial_slave_link - registry_url: https://components.espressif.com - require: private - version: ^1.1.0 - - name: idf - require: private - version: '>=5.2' - source: - registry_url: https://components.espressif.com - type: service - version: 1.1.3 - espressif/esp32_p4_function_ev_board: - component_hash: 1e0436b3d220275d6b7930330b1a9b828fedf0dbc81006531e592b059842641e - dependencies: - - name: espressif/esp_codec_dev - registry_url: https://components.espressif.com - require: public - version: 1.2.* - - name: espressif/esp_lcd_ek79007 - registry_url: https://components.espressif.com - require: private - version: 1.* - - name: espressif/esp_lcd_ili9881c - registry_url: https://components.espressif.com - require: private - version: 1.* - - name: espressif/esp_lcd_touch_gt911 - registry_url: https://components.espressif.com - require: private - version: ^1 - - name: espressif/esp_lvgl_port - registry_url: https://components.espressif.com - require: public - version: ^2 - - name: idf - require: private - version: '>=5.3' - - name: lvgl/lvgl - registry_url: https://components.espressif.com - require: private - version: '>=8,<10' - source: - registry_url: https://components.espressif.com/ - type: service - targets: - - esp32p4 - version: 4.1.1 - espressif/esp_codec_dev: - component_hash: 014948481bda426cd46714f297fe1891711246c62bea288863a8cc8cf13ef1f0 - dependencies: - - name: idf - require: private - version: '>=4.0' - source: - registry_url: https://components.espressif.com - type: service - version: 1.2.0 - espressif/esp_hosted: - component_hash: a19249042b9987097f89e682ec05d7fad1bd2186e7b758363a2ddb5787ef7d98 - dependencies: - - name: idf - require: private - version: '>=5.3' - source: - registry_url: https://components.espressif.com - type: service - version: 2.6.5 - espressif/esp_lcd_ek79007: - component_hash: 8005700b7f10c7136b6e2a3f19a48f972aa1d13ed107ed298574e8d24d17ea83 - dependencies: - - name: espressif/cmake_utilities - registry_url: https://components.espressif.com - require: private - version: 0.* - - name: idf - require: private - version: '>=5.3' - source: - registry_url: https://components.espressif.com - type: service - targets: - - esp32p4 - version: 1.0.4 - espressif/esp_lcd_ili9881c: - component_hash: eb9ba0484d1d14171b69e5d192716fb1cdd6ef068aa4014dc3202486e124498e - dependencies: - - name: idf - require: private - version: '>=5.3' - source: - registry_url: https://components.espressif.com - type: service - targets: - - esp32p4 version: 1.0.2 - espressif/esp_lcd_touch: - component_hash: 779b4ba2464a3ae85681e4b860caa5fdc35801458c23f3039ee761bae7f442a4 - dependencies: - - name: idf - require: private - version: '>=4.4.2' - source: - registry_url: https://components.espressif.com - type: service - version: 1.1.2 - espressif/esp_lcd_touch_gt911: - component_hash: acc1c184358aa29ef72506f618c9c76a8cc2bf12af38a2bff3d44d84f3a08857 - dependencies: - - name: espressif/esp_lcd_touch - registry_url: https://components.espressif.com - require: public - version: ^1.1.0 - - name: idf - require: private - version: '>=4.4.2' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.1.3 espressif/esp_lvgl_port: - component_hash: e720c95cf0667554a204591bb5fade4655fb2990465557041200fa44b5bc7556 + component_hash: f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd dependencies: - name: idf require: private - version: '>=4.4' + version: '>=5.1' - name: lvgl/lvgl registry_url: https://components.espressif.com require: public @@ -184,51 +22,11 @@ dependencies: source: registry_url: https://components.espressif.com/ type: service - version: 2.6.0 - espressif/esp_serial_slave_link: - component_hash: ac1776806de0a6e371c84e87898bb983e19ce62aa7f1e2e5c4a3b0234a575d2c - dependencies: - - name: idf - require: private - version: '>=5.0' - source: - registry_url: https://components.espressif.com - type: service - version: 1.1.2 - espressif/esp_wifi_remote: - component_hash: 20393ed850b2cb40cadcf369b4c852ef5af49e2d89e58774d968c57b0c436fd3 - dependencies: - - name: espressif/eppp_link - registry_url: https://components.espressif.com - require: private - version: '>=0.1' - - name: espressif/esp_hosted - registry_url: https://components.espressif.com - require: private - rules: - - if: target in [esp32h2, esp32p4] - version: '>=0.0.6' - - name: idf - require: private - version: '>=5.3' - source: - registry_url: https://components.espressif.com/ - type: service - version: 0.14.4 + version: 2.7.0 idf: source: type: idf version: 5.5.1 - joltwallet/littlefs: - component_hash: 1808d73e99168f6f3c26dd31799a248484762b3a320ec4962dec11a145f4277f - dependencies: - - name: idf - require: private - version: '>=5.0' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.20.3 lvgl/lvgl: component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f dependencies: [] @@ -236,28 +34,11 @@ dependencies: registry_url: https://components.espressif.com/ type: service version: 9.4.0 - suda-morris/am2302_rmt: - component_hash: 890df8ebfec652eb9f8e1d612959f00a951dbe9241335e5e335fc7fb1468ea32 - dependencies: - - name: idf - require: private - version: '>=5.1' - source: - registry_url: https://components.espressif.com/ - type: service - version: 1.1.0 direct_dependencies: -- chmorgan/esp-audio-player -- chmorgan/esp-file-iterator -- espressif/bh1750 -- espressif/esp32_p4_function_ev_board -- espressif/esp_lcd_touch_gt911 +- espressif/esp_lcd_qemu_rgb - espressif/esp_lvgl_port -- espressif/esp_wifi_remote - idf -- joltwallet/littlefs - lvgl/lvgl -- suda-morris/am2302_rmt -manifest_hash: de62997a910937d24e39c015fd99bd1079849ba3ce9ed3906a52bae461cf5834 -target: esp32p4 +manifest_hash: 4a989d30745f733fc51683ed96b30ee3e7197a9e4e574ab641985cab5013c2be +target: esp32s3 version: 2.0.0 diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 181713e..c96dfe3 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,21 +1,26 @@ -set(EXTRA_COMPONENT_DIRS ../components) +idf_build_get_property(python SIMULATION_QEMU) +message(STATUS "The Python interpreter is: ${python}") -set(comps heap nvs_flash meteofrance esp_netif image_downloader fatfs protocol_examples_common mqtt domotic_display ) +set(comps heap nvs_flash esp_netif image_downloader fatfs protocol_examples_common mqtt) if(${IDF_TARGET} STREQUAL "esp32p4") + message(STATUS "SIMULATION_QEMU = OOF --> main standard") list(APPEND comps bsp_extra esp32_p4_function_ev_board sdmmc vfs littlefs wifi_logger app_update esp_https_ota espcoredump esp_http_server esp_wifi ) + idf_component_register(SRCS main.c obtain_time.c communication.c + INCLUDE_DIRS "./include" + REQUIRES ${comps} + EMBED_TXTFILES ${PROJECT_DIR}/main/ca_cert.pem + EMBED_FILES "index.html") +else() + message(STATUS "SIMULATION_QEMU = On vide le main") + idf_component_register(SRCS test_main.c) + return() endif() -idf_component_register(SRC_DIRS . - INCLUDE_DIRS "." - REQUIRES ${comps} - EMBED_TXTFILES ${project_dir}/main/ca_cert.pem - EMBED_FILES "index.html") - -set_source_files_properties( - PROPERTIES COMPILE_OPTIONS - "-DLV_LVGL_H_INCLUDE_SIMPLE;-Wno-format;-DLV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(montserrat_medium_12) LV_FONT_DECLARE(montserrat_medium_18) LV_FONT_DECLARE(montserrat_medium_24)" - ) +#set_source_files_properties( +# PROPERTIES COMPILE_OPTIONS +# "-DLV_LVGL_H_INCLUDE_SIMPLE;-Wno-format;-DLV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(montserrat_medium_12) LV_FONT_DECLARE(montserrat_medium_18) LV_FONT_DECLARE(montserrat_medium_24)" +# ) diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index bd7b37c..574a7c0 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -12,11 +12,11 @@ menu "Domotic Configuration" help WiFi password (WPA or WPA2) for the example to use. - config GPIO_INPUT_CAPTEUR_PIR - int "GPIO PIN Capteur PIR" - range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX - default 4 - help - GPIO pin à utiliser pour le capteur de présence IR. + #config GPIO_INPUT_CAPTEUR_PIR + # int "GPIO PIN Capteur PIR" + # range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX + # default 4 + # help + # GPIO pin à utiliser pour le capteur de présence IR. endmenu diff --git a/main/idf_component.yml b/main/idf_component.yml index 4ef0e38..3a9f8d0 100644 --- a/main/idf_component.yml +++ b/main/idf_component.yml @@ -1,5 +1,8 @@ dependencies: - espressif/bh1750: ^1.0.3 + espressif/bh1750: + rules: + - if: target in ["esp32p4"] + version: ^1.0.3 espressif/esp_wifi_remote: rules: - if: target in ["esp32p4"] @@ -26,4 +29,4 @@ dependencies: version: 9.4.0 #espressif/esp32_p4_function_ev_board: # version: "4.1.*" - espressif/esp32_p4_function_ev_board: '*' + #espressif/esp32_p4_function_ev_board: '*' diff --git a/main/main.h b/main/include/main.h similarity index 87% rename from main/main.h rename to main/include/main.h index 77e8145..3f59c93 100644 --- a/main/main.h +++ b/main/include/main.h @@ -1,2 +1,2 @@ -#pragma once - +#pragma once + diff --git a/main/obtain_time.h b/main/include/obtain_time.h similarity index 95% rename from main/obtain_time.h rename to main/include/obtain_time.h index 30fe5c3..4528120 100644 --- a/main/obtain_time.h +++ b/main/include/obtain_time.h @@ -1,5 +1,5 @@ -#pragma once -void obtain_time(); -void updateTime(void *pvParameter); - -extern EventGroupHandle_t domotic_event_group; +#pragma once +void obtain_time(); +void updateTime(void *pvParameter); + +extern EventGroupHandle_t domotic_event_group; diff --git a/main/test_main.c b/main/test_main.c new file mode 100644 index 0000000..cae06d0 --- /dev/null +++ b/main/test_main.c @@ -0,0 +1,167 @@ +#include +#include "meteofrance.h" +#include "eventsManager.h" +#include "esp_lcd_panel_ops.h" +#include "esp_lcd_qemu_rgb.h" +#include "lvgl.h" +#include "esp_log.h" + +#include "ihm.h" +#include "esp_heap_caps.h" +extern EventGroupHandle_t domotic_event_group; + +/** + * 32-bit and 16-bit colors are currently supported by QEMU RGB Panel + */ +#if CONFIG_LV_COLOR_DEPTH_32 +#define CURRENT_COLOR_DEPTH RGB_QEMU_BPP_32 +#elif CONFIG_LV_COLOR_DEPTH_16 +#define CURRENT_COLOR_DEPTH RGB_QEMU_BPP_16 +#else +#error "QEMU RGB Panel only supports 32-bit and 16-bit colors, please enable LV_COLOR_DEPTH_32 or LV_COLOR_DEPTH_16" +#endif + +// The pixel number in horizontal and vertical +#define EXAMPLE_LCD_H_RES 800 +#define EXAMPLE_LCD_V_RES 480 + +#define EXAMPLE_LVGL_TICK_PERIOD_MS 2 +#define EXAMPLE_LVGL_TASK_MAX_DELAY_MS 500 +#define EXAMPLE_LVGL_TASK_MIN_DELAY_MS 1 +#define EXAMPLE_LVGL_TASK_STACK_SIZE (10 * 1024) +#define EXAMPLE_LVGL_TASK_PRIORITY 2 +static const char *TAG = "example"; + +SemaphoreHandle_t lvgl_mux; + +static void example_lvgl_flush_cb(lv_display_t *drv, const lv_area_t *area, unsigned char * color_map) +{ + esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)drv->user_data; + int offsetx1 = area->x1; + int offsetx2 = area->x2; + int offsety1 = area->y1; + int offsety2 = area->y2; + // pass the draw buffer to the driver + esp_lcd_panel_draw_bitmap(panel_handle, offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map); + lv_disp_flush_ready(drv); +} + +static void example_increase_lvgl_tick(void *arg) +{ + /* Tell LVGL how many milliseconds has elapsed */ + lv_tick_inc(EXAMPLE_LVGL_TICK_PERIOD_MS); +} + +bool example_lvgl_lock(int timeout_ms) +{ + // Convert timeout in milliseconds to FreeRTOS ticks + // If `timeout_ms` is set to -1, the program will block until the condition is met + const TickType_t timeout_ticks = (timeout_ms == -1) ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms); + return xSemaphoreTakeRecursive(lvgl_mux, timeout_ticks) == pdTRUE; +} + +void example_lvgl_unlock(void) +{ + xSemaphoreGiveRecursive(lvgl_mux); +} + +static void example_lvgl_port_task(void *arg) +{ + ESP_LOGI(TAG, "Starting LVGL task"); + uint32_t task_delay_ms = EXAMPLE_LVGL_TASK_MAX_DELAY_MS; + while (1) + { + // Lock the mutex due to the LVGL APIs are not thread-safe + if (example_lvgl_lock(-1)) + { + task_delay_ms = lv_timer_handler(); + // Release the mutex + example_lvgl_unlock(); + } + if (task_delay_ms > EXAMPLE_LVGL_TASK_MAX_DELAY_MS) + { + task_delay_ms = EXAMPLE_LVGL_TASK_MAX_DELAY_MS; + } + else if (task_delay_ms < EXAMPLE_LVGL_TASK_MIN_DELAY_MS) + { + task_delay_ms = EXAMPLE_LVGL_TASK_MIN_DELAY_MS; + } + vTaskDelay(pdMS_TO_TICKS(task_delay_ms)); + } +} + +static size_t example_lvgl_get_buffers(esp_lcd_panel_handle_t panel_handle, void **buf1, void **buf2) +{ + if (buf2) + { + *buf2 = NULL; + } +#if CONFIG_EXAMPLE_QEMU_RGB_PANEL_DEDIC_FB + ESP_LOGI(TAG, "Use QEMU dedicated frame buffer as LVGL draw buffer"); + ESP_ERROR_CHECK(esp_lcd_rgb_qemu_get_frame_buffer(panel_handle, buf1)); + return EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES; +#else + ESP_LOGI(TAG, "Allocate separate LVGL draw buffer"); + /* Allocate 10 horizontal lines as the frame buffer */ + *buf1 = malloc(EXAMPLE_LCD_H_RES * 10 * sizeof(lv_color_t)); + assert(*buf1); + return EXAMPLE_LCD_H_RES * 10; +#endif // CONFIG_EXAMPLE_DOUBLE_FB +} + +void app_main() +{ + printf(">>> app_main() from test_main.c under Linux\n"); + startEvtManager(); + + ESP_LOGI(TAG, "Install RGB LCD panel driver"); + esp_lcd_panel_handle_t panel_handle = NULL; + esp_lcd_rgb_qemu_config_t panel_config = { + .width = EXAMPLE_LCD_H_RES, + .height = EXAMPLE_LCD_V_RES, + .bpp = CURRENT_COLOR_DEPTH, + }; + ESP_ERROR_CHECK(esp_lcd_new_rgb_qemu(&panel_config, &panel_handle)); + + ESP_LOGI(TAG, "Initialize RGB LCD panel"); + ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); + ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); + + ESP_LOGI(TAG, "Free internal heap: %d", heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); + ESP_LOGI(TAG, "Free SPIRAM heap: %d", heap_caps_get_free_size(MALLOC_CAP_SPIRAM)); + + ESP_LOGI(TAG, "Initialize LVGL library"); + lv_init(); + lv_display_t *disp = lv_display_create(EXAMPLE_LCD_H_RES, EXAMPLE_LCD_V_RES); + disp->user_data=panel_handle; + lv_display_set_flush_cb(disp, example_lvgl_flush_cb); + void *buf1 = NULL; + void *buf2 = NULL; + const size_t buf_pixels = example_lvgl_get_buffers(panel_handle, &buf1, &buf2); + lv_display_set_buffers(disp, buf1, buf2, EXAMPLE_LCD_H_RES * 10 * sizeof(lv_color_t), LV_DISP_RENDER_MODE_PARTIAL); + + lvgl_mux = xSemaphoreCreateRecursiveMutex(); + assert(lvgl_mux); + +/* lv_sdl_mouse_create(); + lv_sdl_keyboard_create(); + lv_sdl_mousewheel_create(); + lv_sdl_mousewheel_create(); + */ + + ESP_LOGI(TAG, "Install LVGL tick timer"); + // Tick interface for LVGL (using esp_timer to generate 2ms periodic event) + const esp_timer_create_args_t lvgl_tick_timer_args = { + .callback = &example_increase_lvgl_tick, + .name = "lvgl_tick"}; + esp_timer_handle_t lvgl_tick_timer = NULL; + ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, EXAMPLE_LVGL_TICK_PERIOD_MS * 1000)); + + ESP_LOGI(TAG, "Create LVGL task"); + xTaskCreate(example_lvgl_port_task, "LVGL", EXAMPLE_LVGL_TASK_STACK_SIZE, NULL, EXAMPLE_LVGL_TASK_PRIORITY, NULL); + + xTaskCreate(drawIhm, "LVGL", 128 * 1024, getIHMQueueHandle(), 3, NULL); + //initialise_weather_data_retrieval(20, domotic_event_group); + printf("<<< end app_main()\n"); +} \ No newline at end of file diff --git a/sdkconfig.defaults b/sdkconfig.defaults index ee7620b..f42cae9 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -8,9 +8,17 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y CONFIG_SPIRAM=y -CONFIG_SPIRAM_SPEED_200M=y -CONFIG_SPIRAM_XIP_FROM_PSRAM=y -CONFIG_CACHE_L2_CACHE_256KB=y +CONFIG_SPIRAM_MODE_QUAD=y +CONFIG_SPIRAM_IGNORE_NOTFOUND=y +# CONFIG_SPIRAM_MEMTEST is not set + +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_USE_CAPS_ALLOC=y + +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=8192 + +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=yCONFIG_CACHE_L2_CACHE_256KB=y CONFIG_CACHE_L2_CACHE_LINE_128B=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y CONFIG_FATFS_LFN_HEAP=y @@ -38,3 +46,4 @@ CONFIG_LV_FS_STDIO_LETTER=65 CONFIG_LV_USE_LODEPNG=y CONFIG_LV_BUILD_EXAMPLES=n CONFIG_IDF_EXPERIMENTAL_FEATURES=y +CONFIG_LV_USE_ASSERT=y