Zephyr + nRF5240 DK + lvgl + SSD1306

Hi,

I am developing an application with the lvgl driver. I was trying to make the example lvgl works, but I can not. I am using a 128 x 32 screen with a ssd1306 controller (in the description of the example says it is compatible). When I connect the screen to the board and flash the code nothing happens (the screen does not turn on). I dont know what part of the configuration I have to change depending on the screen type. I connect the screen to 5V and GND of the DK and the I2C to 31 and 30 pins. I did not change noting in the code. Doing debug of the code I have seen that the the functions below the "device_get_binding" does not execute. 

¿Do you know if I am missing something important about the configuration?. I think the problem is the configuration of the display in the kconfig or the configuration in the I2C bus. ¿Am I in the way?. I can not see where it is exactly.

#include <device.h>
#include <drivers/display.h>
#include <lvgl.h>
#include <stdio.h>
#include <string.h>
#include <zephyr.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(app);

void main(void)
{
	uint32_t count = 0U;
	char count_str[11] = {0};
	const struct device *display_dev;
	lv_obj_t *hello_world_label;
	lv_obj_t *count_label;

	display_dev = device_get_binding(CONFIG_LVGL_DISPLAY_DEV_NAME);

	if (display_dev == NULL) {
		return;
	}

	if (IS_ENABLED(CONFIG_LVGL_POINTER_KSCAN)) {
		lv_obj_t *hello_world_button;

		hello_world_button = lv_btn_create(lv_scr_act(), NULL);
		lv_obj_align(hello_world_button, NULL, LV_ALIGN_CENTER, 0, 0);
		lv_btn_set_fit(hello_world_button, LV_FIT_TIGHT);
		hello_world_label = lv_label_create(hello_world_button, NULL);
	} else {
		hello_world_label = lv_label_create(lv_scr_act(), NULL);
	}

	lv_label_set_text(hello_world_label, "Hello world!");
	lv_obj_align(hello_world_label, NULL, LV_ALIGN_CENTER, 0, 0);

	count_label = lv_label_create(lv_scr_act(), NULL);
	lv_obj_align(count_label, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);

	lv_task_handler();
	display_blanking_off(display_dev);

	while (1) {
		if ((count % 100) == 0U) {
			sprintf(count_str, "%d", count/100U);
			lv_label_set_text(count_label, count_str);
		}
		lv_task_handler();
		k_sleep(K_MSEC(10));
		++count;
	}
}

I have added the shield in CMakeList

# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(lvgl)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
set(ssd1306_128x32)

Thanks for your time 

Parents Reply
  • Hi Simon. Thanks for the time you have spent answering me. The lvgl guide from Zephyr says that you have to use the Shield of ssd1306 (called "ssd1306_128x32" in my case) from the SDK. This shield includes a kconfig.defconfig file which put the display name as "SSD1306" and execute "config SSD1306". The shield also has an overlay file creating a node with the requirements and the links you have commented. I have set the shield in the CMakeList.txt as follows:

    cmake_minimum_required(VERSION 3.20.0)
    
    find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
    project(lvgl)
    
    FILE(GLOB app_sources src/*.c)
    target_sources(app PRIVATE ${app_sources})
    set(SHIELD ssd1306_128x32)

    The shield contents the following files

    • The kconfig.defconfig form the shield file set:

    if SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64
    
    config I2C
    	default y
    
    endif # SHIELD_SSD1306_128X64 || SHIELD_SSD1306_128X32 || SHIELD_SH1106_128X64
    
    config SSD1306
    	default y
    
    choice SSD1306_CONTROLLER_TYPE
    	default SSD1306_SH1106_COMPATIBLE if SHIELD_SH1106_128X64
    endchoice
    
    if LVGL
    
    config LVGL_DISPLAY_DEV_NAME
    	default "SSD1306"
    

    • The overlay file from the shield:

    &arduino_i2c {
    	status = "okay";
    
    	ssd1306@3c {
    		compatible = "solomon,ssd1306fb";
    		reg = <0x3c>;
    		label = "SSD1306";
    		width = <128>;
    		height = <32>;
    		segment-offset = <0>;
    		page-offset = <0>;
    		display-offset = <0>;
    		multiplex-ratio = <31>;
    		segment-remap;
    		com-invdir;
    		com-sequential;
    		prechargep = <0x22>;
    	};
    };
    

    The DeviceTree of my board nrf52840dk_nrf52840.dts.pre.tmp file:

      i2c0: i2c@40003000 {
       #address-cells = <1>;
       #size-cells = <0>;
       reg = <0x40003000 0x1000>;
       clock-frequency = <100000>;
       interrupts = <3 1>;
       status = "disabled";
       label = "I2C_0";
      };
    
    arduino_i2c: &i2c0 {
     compatible = "nordic,nrf-twi";
     status = "okay";
     sda-pin = <26>;
     scl-pin = <27>;
    };
    

    Although I set the shield the way I have showed you the autoconfig.h is not taking the changes.

    Do you know what could be going on?

    When I try to set "CONFIG SDD1306=y " in the proj.conf (I know the shield do it for me but as I said, it was not working) this warning occurs:

    I have realised that if I go to the kconfig GUI from VisualStudio you have the option of enable SDD1306 driver, but I cant selct the option (I dont know why).

    Again, thank you for your time. Your message has guided me a lot.

Children
No Data
Related