Skip to main content

lvgl-widgets-demo

:::warning [UNTESTED] on real hardware native_sim proves the alp_display_open() / alp_gui_lvgl_attach() path builds, runs, and flushes real frames (alp_display_blit() is reached from LVGL's render loop). The underlying MIPI DBI Type C devicetree path on the E1M-EVK still has build-only CI coverage, and this app's target board (ensemble_e8_dk) has no alp-display0 alias checked in yet — real-hardware bring-up lands with the v1.0 HiL sweep. :::

Wraps the upstream lv_demo_widgets() — LVGL's headline showcase of every standard widget (buttons, sliders, tabs, charts, meters, lists, animations).

Source: examples/display/lvgl-widgets-demo/.

What it shows

  • The app opens the panel through the portable <alp/display.h> surface and binds LVGL to it with <alp/gui.h> — no direct Zephyr display_* calls.
  • The SDK's st7789 chip driver handles the panel-specific init.
  • Customer code stays board-portable — no vendor-specific symbols, only <alp/*> peripheral surfaces + the portable LVGL API.

Display bring-up

This is the reference init sequence for every Zephyr LVGL example in the SDK. The app owns the ordering:

alp_display_config_t display_cfg = ALP_DISPLAY_CONFIG_DEFAULT(0);
alp_display_t *display = alp_display_open(&display_cfg);
if (display == NULL) {
LOG_ERR("display open failed (err=%d)", (int)alp_last_error());
return 1;
}

lv_init();
lv_tick_set_cb(k_uptime_get_32);

alp_status_t attach_status = alp_gui_lvgl_attach(display);
if (attach_status != ALP_OK) { /* ... */ }

lv_demo_widgets();

Then the usual pump: lv_timer_handler() followed by a bounded k_msleep().

Required Kconfig

KnobWhereWhy
CONFIG_LV_Z_AUTO_INIT=nprj.confLVGL must not auto-create its own lv_display_t — the app owns the panel via alp_display_open(). Without this you get a second, unbound display.
CONFIG_DISPLAY=yprj.confEnables the display driver class.
CONFIG_DUMMY_DISPLAY=ynative_sim.confHost runs render into a dummy device…
CONFIG_SDL_DISPLAY=nnative_sim.conf…rather than opening an SDL2 window.

The alp-display0 alias

alp_display_open() resolves its panel from an alp-display0 devicetree alias. The native_sim overlay provides one:

/ {
chosen {
zephyr,display = &dummy_dc;
};

aliases {
alp-display0 = &dummy_dc;
};

dummy_dc: dummy_dc {
compatible = "zephyr,dummy-dc";
height = <320>;
width = <240>;
};
};

The other Zephyr LVGL examples reuse this same overlay shape.

Hardware needed

  • An E1M-AEN-family SoM (E8 is the reference target — SRAM headroom for LVGL).
  • E1M-EVK board (or any board exposing SPI + two GPIOs).
  • 240×320 ST7789 TFT panel wired to SPI + reset/DC GPIOs.

board.yaml

libraries:
- name: lvgl
cores: [m55_hp]

som:
sku: E1M-AEN801

preset: e1m-evk

pins:
- { e1m: E1M_SPI1, macro: EVK_SPI_BUS_ARDUINO, doc: "Arduino UNO header SPI" }

cores:
a32_cluster:
os: "off"
m55_hp:
app: ./src
peripherals:
- spi
- gpio

chips:
- st7789

diagnostics:
log_level: info

See also

Questions about this page? Discuss in Community Forum