Skip to content

Commit

Permalink
port updated display/lcd stuff from smalltv-pro-esp-idf
Browse files Browse the repository at this point in the history
  • Loading branch information
jo-m committed May 20, 2024
1 parent 3b97598 commit dad647d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 43 deletions.
35 changes: 11 additions & 24 deletions components/display/display.c
Original file line number Diff line number Diff line change
@@ -1,40 +1,34 @@
#include "display.h"

#include <assert.h>
#include <esp_err.h>
#include <esp_heap_caps.h>
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_ops.h>
#include <esp_log.h>
#include <esp_system.h>
#include <esp_timer.h>

#include "lcd.h"

static const char *TAG = "display";

static void lcd_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t)lv_display_get_user_data(disp);
lcd_t *lcd = (lcd_t *)lv_display_get_user_data(disp);
int x1 = area->x1;
int x2 = area->x2;
int y1 = area->y1;
int y2 = area->y2;
ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(panel_handle, x1, y1, x2 + 1, y2 + 1, px_map));

ESP_LOGD(TAG, "lcd_flush_cb() x1=%d y1=%d x2=%d y2=%d", x1, y1, x2, y2);
lcd_draw_start(lcd, x1, y1, x2, y2, px_map);
}

static uint32_t lcd_lvgl_tick_get_cb() { return esp_timer_get_time() / 1000; }

