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. 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;
	}

	//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");

	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;
		}
	}
}

Related