Error in calling lv_tick_inc function from LVGL in NCS2.5.0

Hi, Nordic Team and Community!

I'm trying to develop a display that shows information dynamically. Each information will shown in the display for about 2 seconds and then move to another, as in pages, each page showing a different information.

But to make this happen I need to use the lv_tick_inc to track time in the code, according to LGVL library docs. But when I call this function, and only this function the compiler shows an "undefined reference to this function", but I don't know why, as IntelliSense C/C++ can open its definition of this function in the correct path.

Looking into the library code, enabling a Kconfig like LV_TICK_CUSTOM appears necessary as I'm doing. But the problem remains.

The display I'm using is a SSD1306 128x64p, there is a reason to create this. And when I build to show only one page it does normally. So the problem isn't the library itself. I guess I'm missing some configuration but I don't know where to look it anymore.

My dev setup: NCS v2.5.0 for vscode.

macOS 14.3.1

Here is my code and my prj.conf to this part of the display for my project.

Any help on this I'm grateful!

Best Regards.

#include "display.h" //calling also lvgl.h
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/display.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(display, LOG_LEVEL_DBG);


#include "common.h"

#define NUMBER_OF_PAGES 4

/* Fecth display device from Devicetree */
const struct device *display_dev;

/* Setup timer for page switching */
static void lv_tick_handler(struct k_timer *timer_id);
static void update_display_page(lv_timer_t *timer);

K_TIMER_DEFINE(lvgl_tick, lv_tick_handler, NULL);

static void lv_tick_handler(struct k_timer *timer_id)
{
    lv_tick_inc(K_MSEC(2)); //Call this every 2 milliseconds.
}

static void update_display_page(lv_timer_t *timer)
{
    static uint8_t current_page = 0;
    current_page = (current_page + 1) % NUMBER_OF_PAGES;
    lv_obj_clean(lv_scr_act()); // Clean the current screen.

    switch (current_page)
    {
    case 0:
        display_channel_levels();
        break;
    case 1:
        display_lte_status();
        break;
    case 2:
        display_mqtt_status();
        break;
    case 3:
        display_soil_temperature();
        break;
    default:

        break;
    }

    lv_task_handler(); // Tell LVGL that tick happened.
}

/* Display init function  */
void display_init(void)
{
    display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
    if (!device_is_ready(display_dev)) {
        LOG_ERR("Device not ready, aborting test");
        return;
    }

    // Initialize LVGL library
    lv_init();

    // Start the LVGL timer
    lv_timer_create(update_display_page, 2000, NULL);

    // Start the Zeohyr timer for LVGL tick increment
    k_timer_start(&lvgl_tick, K_MSEC(2), K_MSEC(2));

    // lv_obj_t *label = lv_label_create(lv_scr_act());
    // lv_label_set_text(label, "TLAMP");
    // lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0);

    // Update the display
    //lv_task_handler();
    return;
}


/* Page Functions */

void display_lte_status(void)
{
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, true ? "LTE: Connected" : "LTE: Disconnected");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

void display_channel_levels(void)
{
    // Example for one channel, repeat for others
    lv_obj_t *label = lv_label_create(lv_scr_act());
    char text[64];
    sprintf(text, "CH1: %d%%", 10);
    lv_label_set_text(label, text);
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
    // Position other labels accordingly
}

void display_soil_temperature(void) 
{
    lv_obj_t *label = lv_label_create(lv_scr_act());
    char text[64];
    snprintf(text, sizeof(text),"Soil Temp: %.2f°C", 20.00);
    lv_label_set_text(label, text);
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

void display_mqtt_status(void) 
{
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, true ? "MQTT: Connected" : "MQTT: Disconnected");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

the prj.conf

# Display Options
CONFIG_I2C=y
CONFIG_DISPLAY=y
CONFIG_SSD1306=y
CONFIG_SSD1306_SH1106_COMPATIBLE=y
CONFIG_SSD1306_DEFAULT=y
CONFIG_SSD1306_REVERSE_MODE=y


#lvgl
CONFIG_LVGL=y
CONFIG_LV_MEM_CUSTOM=y
CONFIG_LV_USE_LABEL=y
CONFIG_LV_USE_CANVAS=y
CONFIG_LV_USE_LOG=y
CONFIG_LV_TICK_CUSTOM=y


CONFIG_LV_DPI_DEF=148
CONFIG_LV_Z_BITS_PER_PIXEL=1
CONFIG_LV_COLOR_DEPTH_1=y
#CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12=y
CONFIG_LV_FONT_MONTSERRAT_8=y
CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8

Related