bool color_trans_done_cb(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata,
void *user_ctx) {
lv_display_t *disp = (lv_display_t *)user_ctx;
lv_display_flush_ready(disp);

return true; // TODO: not sure about this.
static void lcd_wait_cb(lv_display_t *disp) {
lcd_t *lcd = (lcd_t *)lv_display_get_user_data(disp);
lcd_draw_wait_finished(lcd);
}

esp_err_t init_display(esp_lcd_panel_handle_t panel_handle,
esp_lcd_panel_io_handle_t panel_io_handle, lv_display_t **disp_out) {
static uint32_t lcd_lvgl_tick_get_cb() { return esp_timer_get_time() / 1000; }

void init_display(lcd_t *lcd, lv_display_t **disp_out) {
ESP_LOGI(TAG, "Initialize LVGL library");
lv_init();
lv_tick_set_cb(lcd_lvgl_tick_get_cb);
Expand All @@ -52,19 +46,12 @@ esp_err_t init_display(esp_lcd_panel_handle_t panel_handle,

lv_display_t *disp = lv_display_create(SMALLTV_LCD_H_RES, SMALLTV_LCD_V_RES);
assert(disp != NULL);
lv_display_set_user_data(disp, (void *)panel_handle);
lv_display_set_user_data(disp, (void *)lcd);
lv_display_set_flush_wait_cb(disp, lcd_wait_cb);
lv_display_set_flush_cb(disp, lcd_flush_cb);
lv_display_set_buffers(disp, buf0, NULL, buf_sz, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_color_format(disp, SMALLTV_LCD_COLOR_FORMAT);

// Register IO done callback.
const esp_lcd_panel_io_callbacks_t cbs = {
.on_color_trans_done = color_trans_done_cb,
};
esp_lcd_panel_io_register_event_callbacks(panel_io_handle, &cbs, (void *)disp);

assert(disp_out != NULL);
*disp_out = disp;

return ESP_OK;
}
7 changes: 2 additions & 5 deletions components/display/display.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#pragma once

#include <esp_err.h>
#include <esp_lcd_types.h>

#include "lcd.h"
#include "lvgl.h"

esp_err_t init_display(esp_lcd_panel_handle_t panel_handle,
esp_lcd_panel_io_handle_t panel_io_handle, lv_display_t **disp_out);
void init_display(lcd_t *lcd, lv_display_t **disp_out);
54 changes: 45 additions & 9 deletions components/display/lcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
#include <driver/spi_master.h>
#pragma GCC diagnostic pop
#include <driver/ledc.h>
#include <esp_err.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_panel_vendor.h>
#include <esp_log.h>
#include <stdbool.h>
#include <string.h>

static const char *TAG = "lcd";

Expand Down Expand Up @@ -42,7 +44,21 @@ static void setup_backlight_pwm() {
ESP_ERROR_CHECK(ledc_update_duty(BL_LEDC_MODE, BL_LEDC_CHANNEL));
}

esp_err_t init_lcd(lcd_t *lcd_out) {
static bool io_done_cb(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata,
void *user_ctx) {
ESP_LOGD(TAG, "io_done_cb()");

lcd_t *lcd = (lcd_t *)user_ctx;

BaseType_t result = xSemaphoreGive(lcd->drawing);
if (result != pdTRUE) {
ESP_ERROR_CHECK(ESP_ERR_INVALID_STATE);
}

return true; // TODO: not sure about this.
}

void init_lcd(lcd_t *lcd_out) {
setup_backlight_pwm();
lcd_backlight_set_brightness(0);

Expand Down Expand Up @@ -72,7 +88,6 @@ esp_err_t init_lcd(lcd_t *lcd_out) {
};
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)SMALLTV_LCD_SPI_HOST,
&io_config, &panel_io_handle));
assert(panel_io_handle != NULL);

ESP_LOGI(TAG, "Create St7789 LCD panel");
esp_lcd_panel_dev_config_t panel_config = {
Expand All @@ -85,7 +100,6 @@ esp_err_t init_lcd(lcd_t *lcd_out) {
};
esp_lcd_panel_handle_t panel_handle;
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io_handle, &panel_config, &panel_handle));
assert(panel_handle != NULL);

ESP_LOGI(TAG, "Initialize LCD panel");
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
Expand All @@ -97,19 +111,41 @@ esp_err_t init_lcd(lcd_t *lcd_out) {

lcd_backlight_set_brightness(255);

ESP_LOGI(TAG, "Assign outputs");
assert(lcd_out != NULL);
memset(lcd_out, 0, sizeof(*lcd_out));
lcd_out->panel_handle = panel_handle;
lcd_out->panel_io_handle = panel_io_handle;

return ESP_OK;
ESP_LOGI(TAG, "Register IO done callback");
lcd_out->drawing = xSemaphoreCreateBinaryStatic(&lcd_out->drawing_buf);
assert(lcd_out->drawing != NULL);
const esp_lcd_panel_io_callbacks_t cbs = {
.on_color_trans_done = io_done_cb,
};
ESP_ERROR_CHECK(
esp_lcd_panel_io_register_event_callbacks(panel_io_handle, &cbs, (void *)lcd_out));
}

esp_err_t lcd_backlight_set_brightness(uint8_t duty) {
ESP_LOGI(TAG, "Backlight duty cycle: %hhu", duty);
void lcd_draw_start(lcd_t *lcd, int x_start, int y_start, int x_end, int y_end,
const void *color_data) {
ESP_LOGD(TAG, "lcd_draw_start()");
ESP_ERROR_CHECK(esp_lcd_panel_draw_bitmap(lcd->panel_handle, x_start, y_start, x_end + 1,
y_end + 1, color_data));
}

void lcd_draw_wait_finished(lcd_t *lcd) {
ESP_LOGD(TAG, "lcd_draw_wait_finished()");

ledc_set_duty(BL_LEDC_MODE, BL_LEDC_CHANNEL, duty);
ledc_update_duty(BL_LEDC_MODE, BL_LEDC_CHANNEL);
BaseType_t result = xSemaphoreTake(lcd->drawing, portMAX_DELAY);
if (result != pdTRUE) {
ESP_ERROR_CHECK(ESP_ERR_INVALID_STATE);
}
}

return ESP_OK;
void lcd_backlight_set_brightness(uint8_t duty) {
ESP_LOGI(TAG, "lcd_backlight_set_brightness(%hhu)", duty);

ESP_ERROR_CHECK(ledc_set_duty(BL_LEDC_MODE, BL_LEDC_CHANNEL, duty));
ESP_ERROR_CHECK(ledc_update_duty(BL_LEDC_MODE, BL_LEDC_CHANNEL));
}
16 changes: 13 additions & 3 deletions components/display/lcd.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#pragma once

#include <esp_err.h>
#include <esp_lcd_types.h>
#include <stdint.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
#include <freertos/FreeRTOS.h>
#pragma GCC diagnostic pop

#include "lvgl.h"

Expand All @@ -16,10 +19,17 @@
#define SMALLTV_LCD_CMD_BITS 8
#define SMALLTV_LCD_PARAM_BITS 8

// All struct members are private to the implementation.
typedef struct lcd_t {
esp_lcd_panel_handle_t panel_handle;
esp_lcd_panel_io_handle_t panel_io_handle;

SemaphoreHandle_t drawing;
StaticSemaphore_t drawing_buf;
} lcd_t;

esp_err_t init_lcd(lcd_t *lcd_out);
esp_err_t lcd_backlight_set_brightness(uint8_t duty);
void init_lcd(lcd_t *lcd_out);
void lcd_draw_start(lcd_t *lcd, int x_start, int y_start, int x_end, int y_end,
const void *color_data);
void lcd_draw_wait_finished(lcd_t *lcd);
void lcd_backlight_set_brightness(uint8_t duty);
5 changes: 3 additions & 2 deletions main/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <math.h>
#include <nvs_flash.h>
#include <stdio.h>
#include <string.h>

#include "display.h"
#include "dns.h"
Expand Down Expand Up @@ -73,12 +74,12 @@ void app_main(void) {

ESP_LOGI(TAG, "Initialize LCD");
lcd_t lcd = {0};
ESP_ERROR_CHECK(init_lcd(&lcd));
init_lcd(&lcd);
print_free_heap_stack();

ESP_LOGI(TAG, "Initialize display");
lv_display_t *disp = NULL;
ESP_ERROR_CHECK(init_display(lcd.panel_handle, lcd.panel_io_handle, &disp));
init_display(&lcd, &disp);
assert(disp != NULL);
print_free_heap_stack();

Expand Down

0 comments on commit dad647d

Please sign in to comment.