work in qemu

This commit is contained in:
Marc PASTEUR 2025-12-11 18:51:22 +01:00
parent c81027e8e8
commit 88c3c93ae8
30 changed files with 656 additions and 494 deletions

View File

@ -2,7 +2,7 @@
"configurations": [ "configurations": [
{ {
"name": "ESP-IDF", "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", "compileCommands": "${config:idf.buildPath}/compile_commands.json",
"includePath": [ "includePath": [
"${config:idf.espIdfPath}/components/**", "${config:idf.espIdfPath}/components/**",

12
.vscode/settings.json vendored
View File

@ -7,12 +7,12 @@
"idf.customExtraVars": { "idf.customExtraVars": {
"OPENOCD_SCRIPTS": "/home/marc/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240318/openocd-esp32/share/openocd/scripts", "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/", "ESP_ROM_ELF_DIR": "/home/marc/.espressif/tools/esp-rom-elfs/20240305/",
"IDF_TARGET": "esp32p4" "IDF_TARGET": "esp32s3"
}, },
"idf.gitPath": "git", "idf.gitPath": "git",
"idf.adapterTargetName": "esp32s3", "idf.adapterTargetName": "esp32s3",
"idf.openOcdConfigs": [ "idf.openOcdConfigs": [
"board/esp32p4-ftdi.cfg" "board/esp32s3-builtin.cfg"
], ],
"idf.flashType": "UART", "idf.flashType": "UART",
"idf.port": "/dev/ttyUSB0", "idf.port": "/dev/ttyUSB0",
@ -108,5 +108,11 @@
"communication.h": "c", "communication.h": "c",
"mqtt_client.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"
]
} }

View File

@ -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) 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(SIMULATION_QEMU)
if($ENV{IDF_TARGET} STREQUAL "esp32p4") message(STATUS "SIMULATION_QEMU = ON")
include($ENV{IDF_PATH}/tools/cmake/project.cmake) option(SIMULATION_QEMU "Build for QEMU simulation" ON)
# "Trim" the build. Include the minimal set of components, main and anything it depends on. set(COMPONENTS
set(COMPONENTS main) components/meteofrance
set(EXTRA_COMPONENT_DIRS components/domotic_display
/home/marc/esp-dev-kits/examples/esp32-p4-function-ev-board/examples/common_components managed_components/lvgl_lvgl
main
$ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs $ENV{IDF_PATH}/examples/protocols/linux_stubs/esp_stubs
) )
project(rgb_lcd)
add_link_options("-Wl,--disable-non-contiguous-regions")
else() else()
# PROJECT_PLATFORM_LINUX message(STATUS "SIMULATION_QEMU = OFF")
# PROJECT_PLATFORM_ESP32 option(SIMULATION_QEMU "Build for QEMU simulation" OFF)
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 dautres 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)
endif() 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()

7
Kconfig.projbuild Normal file
View File

@ -0,0 +1,7 @@
menu "Simulation options"
config SIMULATION_QEMU
bool "Build with QEMU simulation stubs"
default n
endmenu

View File

@ -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
}

View File

@ -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"
},
}
],
}

View File

@ -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"
}
}

View File

@ -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) 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() endfunction()
make_font(12) #make_font(12)
make_font(18) #make_font(18)
make_font(24) #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 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) #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)
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_ok.png" "images/" "ARGB8888" "NONE")
lvgl_port_create_c_image("images/wifi_ko.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_ok.png" "images/" "AUTO" "NONE")
lvgl_port_create_c_image("images/mqtt_ko.png" "images/" "ARGB8888" "NONE") lvgl_port_create_c_image("images/mqtt_ko.png" "images/" "ARGB8888" "NONE")
lvgl_port_add_images(${COMPONENT_LIB} "images/") lvgl_port_add_images(${COMPONENT_LIB} "images/")
littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT) #littlefs_create_partition_image(littlefs images_meteo FLASH_IN_PROJECT)
endif() #endif()

