Kode Dot

Display

The screen on a Kode Dot: an AMOLED with touch over MIPI-DSI, what brings it up, what LVGL needs from you, and the code to draw on it.

What it is

The front of the Kode Dot is a 2.06-inch AMOLED, 410 pixels wide and 502 tall, with a capacitive touch layer over it. AMOLED means every pixel makes its own light: black costs nothing, white costs the most, and brightness is the biggest lever you have on battery life.

You draw on it with LVGL, version 9: you create labels, buttons and images, and LVGL renders them into a buffer that the panel driver pushes to the screen. kode_bsp_init does the bring-up, powers the panel, resets it, sends the manufacturer's init sequence, starts LVGL and finds whichever touch controller the board carries, so your code starts at "create a label".

How it is connected

flowchart LR
p4["ESP32-P4"] -- "MIPI-DSI, 1 lane" --> panel["CO5300 AMOLED"]
p4 -- "GPIO7 reset" --> panel
exp["TCA6408 P7"] -. "panel power" .-> panel
p4 -- "I2C, 0x15 or 0x5A" --> touch["CST820 or CST916E"]
Pixels over MIPI-DSI; power and reset through the expander and a pin; touch on the I2C bus

The panel's controller is a Chipone CO5300 on a single MIPI-DSI lane. Its power enable is bit P7 of the TCA6408 expander, not a P4 pin, and its reset is GPIO7, shared with the touch controller. Touch is on the shared I2C bus at 0x15 or 0x5A depending on which supplier made the panel; its interrupt is bit P6 of the same expander, so touch is polled.

Specifications

ThingValue
Panel2.06-inch AMOLED, Chipone CO5300, 410 by 502, portrait, RGB565
BusMIPI-DSI, one data lane. The DPHY runs from the P4's internal LDO channel 3 at 2.5 V
PowerExpander P7, active high. Off at boot
ResetGPIO7, active low, shared by panel and touch
TouchCST820 at 0x15 or CST916E at 0x5A, found at start-up. Interrupt on expander P6, polled
UILVGL 9. kode_bsp_display() returns the display; take kode_bsp_lvgl_lock() around UI calls from your own task
One frameAbout 400 KB at two bytes per pixel, in PSRAM
CostAbout 76 mA white at full brightness, about 3 mA at 25 %
ValidatedKode-Dot-Val/03-DISPLAY: panel, touch and LVGL on both panel suppliers

Gotchas

Apps that use it

On the marketplace, apps that put this part to work. Install one from start/first-app and see it before you write a line.

Example code

Put a line of text in the middle of the screen and move it to wherever you touch. You see the text, and it follows your finger.

/*
 * display_touch.c - 2026-09-18 - from Kode with love
 *
 * Draws a label in the middle of the Kode Dot's screen and moves it to the
 * last point touched. Brings the board up, which starts LVGL and the touch
 * controller, then creates the label and a timer that reads the touch state
 * thirty times a second. The text follows your finger.
 */
#include "kode.h"
 
static lv_obj_t *s_label;
 
/* Runs inside the LVGL task: read the one input device and move the label to it. */
static void follow_touch(lv_timer_t *timer)
{
    (void)timer;
    lv_indev_t *touch = lv_indev_get_next(NULL);
    if (!touch || lv_indev_get_state(touch) != LV_INDEV_STATE_PRESSED) return;
    lv_point_t p;
    lv_indev_get_point(touch, &p);
    lv_obj_set_pos(s_label, p.x - lv_obj_get_width(s_label) / 2, p.y - 12);
}
 
/* Board and LVGL, then the label and its timer, under the LVGL lock. */
void app_main(void)
{
    ESP_ERROR_CHECK(kode_bsp_init());
 
    kode_bsp_lvgl_lock();
    s_label = lv_label_create(lv_display_get_screen_active(kode_bsp_display()));
    lv_label_set_text(s_label, "Hello, Kode Dot");
    lv_obj_set_style_text_font(s_label, &lv_font_montserrat_16, 0);
    lv_obj_center(s_label);
    lv_timer_create(follow_touch, 33, NULL);
    kode_bsp_lvgl_unlock();
}

Compiled on the date in the header against the kode component with ESP-IDF v6.1. TBD: a run on a V1 board.

In the SDK