Trying to get st7789 working with mipi using 2.9.1 using a nrf5340dk which has been working with 2.6.1

I'm moving to 2.9.1 and trying to get mipi working with a st7789 display. I have it working with 2.6.1 without mipi, but can't seem to get it working with mipi on a nrf5340dk. It is building and the backlight is working on both. Here is the relevant overlay configuration:

#include <zephyr/dt-bindings/mipi_dbi/mipi_dbi.h>

&pinctrl {

    spi4_default: spi4_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                <NRF_PSEL(SPIM_MOSI, 0, 25)>;
        };
    };

    spi4_sleep: spi4_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                <NRF_PSEL(SPIM_MOSI, 0, 25)>;
            low-power-enable;
        };
    };


};


&spi4 {
	status = "okay";
	cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
};



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

    mipi_dbi {
		compatible = "zephyr,mipi-dbi-spi";
		spi-dev = <&spi4>;
        dc-gpios = < &gpio1 11 GPIO_ACTIVE_HIGH>;
        reset-gpios = < &gpio1 10 GPIO_ACTIVE_LOW>;
		write-only;
		#address-cells = <1>;
		#size-cells = <0>;
        st7789v_st7789v_tl019fqv01: st7789v@0 {
            compatible = "sitronix,st7789v";
            mipi-max-frequency = <20000000>;
            reg = <0>;
            width = <240>;
            height = <280>;
            x-offset = <0>;
            y-offset = <20>;
            vcom = <0x19>;
            gctrl = <0x35>;
            vrhs = <0x12>;
            vdvs = <0x20>;
            mdac = <0x00>;
            gamma = <0x01>;
            colmod = <0x05>;
            lcm = <0x2c>;
            porch-param = [0c 0c 00 33 33];
            cmd2en-param = [5a 69 02 01];
            pwctrl1-param = [a4 a1];
            pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23];
            nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23];
            ram-param = [00 F0];
            rgb-param = [CD 08 14];
            mipi-mode = <MIPI_DBI_MODE_SPI_4WIRE>;
        };
    };
};

The configuration which was working for 2.6.1:

&pinctrl {

    spi4_default: spi4_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                <NRF_PSEL(SPIM_MOSI, 0, 25)>;
        };
    };

    spi4_sleep: spi4_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                <NRF_PSEL(SPIM_MOSI, 0, 25)>;
            low-power-enable;
        };
    };

};


&spi4 {
	compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi4_default>;
	pinctrl-1 = <&spi4_sleep>;
    pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;

    st7789v_st7789v_tl019fqv01: st7789v@0 {
        compatible = "sitronix,st7789v";
        spi-max-frequency = <20000000>;
        reg = <0>;
        cmd-data-gpios = < &gpio1 11 GPIO_ACTIVE_LOW>;
        reset-gpios = < &gpio1 10 GPIO_ACTIVE_LOW>;
        width = <240>;
        height = <280>;
        x-offset = <0>;
        y-offset = <20>;
        vcom = <0x19>;
        gctrl = <0x35>;
        vrhs = <0x12>;
        vdvs = <0x20>;
        mdac = <0x00>;
        gamma = <0x01>;
        colmod = <0x05>;
        lcm = <0x2c>;
        porch-param = [0c 0c 00 33 33];
        cmd2en-param = [5a 69 02 01];
        pwctrl1-param = [a4 a1];
        pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23];
        nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23];
        ram-param = [00 F0];
        rgb-param = [CD 08 14];
	};
};


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

};

The code is very simple, these are the key calls:

#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/logging/log.h>
#include <lvgl.h>
#include <app_version.h>
#include <zephyr/drivers/display.h>
#include <zephyr/pm/device.h>

LOG_MODULE_REGISTER(app, LOG_LEVEL_DBG);

#define BUTTON1_NODE	DT_NODELABEL(button1)



static const struct device *display_dev  = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));

static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET_OR(BUTTON1_NODE, gpios, {0});
static struct gpio_callback button1_cb_data;


/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS   2000


static const struct pwm_dt_spec screen_backlight = PWM_DT_SPEC_GET(DT_ALIAS(screenblk));


