domotic/main/test_main.c

164 lines
5.6 KiB
C

#include <stdio.h>
#include "meteofrance.h"
#include "eventsManager.h"
#include "lvgl.h"
#include "esp_log.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");
}