Zephyr ILI9341 Display Driver Compilation Errors - Missing Devicetree Properties

I'm trying to use an ILI9341 display with nRF52840 in Zephyr (v4.1.99). The build fails with multiple errors about missing Devicetree properties when compiling display_ili9xxx.c:

error: 'DT_N_S_soc_S_spi_40003000_S_ili9341_0_P_gamset_LEN' undeclared
error: 'DT_N_S_soc_S_spi_40003000_S_ili9341_0_P_ifctl' undeclared
error: 'DT_N_S_soc_S_spi_40003000_S_ili9341_0_P_etmod' undeclared
[20+ similar property errors...]

This is my overlay file:

&spi1 {
    status = "okay";
    cs-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;

    ili9341: ili9341@0 {
        compatible = "ilitek,ili9341";
        reg = <0>;
        spi-max-frequency = <8000000>;
        
        // Add these required properties:
        spi-cpol;
        spi-cpha;
        
        dc-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
        reset-gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
        backlight-gpios = <&gpio0 16 GPIO_ACTIVE_HIGH>;

        // Add display inversion mode (try true or false)
        display-inversion;
        // or display-inversion = <1>; 
        // or display-inversion = <0>; if the first doesn't work

        width = <240>;
        height = <320>;
        rotation = <0>;
        
        // These might help if you still have issues:
        pixel-format = "rgb565";
        // cmd-data-gpios = <&gpio0 14 GPIO_ACTIVE_LOW>; // Alternative to dc-gpios
    };
};

I tried fixing the issue by modifying the prj.conf file, but it's still not working. Here's my current prj.conf:

CONFIG_SPI=y
CONFIG_GPIO=y
CONFIG_DISPLAY=y
CONFIG_DISPLAY_INIT_PRIORITY=90
CONFIG_ILI9341=y

This is part from zephyr.dts which include spi1:

spi1: spi@40004000 {
			compatible = "nordic,nrf-spi";
			#address-cells = < 0x1 >;
			#size-cells = < 0x0 >;
			reg = < 0x40004000 0x1000 >;
			interrupts = < 0x4 0x1 >;
			max-frequency = < 0x7a1200 >;
			easydma-maxcnt-bits = < 0x10 >;
			status = "okay";
			pinctrl-0 = < &spi1_default >;
			pinctrl-1 = < &spi1_sleep >;
			pinctrl-names = "default", "sleep";
			cs-gpios = < &gpio0 0xf 0x1 >;
			ili9341: ili9341@0 {
				compatible = "ilitek,ili9341";
				reg = < 0x0 >;
				spi-max-frequency = < 0x7a1200 >;
				spi-cpol;
				spi-cpha;
				dc-gpios = < &gpio0 0xe 0x1 >;
				reset-gpios = < &gpio0 0xd 0x1 >;
				backlight-gpios = < &gpio0 0x10 0x0 >;
				display-inversion;
				width = < 0xf0 >;
				height = < 0x140 >;
				rotation = < 0x0 >;
				pixel-format = "rgb565";
			};
		};

Parents
  • Hi,

     

    It looks like you are setting up a legacy way of declaring a display node. Please see here for the new mipi-dpi setup:

    https://docs.nordicsemi.com/bundle/ncs-2.9.1/page/zephyr/releases/migration-guide-3.7.html#display

     

    Please see here for an example implementation of your device:

    https://github.com/nrfconnect/sdk-zephyr/blob/v4.0.99-ncs1/boards/st/stm32f429i_disc1/stm32f429i_disc1.dts#L66-L101

     

    PS: you should use the NRF_SPIM hardware module instead of the NRF_SPI module that you are currently pointing towards in your device tree node.

    NRF_SPIM is DMA capable, so will be much faster than the NRF_SPI.

    Change this line:

    compatible = "nordic,nrf-spi";

    To:

    compatible = "nordic,nrf-spim";

     

    Kind regards,

    Håkon

  • Thank you very much. This is my overlay file now. But it is still do not show anything:

    / {
        chosen {
            zephyr,display = &ili9341;
        };
    
        mipi_dbi {
            compatible = "zephyr,mipi-dbi-spi";
            dc-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;      // DC/RS pin
            reset-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;    // RESET pin
            write-only;
            #address-cells = <1>;
            #size-cells = <0>;
            spi-dev = <&spi1>;
    
            pinctrl-0 = <&spi1_default>;
            pinctrl-names = "default";
    
            ili9341: ili9341@0 {
                compatible = "ilitek,ili9341";
                reg = <0>;
                mipi-max-frequency = <4000000>;
                width = <240>;
                height = <320>;
                rotation = <180>;
    
                pwctrla = [39 2c 00 34 02];
                pwctrlb = [00 c1 30];
                timctrla = [85 00 78];
                timctrlb = [00 00];
                pwseqctrl = [64 03 12 81];
                pumpratioctrl = [20];
                disctrl = [08 82 27 04];
                vmctrl1 = [45 15];
                vmctrl2 = [90];
                enable3g = [00];
                ifctl = [01 00 06];
                ifmode = [c2];
                gamset = [01];
                frmctr1 = [00 1b];
                pwctrl1 = [10];
                pwctrl2 = [10];
                pgamctrl = [0F 29 24 0c 0e 09 4e 78 3c 09 13 05 17 11 00];
                ngamctrl = [00 16 1b 04 11 07 31 33 42 05 0c 0a 28 2f 0f];
            };
        };
    };
    
    &spi1 {
        status = "okay";
        cs-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; // CS pin displeja
        pinctrl-0 = <&spi1_default>;
        pinctrl-1 = <&spi1_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &pinctrl {
        spi1_default: spi1_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 31)>,       // SCK
                        <NRF_PSEL(SPIM_MOSI, 0, 30)>;      // MOSI
            };
        };
    
        spi1_sleep: spi1_sleep {
            group1 {
                // Sleep stanje prazno
            };
        };
    };
    

    And this is my simple main.c:

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/display.h>
    #include <lvgl.h>
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main);
    
    void main(void)
    {
        const struct device *display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
    
        if (!device_is_ready(display_dev)) {
            printk("Display not ready\n");
            return;
        }
    
        display_blanking_off(display_dev);
        lv_obj_clean(lv_scr_act()); // Očisti ekran
    
        lv_obj_t *rect = lv_obj_create(lv_scr_act());
        lv_obj_set_size(rect, 240, 320);
        lv_obj_set_style_bg_color(rect, lv_color_hex(0xFF0000), 0);  // Crvena pozadina
        lv_obj_center(rect);
    
        while (1) {
            lv_task_handler();
            k_msleep(10);
        }
    }
    
    