View File

@ -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

View File

@ -7,6 +7,7 @@
#include "eventsManager.h" #include "eventsManager.h"
#include "bsp/esp-bsp.h" #include "bsp/esp-bsp.h"
#include "lvgl_private.h" #include "lvgl_private.h"
#include "lv_examples.h"
#define upEvent "monter" #define upEvent "monter"
@ -36,7 +37,7 @@ lv_subject_t meteoStatus;
lv_obj_t *jour; lv_obj_t *jour;
static lv_style_t no_padding; static lv_style_t no_padding;
static const char *TAG = "IHM"; //static const char *TAG = "IHM";
static lv_subject_t wifiStatus; static lv_subject_t wifiStatus;
LV_IMAGE_DECLARE(wifi_ok); LV_IMAGE_DECLARE(wifi_ok);
@ -92,17 +93,73 @@ lv_obj_t* myChart;
lv_chart_series_t * ser; lv_chart_series_t * ser;
lv_obj_t *lblHauteurCuve; lv_obj_t *lblHauteurCuve;
lv_obj_t* lblEtatMachine; 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) { void drawIhm(void *xIHMEventQueueParam) {
QueueHandle_t xIHMEventQueue = (QueueHandle_t)xIHMEventQueueParam; QueueHandle_t xIHMEventQueue = (QueueHandle_t)xIHMEventQueueParam;
display_lock("app_main");
init_display_ihm(); 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_init_int(&wifiStatus, 0);
lv_subject_add_observer_obj(&wifiStatus, wifiStatus_obs_cb, NULL, NULL); lv_subject_add_observer_obj(&wifiStatus, wifiStatus_obs_cb, NULL, NULL);
display_lock("app_main");
//lv_example_style_17();
app_main_display(); app_main_display();
display_unlock("app_main"); 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() void app_main_display()
{ {
@ -329,12 +392,7 @@ void app_main_display()
lv_style_init(&no_padding); lv_style_init(&no_padding);
lv_style_set_pad_all(&no_padding, 0); 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); lv_style_init(&style_gradient);
/*First define a color gradient. In this example we use a purple to black color map.*/ /*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_width(label, lv_pct(100));
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); 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_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); lv_obj_align(label, LV_ALIGN_CENTER, 0, 20);
} }
bool display_lock(const char* TAG){ bool display_lock(const char* TAG){
//ESP_LOGI(TAG,"Obtention mutex"); ESP_LOGI(TAG,"Obtention mutex");
if(bsp_display_lock(3000)){ if(bsp_display_lock(3000)){
//ESP_LOGI(TAG, "Mutex obtenu"); ESP_LOGI(TAG, "Mutex obtenu");
return true; return true;
}else{ }else{
//ESP_LOGE(TAG, "Impossible d'obtenir le mutex"); ESP_LOGE(TAG, "Impossible d'obtenir le mutex");
return false; return false;
} }
} }
void display_unlock(const char* TAG){ void display_unlock(const char* TAG){
//ESP_LOGI(TAG,"Libération mutexx"); ESP_LOGI(TAG,"Libération mutexx");
bsp_display_unlock(); bsp_display_unlock();
} }
@ -508,6 +567,8 @@ void showMeteoIcon(const char *icon, lv_obj_t *desc_icon, int childNr)
free(result); free(result);
} }
static lv_style_t tempStyle;
// Ce fragment affiche une prévision journaliere (date,icone, min et max) // 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) 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_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); 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_init(&tempStyle);
// lv_style_set_text_font(&tempStyle,&notomedium16); // lv_style_set_text_font(&tempStyle,&notomedium16);
@ -574,6 +634,7 @@ static lv_obj_t* weatherDay_fragment_create_obj(int dayNr, lv_obj_t *parent)
return container; return container;
} }
static lv_style_t tempStyle;
// Ce fragment affiche une prévision horaire (date,icone, temp moyenne) // 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) 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_width(container, 150);
lv_obj_set_height(container, LV_SIZE_CONTENT); 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,&notomedium16); // lv_style_set_text_font(&tempStyle,&notomedium16);
lv_obj_t *temp = lv_label_create(container); 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)) #define MIN(a,b) ((a) < (b) ? (a) : (b))
static void draw_event_cb(lv_event_t * e) 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 time_observer_cb(lv_observer_t *observer, lv_subject_t *subject)
static void new_theme_apply_cb(lv_theme_t * th, lv_obj_t * obj)
{ {
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)) { char buf[16];
lv_obj_add_style(obj, &style_btn, 0);
} 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 */ /* Dessin IHM */
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
LV_FONT_DECLARE(montserrat_medium_12);
LV_FONT_DECLARE(montserrat_medium_18); lv_color_t base = LV_COLOR_MAKE(126, 94, 133);
LV_FONT_DECLARE(montserrat_medium_24); lv_color_t accent = LV_COLOR_MAKE(204, 16, 16);
LV_FONT_DECLARE(roboto_medium_36); lv_color_t bgColor = LV_COLOR_MAKE(235, 199, 158);
LV_FONT_DECLARE(roboto_medium_72);
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() void draw_ihm()
{ {
lv_display_t * display = lv_display_get_default();
/*Initialize the styles*/ /*Initialize the styles*/
lv_style_init(&style_btn); lv_style_init(&style_btn);
//lv_style_set_bg_color(&style_btn, lv_palette_main(LV_PALETTE_GREEN)); //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_color(&style_btn, lv_palette_darken(LV_PALETTE_GREEN, 3));
//lv_style_set_border_width(&style_btn, 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(&tempExtSubj, tempExtStr, NULL, 6, "--");
lv_subject_init_string(&tempIntSubj, tempIntStr, NULL, 6, "--"); lv_subject_init_string(&tempIntSubj, tempIntStr, NULL, 6, "--");
lv_subject_init_string(&hauteurCuveSubj, hauteurCuveStr, NULL, 9, "--"); 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_size(bg_cont, LV_PCT(100), LV_PCT(100));
lv_obj_set_flex_flow(bg_cont, LV_FLEX_FLOW_COLUMN); 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_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_init(&objstyle);
lv_style_set_bg_color(&objstyle, accent); lv_style_set_bg_color(&objstyle, accent);
lv_style_set_outline_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->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); //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_init(&txtstyle);
lv_style_set_text_color(&txtstyle, accent); lv_style_set_text_color(&txtstyle, accent);
lv_style_set_line_color(&txtstyle, accent); lv_style_set_line_color(&txtstyle, accent);
lv_style_set_text_font(&txtstyle, &roboto_medium_72); lv_style_set_text_font(&txtstyle, &roboto_medium_72);
static lv_style_t txtstyle_inv;
lv_style_init(&txtstyle_inv); lv_style_init(&txtstyle_inv);
lv_style_set_text_color(&txtstyle_inv, base); lv_style_set_text_color(&txtstyle_inv, base);
lv_style_set_line_color(&txtstyle_inv, base); lv_style_set_line_color(&txtstyle_inv, base);
lv_style_set_text_font(&txtstyle_inv, &roboto_medium_72); lv_style_set_text_font(&txtstyle_inv, &roboto_medium_72);
lv_obj_t * time = lv_spangroup_create(date_and_time); lv_obj_t * time = lv_spangroup_create(date_and_time);
lv_obj_add_style(time, &txtstyle, 0); lv_obj_add_style(time, &txtstyle, 0);
lv_span_t * timeSpan = lv_spangroup_add_span(time); lv_span_t * timeSpan = lv_spangroup_add_span(time);
lv_span_set_text(timeSpan,"21"); 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_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_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_style_set_text_font(lv_span_get_style(minute), &roboto_medium_72);
//lv_subject_add_observer_obj(&c->subject_groups.time.group, time_observer_cb, time, c); // 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_remove_style_all(apps);
lv_obj_set_size(apps, LV_PCT(100), LV_SIZE_CONTENT); lv_obj_set_size(apps, LV_PCT(100), LV_SIZE_CONTENT);
lv_obj_set_style_pad_bottom(apps, 8, 0); 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_flex_flow(apps, LV_FLEX_FLOW_ROW);
lv_obj_set_style_pad_column(apps,6, 0); lv_obj_set_style_pad_column(apps,6, 0);
create_card(apps, "Météo"); create_card(apps, "Météo");
create_card(apps,"Volets");
create_card(apps, "Volets");
create_card(apps,"Minuteur"); create_card(apps,"Minuteur");
create_card(apps,"Messagerie"); create_card(apps,"Messagerie");
return;
//Create a Tab view object return;
// ***************************************************************************************************
// Create a Tab view object
tabview = lv_tabview_create(lv_screen_active()); tabview = lv_tabview_create(lv_screen_active());
lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT); lv_tabview_set_tab_bar_position(tabview, LV_DIR_LEFT);
lv_tabview_set_tab_bar_size(tabview, 80); 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_align(&style_container, LV_ALIGN_BOTTOM_LEFT);
lv_style_set_flex_cross_place(&style_container, LV_FLEX_ALIGN_END); 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_init(&no_padding);
lv_style_set_pad_all(&no_padding, 0); 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); 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_style_init(&objstyle);
lv_color_t accent = LV_COLOR_MAKE(0xcc, 0x00, 0x00); //lv_style_init(&txtstyle);
lv_style_set_bg_color(&objstyle, base);
lv_style_set_outline_color(&objstyle, base);
static lv_style_t objstyle; lv_style_set_text_color(&txtstyle, lv_color_white());
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_line_color(&txtstyle, accent); 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; // if(icon_img_dsc == NULL) return;
lv_obj_t *app_card = lv_obj_create(parent); lv_obj_t *app_card = lv_obj_create(parent);
lv_obj_remove_style_all(app_card); lv_obj_remove_style_all(app_card);
lv_obj_set_size(app_card, 300, 180); lv_obj_set_size(app_card, 300, 180);
lv_obj_set_style_radius(app_card, 20, 0); 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_bg_opa(app_card, 50, 0);
lv_obj_set_style_pad_all(app_card, 24, 0);
lv_obj_add_style(app_card, &objstyle, 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_obj_t *label = lv_label_create(app_card);
lv_label_set_text(label, lbl); lv_label_set_text(label, lbl);

View File

@ -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);
}

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "meteofrance.h" #include "meteofrance.h"
#include "lvgl.h" #include "lvgl.h"
#include "model.h"
void app_main_display(); void app_main_display();
void app_ota_display(); void app_ota_display();

View File

@ -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;

View File

@ -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);

