diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a88f44f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "examples/common_components/lvgl"] + path = examples/common_components/lvgl + url = git@github.com:lvgl/lvgl.git diff --git a/examples/common_components/lvgl b/examples/common_components/lvgl new file mode 160000 index 0000000..ec9de51 --- /dev/null +++ b/examples/common_components/lvgl @@ -0,0 +1 @@ +Subproject commit ec9de515b36641be565d7bace5863ab631ce3b69 diff --git a/examples/wemos_lolin_oled/hello_world/CMakeLists.txt b/examples/wemos_lolin_oled/hello_world/CMakeLists.txt new file mode 100644 index 0000000..b65f74e --- /dev/null +++ b/examples/wemos_lolin_oled/hello_world/CMakeLists.txt @@ -0,0 +1,9 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five 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.5) + +set(EXTRA_COMPONENT_DIRS ../../common_components ../../..) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(hello_world) diff --git a/examples/wemos_lolin_oled/hello_world/main/CMakeLists.txt b/examples/wemos_lolin_oled/hello_world/main/CMakeLists.txt new file mode 100644 index 0000000..4e8dbcf --- /dev/null +++ b/examples/wemos_lolin_oled/hello_world/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "hello_world.c" + INCLUDE_DIRS ".") diff --git a/examples/wemos_lolin_oled/hello_world/main/hello_world.c b/examples/wemos_lolin_oled/hello_world/main/hello_world.c new file mode 100644 index 0000000..3b0e6b4 --- /dev/null +++ b/examples/wemos_lolin_oled/hello_world/main/hello_world.c @@ -0,0 +1,98 @@ +/* Hello world on Wemos Lolin32 board + * + * This example code is in the Public Domain (or CC0 licensed, at your option.) + * + * Unless required by applicable law or agreed to in writing, this + * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + * CONDITIONS OF ANY KIND, either express or implied. + */ +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_freertos_hooks.h" +#include "freertos/semphr.h" +#include "esp_system.h" +#include "driver/gpio.h" + +/* Littlevgl specific */ +#ifdef LV_LVGL_H_INCLUDE_SIMPLE +#include "lvgl.h" +#else +#include "lvgl/lvgl.h" +#endif + +#include "lvgl_helpers.h" + +/********************* + * DEFINES + *********************/ +#define LV_TICK_PERIOD_MS 1 + +/********************** + * STATIC PROTOTYPES + **********************/ +static void lvgl_tick_inc(void *arg); +static void guiTask(void *pvParameter); + +/********************** + * APPLICATION MAIN + **********************/ +void app_main() +{ + xTaskCreatePinnedToCore(guiTask, "gui", 4096*2, NULL, 0, NULL, 1); +} + +static void guiTask(void *pvParameter) +{ + (void) pvParameter; + lv_init(); + lvgl_driver_init(); + + lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA); + assert(buf1 != NULL); + + static lv_disp_buf_t disp_buf; + lv_disp_buf_init(&disp_buf, buf1, NULL, DISP_BUF_SIZE * 8); + + lv_disp_drv_t disp_drv; + lv_disp_drv_init(&disp_drv); + disp_drv.flush_cb = disp_driver_flush; + disp_drv.rounder_cb = disp_driver_rounder; + disp_drv.set_px_cb = disp_driver_set_px; + disp_drv.buffer = &disp_buf; + lv_disp_drv_register(&disp_drv); + + /* Create and start a periodic timer interrupt to call lv_tick_inc */ + const esp_timer_create_args_t periodic_timer_args = { + .callback = &lvgl_tick_inc, + .name = "lvgl_tick" + }; + esp_timer_handle_t periodic_timer; + ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer)); + ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000)); + + /* Create a Hellow World label on the currently active screen */ + lv_obj_t *scr = lv_disp_get_scr_act(NULL); + lv_obj_t *label1 = lv_label_create(scr, NULL); + lv_label_set_text(label1, "Hello\nworld"); + + /* Align the Label to the center + * NULL means align on parent (which is the screen now) + * 0, 0 at the end means an x, y offset after alignment*/ + lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0); + + while (1) { + vTaskDelay(pdMS_TO_TICKS(10)); + lv_task_handler(); + } + free(buf1); +} + +static void lvgl_tick_inc(void *arg) { + (void) arg; + lv_tick_inc(LV_TICK_PERIOD_MS); +} diff --git a/examples/wemos_lolin_oled/hello_world/sdkconfig.defaults b/examples/wemos_lolin_oled/hello_world/sdkconfig.defaults new file mode 100644 index 0000000..b92d2d5 --- /dev/null +++ b/examples/wemos_lolin_oled/hello_world/sdkconfig.defaults @@ -0,0 +1,11 @@ +CONFIG_LV_HOR_RES_MAX=128 +CONFIG_LV_VER_RES_MAX=64 +CONFIG_LV_COLOR_DEPTH_1=y +CONFIG_LV_THEME_MONO=y + +CONFIG_LV_PREDEFINED_DISPLAY_WEMOS_LOLIN=y + +CONFIG_I2C_MANAGER_0_ENABLED=y +CONFIG_I2C_MANAGER_0_SDA=5 +CONFIG_I2C_MANAGER_0_SCL=4 +CONFIG_I2C_MANAGER_0_FREQ_HZ=100000