Reply
  • Thank you very much. This is my overlay file now. But it is still do not show anything:

    / {
        chosen {
            zephyr,display = &ili9341;
        };
    
        mipi_dbi {
            compatible = "zephyr,mipi-dbi-spi";
            dc-gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>;      // DC/RS pin
            reset-gpios = <&gpio0 28 GPIO_ACTIVE_LOW>;    // RESET pin
            write-only;
            #address-cells = <1>;
            #size-cells = <0>;
            spi-dev = <&spi1>;
    
            pinctrl-0 = <&spi1_default>;
            pinctrl-names = "default";
    
            ili9341: ili9341@0 {
                compatible = "ilitek,ili9341";
                reg = <0>;
                mipi-max-frequency = <4000000>;
                width = <240>;
                height = <320>;
                rotation = <180>;
    
                pwctrla = [39 2c 00 34 02];
                pwctrlb = [00 c1 30];
                timctrla = [85 00 78];
                timctrlb = [00 00];
                pwseqctrl = [64 03 12 81];
                pumpratioctrl = [20];
                disctrl = [08 82 27 04];
                vmctrl1 = [45 15];
                vmctrl2 = [90];
                enable3g = [00];
                ifctl = [01 00 06];
                ifmode = [c2];
                gamset = [01];
                frmctr1 = [00 1b];
                pwctrl1 = [10];
                pwctrl2 = [10];
                pgamctrl = [0F 29 24 0c 0e 09 4e 78 3c 09 13 05 17 11 00];
                ngamctrl = [00 16 1b 04 11 07 31 33 42 05 0c 0a 28 2f 0f];
            };
        };
    };
    
    &spi1 {
        status = "okay";
        cs-gpios = <&gpio0 29 GPIO_ACTIVE_LOW>; // CS pin displeja
        pinctrl-0 = <&spi1_default>;
        pinctrl-1 = <&spi1_sleep>;
        pinctrl-names = "default", "sleep";
    };
    
    &pinctrl {
        spi1_default: spi1_default {
            group1 {
                psels = <NRF_PSEL(SPIM_SCK, 0, 31)>,       // SCK
                        <NRF_PSEL(SPIM_MOSI, 0, 30)>;      // MOSI
            };
        };
    
        spi1_sleep: spi1_sleep {
            group1 {
                // Sleep stanje prazno
            };
        };
    };
    

    And this is my simple main.c:

    #include <zephyr/kernel.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/display.h>
    #include <lvgl.h>
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main);
    
    void main(void)
    {
        const struct device *display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
    
        if (!device_is_ready(display_dev)) {
            printk("Display not ready\n");
            return;
        }
    
        display_blanking_off(display_dev);
        lv_obj_clean(lv_scr_act()); // Očisti ekran
    
        lv_obj_t *rect = lv_obj_create(lv_scr_act());
        lv_obj_set_size(rect, 240, 320);
        lv_obj_set_style_bg_color(rect, lv_color_hex(0xFF0000), 0);  // Crvena pozadina
        lv_obj_center(rect);
    
        while (1) {
            lv_task_handler();
            k_msleep(10);
        }
    }
    
    

Children
No Data
Related