View File

@ -0,0 +1,3 @@
{
"idf.pythonInstallPath": "/usr/bin/python3"
}

View File

@ -1,10 +1,11 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main) set(COMPONENTS main)
# This test app doesn't require FreeRTOS, using mock instead # This test app doesn't require FreeRTOS, using mock instead
list(APPEND EXTRA_COMPONENT_DIRS list(APPEND EXTRA_COMPONENT_DIRS
"$ENV{IDF_PATH}/tools/mocks/freertos/" # "$ENV{IDF_PATH}/tools/mocks/freertos/"
"$ENV{IDF_PATH}/tools/mocks/esp_timer" "$ENV{IDF_PATH}/tools/mocks/esp_timer"
../../meteofrance ../../meteofrance
../../stateManagement ../../stateManagement

View File

@ -2,6 +2,7 @@ set(LV_BUILD_USE_KCONFIG ON)
idf_component_register(SRCS idf_component_register(SRCS
"test_ihm.c" "test_ihm.c"
"../../ihm.c" "../../ihm.c"
"../../model.c"
"driver_backends.c" "driver_backends.c"
"sdl.c" "sdl.c"
"../../fonts/montserrat_medium_12.c" "../../fonts/montserrat_medium_12.c"

View File

@ -10,7 +10,7 @@
#include "driver_backends.h" #include "driver_backends.h"
#include "simulator_util.h" #include "simulator_util.h"
#include "simulator_settings.h" #include "simulator_settings.h"
#include "esp_log.h"
esp_mqtt_client_handle_t client; esp_mqtt_client_handle_t client;
/* contains the name of the selected backend if user /* 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 */ /* code */
printf("hello\n"); printf("hello\n");
@ -128,8 +151,20 @@ int main(int argc, char const *argv[])
lv_sdl_keyboard_create(); lv_sdl_keyboard_create();
lv_sdl_mousewheel_create(); lv_sdl_mousewheel_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(); driver_backends_run_loop();
return 0; return 0;

View File

@ -2,7 +2,7 @@
# Espressif IoT Development Framework (ESP-IDF) 5.5.1 Project Minimal Configuration # Espressif IoT Development Framework (ESP-IDF) 5.5.1 Project Minimal Configuration
# #
CONFIG_IDF_TARGET="linux" CONFIG_IDF_TARGET="linux"
CONFIG_LV_CONF_SKIP=n CONFIG_ESP_MAIN_TASK_STACK_SIZE=12288
CONFIG_LV_USE_LOG=y CONFIG_LV_USE_LOG=y
CONFIG_LV_LOG_PRINTF=y CONFIG_LV_LOG_PRINTF=y
CONFIG_LV_FONT_MONTSERRAT_40=y CONFIG_LV_FONT_MONTSERRAT_40=y

View File

@ -6,7 +6,7 @@
EventGroupHandle_t domotic_event_group; EventGroupHandle_t domotic_event_group;
QueueHandle_t ihm_queue; QueueHandle_t ihm_queue;
extern esp_mqtt_client_handle_t client; //extern esp_mqtt_client_handle_t client;
static const char *TAG = "evtMgr"; static const char *TAG = "evtMgr";
@ -62,7 +62,7 @@ void send_event(domo_events evt, void* pDatas) {
break; break;
case EVT_BTN_VOLET: 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 free(ihmEvt); // rien à envoyer à l'IHM
return; return;
@ -115,11 +115,15 @@ void send_event(domo_events evt, void* pDatas) {
return; return;
} }
ESP_LOGE(TAG, "Envoi d'un evt %i a l'IHM", ihmEvt->eEventType); ESP_LOGE(TAG, "Envoi d'un evt %i a l'IHM", ihmEvt->eEventType);
if (ihmEvt && xQueueSendToFront(ihm_queue, &ihmEvt, pdMS_TO_TICKS(10)) != pdPASS) { if( 0 && ihm_queue != NULL ){
ESP_LOGE(TAG, "La queue est pleine"); if (ihmEvt && xQueueSendToFront(ihm_queue, &ihmEvt, pdMS_TO_TICKS(10)) != pdPASS)
if (ihmEvt->bNeedToFreeData && ihmEvt->pvData) { {
free(ihmEvt->pvData); ESP_LOGE(TAG, "La queue est pleine");
if (ihmEvt->bNeedToFreeData && ihmEvt->pvData)
{
free(ihmEvt->pvData);
}
free(ihmEvt);
} }
free(ihmEvt);
} }
} }

View File

@ -1,11 +1,11 @@
IF(ESP_PLATFORM) #IF(ESP_PLATFORM)
idf_component_register(SRCS "meteofrance.c" idf_component_register(SRCS "meteofrance.c"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
REQUIRES json esp_http_client esp-tls stateManagement eventsManager) REQUIRES json esp_http_client esp-tls stateManagement eventsManager)
else() #else()
add_library(meteofrance SHARED # add_library(meteofrance SHARED
meteofrance.c) # meteofrance.c)
target_include_directories(meteofrance PUBLIC ./include) # target_include_directories(meteofrance PUBLIC ./include)
target_link_libraries(meteofrance PRIVATE stateManagement FreeRTOS freertos_kernel) # target_link_libraries(meteofrance PRIVATE stateManagement FreeRTOS freertos_kernel)
endif() #endif()

View File

@ -3,62 +3,66 @@
#include "stdbool.h" #include "stdbool.h"
#include "stateManagement.h" #include "stateManagement.h"
/*struct node { /*struct node {
struct node *next; struct node *next;
int e; int e;
};
struct Hashtable {
unsigned Tablesize;
struct node *Cells;
};
*/
struct dailyforecast_prev
{
float min;
float max;
char desc[25];
char icon[9];
}; };
struct Hashtable { struct forecast_prev
unsigned Tablesize; {
struct node *Cells; float value;
char desc[25];
char icon[9];
}; };
*/
struct dailyforecast_prev{ typedef struct meteodailyforecast_data
float min; {
float max; time_t datetime;
char desc[25]; bool isValid;
char icon[9]; struct dailyforecast_prev previsions;
}; } meteodailyforecast_data;
struct forecast_prev{ typedef struct meteoforecast_data
float value; {
char desc[25]; time_t datetime;
char icon[9]; bool isValid;
}; struct forecast_prev previsions;
} meteoforecast_data;
typedef struct meteodailyforecast_data{ typedef void (*weather_data_callback)(struct meteodailyforecast_data *datas, struct meteoforecast_data *datasf);
time_t datetime; typedef void (*weather_data_start_callback)();
bool isValid;
struct dailyforecast_prev previsions;
} meteodailyforecast_data;
typedef struct meteoforecast_data{ typedef struct
time_t datetime; {
bool isValid; unsigned int humidity;
struct forecast_prev previsions; float temperature;
} meteoforecast_data; 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); void printdftemp(struct dailyforecast_prev * tmp);
typedef void (*weather_data_start_callback)(); void printftemp(struct forecast_prev * tmp);
void printfdf(struct meteodailyforecast_data * tmp);
typedef struct { void dtToString(time_t, char *buffer);
unsigned int humidity; void dtHToString(time_t, char *buffer);
float temperature; void printff(struct meteoforecast_data * tmp);
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 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);

View File

@ -1,182 +1,20 @@
dependencies: dependencies:
chmorgan/esp-audio-player: espressif/esp_lcd_qemu_rgb:
component_hash: c8ac1998e9af863bc41b57e592f88d1a5791a0f891485122336ddabbf7a65033 component_hash: e8981dd7399504a5ab647ce28a4876f8467c03b759895f50c24f0cb6095faaa0
dependencies: dependencies:
- name: chmorgan/esp-libhelix-mp3
registry_url: https://components.espressif.com
require: private
version: '>=1.0.0,<2.0.0'
- name: idf - name: idf
require: private require: private
version: '>=5.0' version: '>=5.3'
source: source:
registry_url: https://components.espressif.com/ registry_url: https://components.espressif.com/
type: service 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 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: espressif/esp_lvgl_port:
component_hash: e720c95cf0667554a204591bb5fade4655fb2990465557041200fa44b5bc7556 component_hash: f872401524cb645ee6ff1c9242d44fb4ddcfd4d37d7be8b9ed3f4e85a404efcd
dependencies: dependencies:
- name: idf - name: idf
require: private require: private
version: '>=4.4' version: '>=5.1'
- name: lvgl/lvgl - name: lvgl/lvgl
registry_url: https://components.espressif.com registry_url: https://components.espressif.com
require: public require: public
@ -184,51 +22,11 @@ dependencies:
source: source:
registry_url: https://components.espressif.com/ registry_url: https://components.espressif.com/
type: service type: service
version: 2.6.0 version: 2.7.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
idf: idf:
source: source:
type: idf type: idf
version: 5.5.1 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: lvgl/lvgl:
component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f component_hash: 17e68bfd21f0edf4c3ee838e2273da840bf3930e5dbc3bfa6c1190c3aed41f9f
dependencies: [] dependencies: []
@ -236,28 +34,11 @@ dependencies:
registry_url: https://components.espressif.com/ registry_url: https://components.espressif.com/
type: service type: service
version: 9.4.0 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: direct_dependencies:
- chmorgan/esp-audio-player - espressif/esp_lcd_qemu_rgb
- chmorgan/esp-file-iterator
- espressif/bh1750
- espressif/esp32_p4_function_ev_board
- espressif/esp_lcd_touch_gt911
- espressif/esp_lvgl_port - espressif/esp_lvgl_port
- espressif/esp_wifi_remote
- idf - idf
- joltwallet/littlefs
- lvgl/lvgl - lvgl/lvgl
- suda-morris/am2302_rmt manifest_hash: 4a989d30745f733fc51683ed96b30ee3e7197a9e4e574ab641985cab5013c2be
manifest_hash: de62997a910937d24e39c015fd99bd1079849ba3ce9ed3906a52bae461cf5834 target: esp32s3
target: esp32p4
version: 2.0.0 version: 2.0.0

View File

@ -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") 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 ) 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() 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(
set_source_files_properties( # PROPERTIES COMPILE_OPTIONS
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)"
"-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)" # )
)