bool pwm_on = true;
int pwm_value = 0;

static  lv_obj_t *screen_helloworld;




int display_manager_init(void) 
{
    LOG_DBG("Initializing display manager");

	if (!device_is_ready(display_dev)) {
		LOG_ERR("Device not ready, aborting test");
		return 0;
	}

    display_blanking_off(display_dev);
    

    return 0;
}


static void screen_backlight_pulse(uint8_t percent) {

    LOG_DBG("Backlight pwm set to %d%%", percent);

    int ret;
    uint32_t step = screen_backlight.period / 100;
    uint32_t pulse_width = step * percent;

    if (!device_is_ready(screen_backlight.dev)) {
		LOG_ERR("Screen backlight is not ready");
        return;
    }

    ret = pwm_set_pulse_dt(&screen_backlight, pulse_width);
    if (ret < 0) {
        LOG_ERR("Failed to set pulse width: %i", ret);
        return;
    }
}


//static void button_isr_callback(const struct device *port,struct gpio_callback *cb,uint32_t pins)
void button1_pressed(const struct device *dev, struct gpio_callback *cb,uint32_t pins)
{
	LOG_DBG("Button pressed at %" PRIu32, k_cycle_get_32());
	ARG_UNUSED(dev);
	ARG_UNUSED(cb);
	ARG_UNUSED(pins);

   	LOG_DBG("Button pressed");

	if (pwm_on) {
		pwm_value = !pwm_value;
		LOG_DBG("pwm_value: %d", pwm_value);
		if (pwm_value) {
			screen_backlight_pulse(100);
		} else {
			screen_backlight_pulse(0);
		}
	}

}


int button_manager_init(void) 
{
	LOG_DBG("Initializing button manager");
	int ret;

	if (!gpio_is_ready_dt(&button1)) {
		LOG_ERR("Error: button device %s is not ready",button1.port->name);
		return 0;
	}

	ret = gpio_pin_configure_dt(&button1, GPIO_INPUT);
	if (ret != 0) {
		LOG_ERR("Error %d: failed to configure %s pin %d",
			ret, button1.port->name, button1.pin);
		return 0;
	}

	ret = gpio_pin_interrupt_configure_dt(&button1,GPIO_INT_EDGE_TO_ACTIVE);
	if (ret != 0) {
		LOG_ERR("Error %d: failed to configure interrupt on %s pin %d",
			ret, button1.port->name, button1.pin);
		return 0;
	}

	gpio_init_callback(&button1_cb_data, button1_pressed, BIT(button1.pin));
	gpio_add_callback(button1.port, &button1_cb_data);
	LOG_DBG("Set up button at %s pin %d", button1.port->name, button1.pin);

	return 0;
}

