Initial commit.
This commit is contained in:
commit
7f183e2928
11
.clang-format
Normal file
11
.clang-format
Normal file
|
@ -0,0 +1,11 @@
|
|||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
AlignConsecutiveMacros: AcrossEmptyLines
|
||||
AlignConsecutiveDeclarations: true
|
||||
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterEnum: false
|
||||
AfterStruct: false
|
||||
SplitEmptyFunction: false
|
||||
ColumnLimit: 120
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/build
|
||||
/sdkconfig
|
||||
/sdkconfig.old
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
[submodule "components/lvgl"]
|
||||
path = components/lvgl
|
||||
url = https://github.com/lvgl/lvgl.git
|
||||
[submodule "main/lib/epd-spi"]
|
||||
path = main/lib/epd-spi
|
||||
url = https://github.com/imi415/epd-spi.git
|
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# 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.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(esp32_s2_cal)
|
8
Makefile
Normal file
8
Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := esp32_s2_cal
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
52
README.md
Normal file
52
README.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Hello World Example
|
||||
|
||||
Starts a FreeRTOS task to print "Hello World".
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
## How to use example
|
||||
|
||||
Follow detailed instructions provided specifically for this example.
|
||||
|
||||
Select the instructions depending on Espressif chip installed on your development board:
|
||||
|
||||
- [ESP32 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/index.html)
|
||||
- [ESP32-S2 Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/get-started/index.html)
|
||||
|
||||
|
||||
## Example folder contents
|
||||
|
||||
The project **hello_world** contains one source file in C language [hello_world_main.c](main/hello_world_main.c). The file is located in folder [main](main).
|
||||
|
||||
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt` files that provide set of directives and instructions describing the project's source files and targets (executable, library, or both).
|
||||
|
||||
Below is short explanation of remaining files in the project folder.
|
||||
|
||||
```
|
||||
├── CMakeLists.txt
|
||||
├── example_test.py Python script used for automated example testing
|
||||
├── main
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── component.mk Component make file
|
||||
│ └── hello_world_main.c
|
||||
├── Makefile Makefile used by legacy GNU Make
|
||||
└── README.md This is the file you are currently reading
|
||||
```
|
||||
|
||||
For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html) of the ESP-IDF Programming Guide.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
* Program upload failure
|
||||
|
||||
* Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs.
|
||||
* The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again.
|
||||
|
||||
## Technical support and feedback
|
||||
|
||||
Please use the following feedback channels:
|
||||
|
||||
* For technical queries, go to the [esp32.com](https://esp32.com/) forum
|
||||
* For a feature request or bug report, create a [GitHub issue](https://github.com/espressif/esp-idf/issues)
|
||||
|
||||
We will get back to you as soon as possible.
|
1
components/lvgl
Submodule
1
components/lvgl
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit d38eb1e689fa5a64c25e677275172d9c8a4ab2f0
|
12
main/CMakeLists.txt
Normal file
12
main/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
idf_component_register(SRCS
|
||||
"main.c"
|
||||
"helper/helper_wifi.c"
|
||||
"impl/impl_epd.c"
|
||||
"impl/impl_lvgl.c"
|
||||
"lib/epd-spi/src/epd_common.c"
|
||||
"lib/epd-spi/src/epd_panel_gdew042t2.c"
|
||||
|
||||
INCLUDE_DIRS
|
||||
"lib/epd-spi/include"
|
||||
"impl"
|
||||
)
|
4
main/component.mk
Normal file
4
main/component.mk
Normal file
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
17
main/helper/helper_wifi.c
Normal file
17
main/helper/helper_wifi.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "esp_log.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
esp_err_t helper_wifi_init(void) {
|
||||
// Check stored credentials from NVS,
|
||||
// if no credentials stored or button pressed, force initiate easy connect
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void helper_wifi_task(void *pvParameters) {
|
||||
//
|
||||
}
|
179
main/impl/impl_epd.c
Normal file
179
main/impl/impl_epd.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
|
||||
#include "impl_epd.h"
|
||||
|
||||
#define EPD_GPIO_MOSI GPIO_NUM_15
|
||||
#define EPD_GPIO_SCLK GPIO_NUM_14
|
||||
#define EPD_GPIO_BUSY GPIO_NUM_11
|
||||
#define EPD_GPIO_CS GPIO_NUM_13
|
||||
#define EPD_GPIO_RES GPIO_NUM_10
|
||||
#define EPD_GPIO_DC GPIO_NUM_12
|
||||
|
||||
#define EPD_SPI_HOST SPI2_HOST
|
||||
#define EPD_SPI_SPEED (16 * 1000 * 1000) /* 16MHz */
|
||||
#define EPD_SPI_MAX_XFER_SIZE (1024)
|
||||
|
||||
/* Pre-transfer callback for SPI driver. */
|
||||
static void impl_epd_spi_pre_transfer_cb(spi_transaction_t *txn) {
|
||||
uint32_t dc_value = (uint32_t)txn->user;
|
||||
gpio_set_level(EPD_GPIO_DC, dc_value);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR impl_epd_busy_irq_handler(void *arg) {
|
||||
impl_epd_handle_t *epd = arg;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
|
||||
xSemaphoreGiveFromISR(epd->busy_semaphore, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
esp_err_t impl_epd_init(void *handle) {
|
||||
esp_err_t ret;
|
||||
spi_bus_config_t bus_config = {
|
||||
.mosi_io_num = EPD_GPIO_MOSI,
|
||||
.sclk_io_num = EPD_GPIO_SCLK,
|
||||
.miso_io_num = -1,
|
||||
.quadwp_io_num = -1,
|
||||
.quadhd_io_num = -1,
|
||||
.max_transfer_sz = EPD_SPI_MAX_XFER_SIZE,
|
||||
};
|
||||
spi_device_interface_config_t device_config = {
|
||||
.clock_speed_hz = EPD_SPI_SPEED,
|
||||
.mode = 0,
|
||||
.spics_io_num = EPD_GPIO_CS,
|
||||
.queue_size = 7,
|
||||
.pre_cb = impl_epd_spi_pre_transfer_cb,
|
||||
};
|
||||
|
||||
impl_epd_handle_t *epd = handle;
|
||||
|
||||
/* Initialize SPI bus */
|
||||
ret = spi_bus_initialize(EPD_SPI_HOST, &bus_config, SPI_DMA_CH_AUTO);
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
ret = spi_bus_add_device(EPD_SPI_HOST, &device_config, &epd->spi);
|
||||
ESP_ERROR_CHECK(ret);
|
||||
|
||||
/* Initialize RTOS components */
|
||||
epd->busy_semaphore = xSemaphoreCreateBinary();
|
||||
if (epd->busy_semaphore == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Initialize auxillary IOs */
|
||||
gpio_set_direction(EPD_GPIO_BUSY, GPIO_MODE_INPUT);
|
||||
gpio_set_direction(EPD_GPIO_DC, GPIO_MODE_OUTPUT);
|
||||
gpio_set_direction(EPD_GPIO_RES, GPIO_MODE_OUTPUT);
|
||||
|
||||
// Set up EPD busy interrupt
|
||||
gpio_pullup_en(EPD_GPIO_BUSY);
|
||||
gpio_set_intr_type(EPD_GPIO_BUSY, GPIO_INTR_POSEDGE);
|
||||
gpio_isr_handler_add(EPD_GPIO_BUSY, impl_epd_busy_irq_handler, epd);
|
||||
|
||||
/* Release RESET pin */
|
||||
gpio_set_level(EPD_GPIO_RES, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
epd_ret_t impl_epd_write_command(void *handle, uint8_t *command, uint32_t len) {
|
||||
esp_err_t ret = EPD_OK;
|
||||
spi_transaction_t txn;
|
||||
|
||||
impl_epd_handle_t *epd = handle;
|
||||
|
||||
memset(&txn, 0x0, sizeof(txn));
|
||||
|
||||
txn.length = 8;
|
||||
txn.tx_buffer = command;
|
||||
txn.user = (void *)0;
|
||||
|
||||
ret = spi_device_polling_transmit(epd->spi, &txn);
|
||||
if (ret != ESP_OK) ret = EPD_FAIL;
|
||||
|
||||
if (len > 1) {
|
||||
txn.length = 8 * (len - 1);
|
||||
txn.tx_buffer = &command[1];
|
||||
txn.user = (void *)1;
|
||||
|
||||
ret = spi_device_polling_transmit(epd->spi, &txn);
|
||||
if (ret != ESP_OK) ret = EPD_FAIL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
epd_ret_t impl_epd_write_data(void *handle, uint8_t *data, uint32_t len) {
|
||||
esp_err_t ret = EPD_OK;
|
||||
spi_transaction_t txn;
|
||||
|
||||
impl_epd_handle_t *epd = handle;
|
||||
|
||||
uint8_t *dma_buffer = heap_caps_malloc(EPD_SPI_MAX_XFER_SIZE, MALLOC_CAP_DMA);
|
||||
if (dma_buffer == NULL) return EPD_FAIL;
|
||||
|
||||
memset(&txn, 0x0, sizeof(txn));
|
||||
|
||||
uint8_t has_partial = (len % EPD_SPI_MAX_XFER_SIZE ? 1 : 0);
|
||||
uint32_t txn_count = len / EPD_SPI_MAX_XFER_SIZE + has_partial;
|
||||
|
||||
txn.user = (void *)1;
|
||||
|
||||
for (uint32_t i = 0; i < txn_count; i++) {
|
||||
uint16_t txn_bytes = EPD_SPI_MAX_XFER_SIZE;
|
||||
if ((i == txn_count - 1) && has_partial) {
|
||||
txn_bytes = len % EPD_SPI_MAX_XFER_SIZE;
|
||||
}
|
||||
|
||||
memcpy(dma_buffer, &data[i * EPD_SPI_MAX_XFER_SIZE], txn_bytes);
|
||||
|
||||
txn.length = 8 * txn_bytes;
|
||||
txn.rxlength = 0;
|
||||
txn.tx_buffer = dma_buffer;
|
||||
|
||||
ret = spi_device_polling_transmit(epd->spi, &txn);
|
||||
if (ret != ESP_OK) ret = EPD_FAIL;
|
||||
}
|
||||
|
||||
free(dma_buffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
epd_ret_t impl_epd_reset(void *handle) {
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
gpio_set_level(EPD_GPIO_RES, 0);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
gpio_set_level(EPD_GPIO_RES, 1);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t impl_epd_poll_busy(void *handle) {
|
||||
impl_epd_handle_t *epd = handle;
|
||||
|
||||
if (gpio_get_level(EPD_GPIO_BUSY) == 1) {
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
gpio_intr_enable(EPD_GPIO_BUSY);
|
||||
|
||||
if (xSemaphoreTake(epd->busy_semaphore, pdMS_TO_TICKS(10000)) != pdTRUE) {
|
||||
gpio_intr_disable(EPD_GPIO_BUSY);
|
||||
|
||||
return EPD_FAIL;
|
||||
}
|
||||
|
||||
gpio_intr_disable(EPD_GPIO_BUSY);
|
||||
|
||||
return EPD_OK;
|
||||
}
|
||||
|
||||
epd_ret_t impl_epd_delay(void *handle, uint32_t msec) {
|
||||
vTaskDelay(pdMS_TO_TICKS(msec));
|
||||
|
||||
return EPD_OK;
|
||||
}
|
25
main/impl/impl_epd.h
Normal file
25
main/impl/impl_epd.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef IMPL_EPD_H
|
||||
#define IMPL_EPD_H
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "esp_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/task.h"
|
||||
//
|
||||
#include "epd_panel_gdew042t2.h"
|
||||
|
||||
typedef struct {
|
||||
spi_device_handle_t spi;
|
||||
SemaphoreHandle_t busy_semaphore;
|
||||
} impl_epd_handle_t;
|
||||
|
||||
esp_err_t impl_epd_init(void *handle);
|
||||
epd_ret_t impl_epd_write_command(void *handle, uint8_t *command, uint32_t len);
|
||||
epd_ret_t impl_epd_write_data(void *handle, uint8_t *data, uint32_t len);
|
||||
epd_ret_t impl_epd_reset(void *handle);
|
||||
epd_ret_t impl_epd_poll_busy(void *handle);
|
||||
epd_ret_t impl_epd_delay(void *handle, uint32_t msec);
|
||||
|
||||
#endif
|
186
main/impl/impl_lvgl.c
Normal file
186
main/impl/impl_lvgl.c
Normal file
|
@ -0,0 +1,186 @@
|
|||
#include "impl_lvgl.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "impl_epd.h"
|
||||
|
||||
#define EPD_DISPLAY_PIXEL_COUNT 400 * 300
|
||||
#define EPD_DISPLAY_FRAME_SIZE (EPD_DISPLAY_PIXEL_COUNT * 2 / 8)
|
||||
|
||||
#define EPD_DISPLAY_GS 0
|
||||
#define EPD_DISPLAY_MAX_PARTIAL 6
|
||||
|
||||
static impl_epd_handle_t s_epd_impl;
|
||||
|
||||
static epd_gdew042t2_t s_gd_epd = {
|
||||
.cb =
|
||||
{
|
||||
.reset_cb = impl_epd_reset,
|
||||
.write_command_cb = impl_epd_write_command,
|
||||
.write_data_cb = impl_epd_write_data,
|
||||
.poll_busy_cb = impl_epd_poll_busy,
|
||||
.delay_cb = impl_epd_delay,
|
||||
},
|
||||
#if EPD_DISPLAY_GS
|
||||
.mode = EPD_GDEW042T2_MODE_GS,
|
||||
#else
|
||||
.mode = EPD_GDEW042T2_MODE_BW,
|
||||
#endif
|
||||
.user_data = &s_epd_impl,
|
||||
};
|
||||
|
||||
#if !EPD_DISPLAY_GS
|
||||
static uint8_t s_epd_partial_counter = EPD_DISPLAY_MAX_PARTIAL - 1;
|
||||
#endif
|
||||
|
||||
static lv_disp_draw_buf_t s_disp_buf;
|
||||
static lv_color_t s_disp_store[EPD_DISPLAY_FRAME_SIZE];
|
||||
static lv_disp_drv_t s_disp_drv;
|
||||
|
||||
static TaskHandle_t s_lv_tick_handle;
|
||||
static TaskHandle_t s_lv_task_handle;
|
||||
static SemaphoreHandle_t s_lv_semphr_handle;
|
||||
|
||||
static void impl_lvgl_epd_set_px_cb(lv_disp_drv_t *disp_drv, uint8_t *buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y,
|
||||
lv_color_t color, lv_opa_t opa) {
|
||||
uint32_t byte_index = (buf_w * y + x) / 8;
|
||||
uint8_t bit_index = 7 - (x % 8);
|
||||
|
||||
uint8_t brightness = lv_color_brightness(color);
|
||||
|
||||
#if EPD_DISPLAY_GS
|
||||
if (brightness < 64) {
|
||||
buf[byte_index] &= ~(1 << bit_index);
|
||||
buf[15000 + byte_index] &= ~(1 << bit_index);
|
||||
} else if (brightness < 128) {
|
||||
buf[byte_index] &= ~(1 << bit_index);
|
||||
buf[15000 + byte_index] |= (1 << bit_index);
|
||||
} else if (brightness < 192) {
|
||||
buf[byte_index] |= (1 << bit_index);
|
||||
buf[15000 + byte_index] &= ~(1 << bit_index);
|
||||
} else {
|
||||
buf[byte_index] |= (1 << bit_index);
|
||||
buf[15000 + byte_index] |= (1 << bit_index);
|
||||
}
|
||||
#else
|
||||
uint8_t current_frame = 0;
|
||||
if ((s_epd_partial_counter % 2) == 1) {
|
||||
current_frame = 1;
|
||||
}
|
||||
|
||||
if (brightness > 128) {
|
||||
buf[current_frame * 15000 + byte_index] |= (1 << bit_index);
|
||||
} else {
|
||||
buf[current_frame * 15000 + byte_index] &= ~(1 << bit_index);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void impl_lvgl_epd_flush_cb(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) {
|
||||
epd_coord_t coord = {
|
||||
.x_start = 0,
|
||||
.x_end = 399,
|
||||
.y_start = 0,
|
||||
.y_end = 299,
|
||||
};
|
||||
|
||||
#if EPD_DISPLAY_GS
|
||||
epd_gdew042t2_upload(&s_gd_epd, &coord, (uint8_t *)color_p, (uint8_t *)&color_p[15000]);
|
||||
#else
|
||||
if (s_epd_partial_counter == 0) {
|
||||
s_epd_partial_counter = EPD_DISPLAY_MAX_PARTIAL - 1;
|
||||
|
||||
s_gd_epd.mode = EPD_GDEW042T2_MODE_BW;
|
||||
|
||||
// Flush to full
|
||||
epd_gdew042t2_upload(&s_gd_epd, &coord, (uint8_t *)color_p, (uint8_t *)color_p);
|
||||
} else {
|
||||
s_gd_epd.mode = EPD_GDEW042T2_MODE_BW_PART;
|
||||
|
||||
// Even: buffer 0, odd: buffer 1
|
||||
if ((s_epd_partial_counter % 2) == 1) {
|
||||
epd_gdew042t2_upload(&s_gd_epd, &coord, (uint8_t *)color_p, (uint8_t *)&color_p[15000]);
|
||||
} else {
|
||||
epd_gdew042t2_upload(&s_gd_epd, &coord, (uint8_t *)&color_p[15000], (uint8_t *)color_p);
|
||||
}
|
||||
s_epd_partial_counter--;
|
||||
}
|
||||
#endif
|
||||
|
||||
lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
||||
static void impl_lvgl_epd_rounder_cb(lv_disp_drv_t *disp_drv, lv_area_t *area) {
|
||||
area->x1 = 0;
|
||||
area->x2 = 399;
|
||||
}
|
||||
|
||||
static void impl_lvgl_log_cb(const char *buf) { ESP_LOGI("LVGL", "%s", buf); }
|
||||
|
||||
void impl_lvgl_timer_task(void *pvParameters) {
|
||||
for (;;) {
|
||||
impl_lvgl_lock();
|
||||
lv_timer_handler();
|
||||
impl_lvgl_unlock();
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
}
|
||||
|
||||
void impl_lvgl_tick_task(void *pvParameters) {
|
||||
for (;;) {
|
||||
impl_lvgl_lock();
|
||||
lv_tick_inc(50);
|
||||
impl_lvgl_unlock();
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t impl_lvgl_lock(void) {
|
||||
if (xSemaphoreTake(s_lv_semphr_handle, portMAX_DELAY) != pdTRUE) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t impl_lvgl_unlock(void) {
|
||||
xSemaphoreGive(s_lv_semphr_handle);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t impl_lvgl_init(void) {
|
||||
ESP_ERROR_CHECK(impl_epd_init(&s_epd_impl));
|
||||
|
||||
lv_init();
|
||||
lv_disp_draw_buf_init(&s_disp_buf, s_disp_store, NULL, EPD_DISPLAY_PIXEL_COUNT);
|
||||
lv_disp_drv_init(&s_disp_drv);
|
||||
|
||||
s_disp_drv.set_px_cb = impl_lvgl_epd_set_px_cb;
|
||||
s_disp_drv.flush_cb = impl_lvgl_epd_flush_cb;
|
||||
s_disp_drv.rounder_cb = impl_lvgl_epd_rounder_cb;
|
||||
s_disp_drv.hor_res = 400;
|
||||
s_disp_drv.ver_res = 300;
|
||||
s_disp_drv.draw_buf = &s_disp_buf;
|
||||
s_disp_drv.full_refresh = 1;
|
||||
|
||||
printf("Buffer start: %p\r\n", s_disp_store);
|
||||
|
||||
lv_disp_t *disp = lv_disp_drv_register(&s_disp_drv);
|
||||
if (disp == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
s_lv_semphr_handle = xSemaphoreCreateBinary();
|
||||
if (s_lv_semphr_handle == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
xSemaphoreGive(s_lv_semphr_handle);
|
||||
|
||||
xTaskCreate(impl_lvgl_tick_task, "LV_TICK", 1024, NULL, 5, &s_lv_tick_handle);
|
||||
xTaskCreate(impl_lvgl_timer_task, "LV_TMR", 4096, NULL, 4, &s_lv_task_handle);
|
||||
|
||||
// TODO: Launch LVGL tasks below.
|
||||
|
||||
return ESP_OK;
|
||||
}
|
12
main/impl/impl_lvgl.h
Normal file
12
main/impl/impl_lvgl.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef IMPL_LVGL_H
|
||||
#define IMPL_LVGL_H
|
||||
|
||||
#include "esp_system.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
esp_err_t impl_lvgl_lock(void);
|
||||
esp_err_t impl_lvgl_unlock(void);
|
||||
esp_err_t impl_lvgl_init(void);
|
||||
|
||||
#endif
|
1
main/lib/epd-spi
Submodule
1
main/lib/epd-spi
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit e08d953fcb0f8483f72c7b232494d421c22f2447
|
55
main/main.c
Normal file
55
main/main.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "sdkconfig.h"
|
||||
//
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
//
|
||||
#include "impl_lvgl.h"
|
||||
|
||||
static esp_err_t app_init_nvs(void) {
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t app_init_gpio(void) { return gpio_install_isr_service(0); }
|
||||
|
||||
esp_err_t impl_lvgl_init(void);
|
||||
|
||||
void app_main(void) {
|
||||
ESP_ERROR_CHECK(app_init_nvs());
|
||||
ESP_ERROR_CHECK(app_init_gpio());
|
||||
|
||||
ESP_ERROR_CHECK(impl_lvgl_init());
|
||||
|
||||
/*Create a style for the shadow*/
|
||||
impl_lvgl_lock();
|
||||
lv_obj_t *test_label = lv_label_create(lv_scr_act());
|
||||
lv_label_set_recolor(test_label, true);
|
||||
lv_label_set_text(test_label, "#000000 Test Label with# #808080 ReColor #");
|
||||
lv_obj_set_width(test_label, 400);
|
||||
lv_obj_set_style_text_align(test_label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
lv_obj_align(test_label, LV_ALIGN_CENTER, 0, -25);
|
||||
impl_lvgl_unlock();
|
||||
|
||||
char text_buf[32];
|
||||
|
||||
/* Dead loop */
|
||||
for (;;) {
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
snprintf(text_buf, 32, "C=%d", xTaskGetTickCount());
|
||||
impl_lvgl_lock();
|
||||
lv_label_set_text(test_label, text_buf);
|
||||
lv_obj_set_style_text_align(test_label, LV_TEXT_ALIGN_CENTER, 0);
|
||||
impl_lvgl_unlock();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user