View File

@ -12,11 +12,11 @@ menu "Domotic Configuration"
help help
WiFi password (WPA or WPA2) for the example to use. WiFi password (WPA or WPA2) for the example to use.
config GPIO_INPUT_CAPTEUR_PIR #config GPIO_INPUT_CAPTEUR_PIR
int "GPIO PIN Capteur PIR" # int "GPIO PIN Capteur PIR"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX # range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 4 # default 4
help # help
GPIO pin à utiliser pour le capteur de présence IR. # GPIO pin à utiliser pour le capteur de présence IR.
endmenu endmenu

View File

@ -1,5 +1,8 @@
dependencies: dependencies:
espressif/bh1750: ^1.0.3 espressif/bh1750:
rules:
- if: target in ["esp32p4"]
version: ^1.0.3
espressif/esp_wifi_remote: espressif/esp_wifi_remote:
rules: rules:
- if: target in ["esp32p4"] - if: target in ["esp32p4"]
@ -26,4 +29,4 @@ dependencies:
version: 9.4.0 version: 9.4.0
#espressif/esp32_p4_function_ev_board: #espressif/esp32_p4_function_ev_board:
# version: "4.1.*" # version: "4.1.*"
espressif/esp32_p4_function_ev_board: '*' #espressif/esp32_p4_function_ev_board: '*'

167
main/test_main.c Normal file
View File

@ -0,0 +1,167 @@
#include <stdio.h>
#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");
}

View File

@ -8,9 +8,17 @@ CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y
CONFIG_SPIRAM=y CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_200M=y CONFIG_SPIRAM_MODE_QUAD=y
CONFIG_SPIRAM_XIP_FROM_PSRAM=y CONFIG_SPIRAM_IGNORE_NOTFOUND=y
CONFIG_CACHE_L2_CACHE_256KB=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_CACHE_L2_CACHE_LINE_128B=y
CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
CONFIG_FATFS_LFN_HEAP=y CONFIG_FATFS_LFN_HEAP=y
@ -38,3 +46,4 @@ CONFIG_LV_FS_STDIO_LETTER=65
CONFIG_LV_USE_LODEPNG=y CONFIG_LV_USE_LODEPNG=y
CONFIG_LV_BUILD_EXAMPLES=n CONFIG_LV_BUILD_EXAMPLES=n
CONFIG_IDF_EXPERIMENTAL_FEATURES=y CONFIG_IDF_EXPERIMENTAL_FEATURES=y
CONFIG_LV_USE_ASSERT=y