void screen_helloworld_init()
{
    LOG_DBG("Starting...");

	static lv_obj_t *helloworld_label;

    screen_helloworld = lv_obj_create(NULL);

	LOG_DBG("Setting text and back color");
	lv_obj_set_style_bg_color(screen_helloworld, lv_color_black(), LV_PART_MAIN);
	lv_obj_set_style_text_color(screen_helloworld, lv_color_white(), LV_PART_MAIN);

    LOG_DBG("Creating label");
    helloworld_label = lv_label_create(screen_helloworld);
    lv_label_set_text(helloworld_label, "Hello World");
    lv_obj_align(helloworld_label, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_style_text_font(helloworld_label, &lv_font_montserrat_16, LV_PART_MAIN);

}

void display_test(){

	LOG_DBG("Display test");
	if (!device_is_ready(display_dev)) {
		LOG_ERR("Device not ready, aborting test");
		return;
	}

	display_blanking_off(display_dev);
}

int main(void)
{
	int count = 0;
    LOG_DBG("Display Hello World! %s (%s)", CONFIG_BOARD, APP_VERSION_EXTENDED_STRING);

	button_manager_init();

    if (!device_is_ready(screen_backlight.dev)) {
        LOG_WRN("Screen backlight pwm device is not ready");
        return -ENODEV;
    }

	display_manager_init();

	if (pwm_on) {
		screen_backlight_pulse(100);
	} else {
		screen_backlight_pulse(0);
	}

	screen_helloworld_init();
	LOG_DBG("calling lv_task_handler");
	lv_task_handler();
	LOG_DBG("Starting loop");
	while (1) {
		count++;
		LOG_DBG("count = %d", count);
		lv_task_handler();
		k_msleep(SLEEP_TIME_MS);
		if (count > 1000) {
			count = 0;
		}
	}
}

I've based it off code I've seen in github and. the migration guide. I've also seen this post on the lvgl forum, but it didn't have any additional information. I also read this DevZone post Inquiry on ST7789V MIPI-DBI Driver Configuration in NCS 2.9.0 but it did not give me any clues.

  • Hello,

    There's quite a few changes in between the two overlay configurations, for instance the &spi4 device. Are they your modifications based on some migration notes?

    You're also referring to Zephyr SDK documentation. Are you using nRF Connect SDK (which is based on Zephyr), or are you using vanilla Zephyr?

    There are significant changes in between NCS 2.6.1 and 2.9.0, among them are changes to the build system. The faults you see may be related to the hardware model you're using and/or that you've not migrated to sysbuild. I recommend you to have a look at 

    Kind regards,
    Andreas

  • My changes are based on the migration guide and a number of DevZone posts regarding the matter:

    I am not getting faults. I just cannot see anything on the screen when I was able to in 2.6.1. Now I can't flash 2.6.1, which is a different issue I am trying to solve. If this is a wrapper, it seems like the simple changes to the device tree should not cause an issue.

    I am using nRF Connect in VS Code and am using sysbuild. I have the code building and deploying to a nrf5340dk. There is button and it is working. I see the logs in the RTT viewer.

  • I created one project with two builds for testing. One build is with 2.6.2 toolchain and sdk, the other is with 2.9.1 toolchain and sdk. Both build and flash. After flashing "Hello World" is printed on the screen for 2.6.2 but not for 2.9.1.

    overlay for 2.6.2:

    &pinctrl {
    
        spi4_default: spi4_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 25)>;
            };
        };
    
        spi4_sleep: spi4_sleep {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 25)>;
                low-power-enable;
            };
        };
    
        pwm1_default: pwm1_default {
    		group1 {
    			psels = <NRF_PSEL(PWM_OUT0, 0, 7)>;
    		};
    	};
    
    	pwm1_sleep: pwm1_sleep {
    		group1 {
    			psels = <NRF_PSEL(PWM_OUT0, 0, 7)>;
    			low-power-enable;
    		};
    	};
    };
    
    &pwm1 {
        status = "okay";
        pinctrl-0 = <&pwm1_default>;
        pinctrl-1 = <&pwm1_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &spi4 {
    	compatible = "nordic,nrf-spim";
    	status = "okay";
    	pinctrl-0 = <&spi4_default>;
    	pinctrl-1 = <&spi4_sleep>;
        pinctrl-names = "default", "sleep";
    	cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
    
        st7789v_st7789v_tl019fqv01: st7789v@0 {
            compatible = "sitronix,st7789v";
            spi-max-frequency = <20000000>;
            reg = <0>;
            cmd-data-gpios = < &gpio1 11 GPIO_ACTIVE_LOW>;
            reset-gpios = < &gpio1 10 GPIO_ACTIVE_LOW>;
            width = <240>;
            height = <280>;
            x-offset = <0>;
            y-offset = <20>;
            vcom = <0x19>;
            gctrl = <0x35>;
            vrhs = <0x12>;
            vdvs = <0x20>;
            mdac = <0x00>;
            gamma = <0x01>;
            colmod = <0x05>;
            lcm = <0x2c>;
            porch-param = [0c 0c 00 33 33];
            cmd2en-param = [5a 69 02 01];
            pwctrl1-param = [a4 a1];
            pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23];
            nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23];
            ram-param = [00 F0];
            rgb-param = [CD 08 14];
    	};
    
        
    };
    
    
    / {
        chosen {
            zephyr,display = &st7789v_st7789v_tl019fqv01;
        };
    
    
        aliases {
            screenblk = &display_blk;
        };
    
    	pwmleds {
    		compatible = "pwm-leds";
    	
    		display_blk: pwm_led_0 {
    			pwms = <&pwm1 0 PWM_USEC(15) PWM_POLARITY_NORMAL>;
                label = "Display Backlight";
    		};
    
    	};
    
        buttons {
    		compatible = "gpio-keys";
    		button1: button_1 {
    			gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    			label = "Push button 2";
    			zephyr,code = <INPUT_KEY_1>;
    		};
    	};
    
    };
    

    overlay for 2.9.1:

    /* Include the MIPI DBI definitions */
    #include <zephyr/dt-bindings/mipi_dbi/mipi_dbi.h>
    
    &pinctrl {
    
        spi4_default: spi4_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 25)>;
            };
        };
    
        spi4_sleep: spi4_sleep {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 6)>,
                    <NRF_PSEL(SPIM_MOSI, 0, 25)>;
                low-power-enable;
            };
        };
    
        pwm1_default: pwm1_default {
    		group1 {
    			psels = <NRF_PSEL(PWM_OUT0, 0, 7)>;
    		};
    	};
    
    	pwm1_sleep: pwm1_sleep {
    		group1 {
    			psels = <NRF_PSEL(PWM_OUT0, 0, 7)>;
    			low-power-enable;
    		};
    	};
    };
    
    &pwm1 {
        status = "okay";
        pinctrl-0 = <&pwm1_default>;
        pinctrl-1 = <&pwm1_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &spi4 {
    	status = "okay";
    	pinctrl-0 = <&spi4_default>;
    	pinctrl-1 = <&spi4_sleep>;
    	cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
    
    };
    
    / {
        chosen {
            zephyr,display = &st7789v_st7789v_tl019fqv01;
        };
    
        aliases {
            screenblk = &display_blk;
        };
    
    	pwmleds {
    		compatible = "pwm-leds";
    	
    		display_blk: pwm_led_0 {
    			pwms = <&pwm1 0 PWM_USEC(15) PWM_POLARITY_NORMAL>;
                label = "Display Backlight";
    		};
    
    	};
    
        mipi_dbi {
    		compatible = "zephyr,mipi-dbi-spi";
            reset-gpios = < &gpio1 10 GPIO_ACTIVE_LOW>;
            dc-gpios = < &gpio1 11 GPIO_ACTIVE_HIGH>;
    		spi-dev = <&spi4>;
    		#address-cells = <1>;
    		#size-cells = <0>;
    		write-only;
            st7789v_st7789v_tl019fqv01: st7789v@0 {
                compatible = "sitronix,st7789v";
                reg = <0>;
                mipi-max-frequency = <20000000>;
                mipi-mode = <MIPI_DBI_MODE_SPI_4WIRE>;
                status = "okay";
                width = <240>;
                height = <280>;
                x-offset = <0>;
                y-offset = <20>;
                vcom = <0x19>;
                gctrl = <0x35>;
                vrhs = <0x12>;
                vdvs = <0x20>;
                mdac = <0x00>;
                gamma = <0x01>;
                colmod = <0x05>;
                lcm = <0x2c>;
                porch-param = [0c 0c 00 33 33];
                cmd2en-param = [5a 69 02 01];
                pwctrl1-param = [a4 a1];
                pvgam-param = [D0 04 0D 11 13 2B 3F 54 4C 18 0D 0B 1F 23];
                nvgam-param = [D0 04 0C 11 13 2C 3F 44 51 2F 1F 1F 20 23];
                ram-param = [00 F0];
                rgb-param = [CD 08 14];
                //mipi-mode = <0x2>;
            };
        };
    
    
        buttons {
    		compatible = "gpio-keys";
    		button1: button_1 {
    			gpios = <&gpio0 24 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    			label = "Push button 2";
    			zephyr,code = <INPUT_KEY_1>;
    		};
    	};
    
    };

    prj.conf is:

    CONFIG_GPIO=y
    CONFIG_LOG=y
    CONFIG_PINCTRL=y
    CONFIG_PWM=y
    CONFIG_SPI=y
    CONFIG_SHELL=y
    
    
    CONFIG_MAIN_STACK_SIZE=2048
    
    #Segger RTT Settings
    CONFIG_LOG_MODE_IMMEDIATE=n
    CONFIG_USE_SEGGER_RTT=y
    CONFIG_RTT_CONSOLE=y
    CONFIG_LOG_BACKEND_RTT=y
    CONFIG_UART_CONSOLE=n
    CONFIG_LOG_INFO_COLOR_GREEN=y
    CONFIG_DEBUG_OPTIMIZATIONS=y
    CONFIG_LOG_BACKEND_RTT_MODE_BLOCK=y
    CONFIG_LOG_BUFFER_SIZE=4096
    CONFIG_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE=128
    CONFIG_LOG_BLOCK_IN_THREAD=y
    
    
    CONFIG_CONSOLE=y
    CONFIG_LOG_BACKEND_UART=n
    
    #display
    CONFIG_DISPLAY=y
    CONFIG_DISPLAY_LOG_LEVEL_DBG=y
    
    
    # lvgl configuraiton
    CONFIG_LVGL=y
    CONFIG_LV_Z_MEM_POOL_SIZE=16384
    CONFIG_LV_Z_SHELL=y
    CONFIG_LV_MEM_CUSTOM=y
    CONFIG_LV_USE_LOG=y
    CONFIG_LV_USE_LABEL=y
    CONFIG_LV_USE_BTN=y
    CONFIG_LV_USE_ARC=y
    CONFIG_LV_USE_IMG=y
    CONFIG_LV_USE_MONKEY=y
    CONFIG_LV_FONT_MONTSERRAT_16=y
    CONFIG_LV_FONT_MONTSERRAT_18=y
    CONFIG_LV_FONT_MONTSERRAT_24=y
    CONFIG_LV_FONT_MONTSERRAT_48=y
    #CONFIG_LV_Z_USE_FILESYSTEM=y
    CONFIG_LV_IMG_CACHE_DEF_SIZE=10
    CONFIG_LV_USE_QRCODE=y
    
    
    # added for color display
    CONFIG_LV_COLOR_16_SWAP=y
    CONFIG_LV_COLOR_DEPTH_16=y

    main.c is:

    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/pwm.h>
    #include <zephyr/logging/log.h>
    #include <lvgl.h>
    #include <app_version.h>
    #include <zephyr/drivers/display.h>
    #include <zephyr/pm/device.h>
    
    LOG_MODULE_REGISTER(app, LOG_LEVEL_DBG);
    
    #define BUTTON1_NODE	DT_NODELABEL(button1)
    
    
    
    static const struct device *display_dev  = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
    
    static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET_OR(BUTTON1_NODE, gpios, {0});
    static struct gpio_callback button1_cb_data;
    
    
    /* 1000 msec = 1 sec */
    #define SLEEP_TIME_MS   2000
    
    
    static const struct pwm_dt_spec screen_backlight = PWM_DT_SPEC_GET(DT_ALIAS(screenblk));
    
    
    bool pwm_on = true;
    
    static  lv_obj_t *screen_helloworld;
    
    
    
    
    int display_manager_init(void) 
    {
        LOG_DBG("Initializing display manager");
    
    	if (!device_is_ready(display_dev)) {
    		LOG_ERR("Device not ready, aborting test");
    		return 0;
    	}
    
    	//LOG_DBG("Display name: %d", display_dev->name);
    	//LOG_DBG("Display driver name: %d", display_dev->driver_api->name);
    	//LOG_DBG("Display driver version: %d", display_dev->driver_api->version);
    
        display_blanking_off(display_dev);
        
    
        return 0;
    }
    
    
    static void screen_backlight_pulse(uint8_t percent) {
    
        LOG_DBG("Backlight pwm set to %d%%", percent);
    
        int ret;
        uint32_t step = screen_backlight.period / 100;
        uint32_t pulse_width = step * percent;
    
        if (!device_is_ready(screen_backlight.dev)) {
    		LOG_ERR("Screen backlight is not ready");
            return;
        }
    
        ret = pwm_set_pulse_dt(&screen_backlight, pulse_width);
        if (ret < 0) {
            LOG_ERR("Failed to set pulse width: %i", ret);
            return;
        }
    }
    
    
    //static void button_isr_callback(const struct device *port,struct gpio_callback *cb,uint32_t pins)
    void button1_pressed(const struct device *dev, struct gpio_callback *cb,uint32_t pins)
    {
    	LOG_DBG("Button pressed at %" PRIu32, k_cycle_get_32());
    	ARG_UNUSED(dev);
    	ARG_UNUSED(cb);
    	ARG_UNUSED(pins);
    
       	LOG_DBG("Button pressed");
    
    	pwm_on = !pwm_on;
    	if (pwm_on) {
    		screen_backlight_pulse(100);
    	} else {
    		screen_backlight_pulse(0);
    	}
    
    }
    
    
    int button_manager_init(void) 
    {
    	LOG_DBG("Initializing button manager");
    	int ret;
    
    	if (!gpio_is_ready_dt(&button1)) {
    		LOG_ERR("Error: button device %s is not ready",button1.port->name);
    		return 0;
    	}
    
    	ret = gpio_pin_configure_dt(&button1, GPIO_INPUT);
    	if (ret != 0) {
    		LOG_ERR("Error %d: failed to configure %s pin %d",
    			ret, button1.port->name, button1.pin);
    		return 0;
    	}
    
    	ret = gpio_pin_interrupt_configure_dt(&button1,GPIO_INT_EDGE_TO_ACTIVE);
    	if (ret != 0) {
    		LOG_ERR("Error %d: failed to configure interrupt on %s pin %d",
    			ret, button1.port->name, button1.pin);
    		return 0;
    	}
    
    	gpio_init_callback(&button1_cb_data, button1_pressed, BIT(button1.pin));
    	gpio_add_callback(button1.port, &button1_cb_data);
    	LOG_DBG("Set up button at %s pin %d", button1.port->name, button1.pin);
    
    	return 0;
    }
    
    void screen_helloworld_init()
    {
        LOG_DBG("Starting...");
        screen_helloworld = lv_obj_create(NULL);
    	lv_scr_load_anim(screen_helloworld, LV_SCR_LOAD_ANIM_NONE, 0, 0, true);
    
    	static lv_obj_t *helloworld_label;
    
    
    	LOG_DBG("Setting text and back color");
    	lv_obj_set_style_bg_color(screen_helloworld, lv_color_black(), LV_PART_MAIN);
    	lv_obj_set_style_text_color(screen_helloworld, lv_color_white(), LV_PART_MAIN);
    
        LOG_DBG("Creating label");
        helloworld_label = lv_label_create(screen_helloworld);
        lv_label_set_text(helloworld_label, "Hello World");
        lv_obj_align(helloworld_label, LV_ALIGN_CENTER, 0, 0);
        lv_obj_set_style_text_font(helloworld_label, &lv_font_montserrat_16, LV_PART_MAIN);
    
    }
    
    void display_test(){
    
    	LOG_DBG("Display test");
    	if (!device_is_ready(display_dev)) {
    		LOG_ERR("Device not ready, aborting test");
    		return;
    	}
    
    	display_blanking_off(display_dev);
    }
    
    int main(void)
    {
    	int count = 0;
        LOG_DBG("Display Hello World! %s (%s)", CONFIG_BOARD, APP_VERSION_EXTENDED_STRING);
    
    	button_manager_init();
    
        if (!device_is_ready(screen_backlight.dev)) {
            LOG_WRN("Screen backlight pwm device is not ready");
            return -ENODEV;
        }
    
    	display_manager_init();
    
    	if (pwm_on) {
    		screen_backlight_pulse(100);
    	} else {
    		screen_backlight_pulse(0);
    	}
    
    	screen_helloworld_init();
    	LOG_DBG("calling lv_task_handler");
    	lv_task_handler();
    	LOG_DBG("Starting loop");
    	while (1) {
    		count++;
    		LOG_DBG("count = %d", count);
    		lv_task_handler();
    		k_msleep(SLEEP_TIME_MS);
    		if (count > 1000) {
    			count = 0;
    		}
    	}
    }
    

Related