LVGL sample failing to display properly on SHARP displayl

Hello, I am using the nRF54L15 board, and trying to connect to the Adafruit SHARP 400x240 monochrome LCD display.

I got the display driver alone to function just fine after a while, but when I attempted to implement LVGL in the project using the Zephyr sample, I wound up with a BUS FAULT. The full error is below:

[00:00:00.014,616] <err> os: ***** BUS FAULT *****
[00:00:00.014,628] <err> os:   Precise data bus error
[00:00:00.014,632] <err> os:   BFAR Address: 0x1bf9f08
[00:00:00.014,642] <err> os: r0/a1:  0xffffffff  r1/a2:  0x20011264  r2/a3:  0x20011264
[00:00:00.014,649] <err> os: r3/a4:  0x01bf9f00 r12/ip:  0xffffda80 r14/lr:  0x00019275
[00:00:00.014,654] <err> os:  xpsr:  0x09000000
[00:00:00.014,658] <err> os: Faulting instruction address (r15/pc): 0x000192b0
[00:00:00.014,677] <err> os: >>> ZEPHYR FATAL ERROR 25: Unknown error on CPU 0
[00:00:00.014,691] <err> os: Current thread: 0x20010940 (unknown)
[00:00:00.076,313] <err> os: Halting system

The hardware seems to be fine, on the display I have connected GND, VIN, CS to port 1, pin 8, CLK to port 1, pin 11, and MOSI to port 1, pin 12. The Adafruit display datasheet said that these were all of the pins required.

Here are the files as of now:

main.c (unchanged sample code)

/*
 * Copyright (c) 2018 Jan Van Winkel <[email protected]>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/display.h>
#include <zephyr/drivers/gpio.h>
#include <lvgl.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/kernel.h>
#include <lvgl_input_device.h>

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

static uint32_t count;

#ifdef CONFIG_RESET_COUNTER_SW0
static struct gpio_dt_spec button_gpio = GPIO_DT_SPEC_GET_OR(
		DT_ALIAS(sw0), gpios, {0});
static struct gpio_callback button_callback;

static void button_isr_callback(const struct device *port,
				struct gpio_callback *cb,
				uint32_t pins)
{
	ARG_UNUSED(port);
	ARG_UNUSED(cb);
	ARG_UNUSED(pins);

	count = 0;
}
#endif /* CONFIG_RESET_COUNTER_SW0 */

#ifdef CONFIG_LV_Z_ENCODER_INPUT
static const struct device *lvgl_encoder =
	DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_encoder_input));
#endif /* CONFIG_LV_Z_ENCODER_INPUT */

#ifdef CONFIG_LV_Z_KEYPAD_INPUT
static const struct device *lvgl_keypad =
	DEVICE_DT_GET(DT_COMPAT_GET_ANY_STATUS_OKAY(zephyr_lvgl_keypad_input));
#endif /* CONFIG_LV_Z_KEYPAD_INPUT */

static void lv_btn_click_callback(lv_event_t *e)
{
	ARG_UNUSED(e);

	count = 0;
}

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

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

#ifdef CONFIG_RESET_COUNTER_SW0
	if (gpio_is_ready_dt(&button_gpio)) {
		int err;

		err = gpio_pin_configure_dt(&button_gpio, GPIO_INPUT);
		if (err) {
			LOG_ERR("failed to configure button gpio: %d", err);
			return 0;
		}

		gpio_init_callback(&button_callback, button_isr_callback,
				   BIT(button_gpio.pin));

		err = gpio_add_callback(button_gpio.port, &button_callback);
		if (err) {
			LOG_ERR("failed to add button callback: %d", err);
			return 0;
		}

		err = gpio_pin_interrupt_configure_dt(&button_gpio,
						      GPIO_INT_EDGE_TO_ACTIVE);
		if (err) {
			LOG_ERR("failed to enable button callback: %d", err);
			return 0;
		}
	}
#endif /* CONFIG_RESET_COUNTER_SW0 */

#ifdef CONFIG_LV_Z_ENCODER_INPUT
	lv_obj_t *arc;
	lv_group_t *arc_group;

	arc = lv_arc_create(lv_screen_active());
	lv_obj_align(arc, LV_ALIGN_CENTER, 0, -15);
	lv_obj_set_size(arc, 150, 150);

	arc_group = lv_group_create();
	lv_group_add_obj(arc_group, arc);
	lv_indev_set_group(lvgl_input_get_indev(lvgl_encoder), arc_group);
#endif /* CONFIG_LV_Z_ENCODER_INPUT */

#ifdef CONFIG_LV_Z_KEYPAD_INPUT
	lv_obj_t *btn_matrix;
	lv_group_t *btn_matrix_group;
	static const char *const btnm_map[] = {"1", "2", "3", "4", ""};

	btn_matrix = lv_buttonmatrix_create(lv_screen_active());
	lv_obj_align(btn_matrix, LV_ALIGN_CENTER, 0, 70);
	lv_buttonmatrix_set_map(btn_matrix, (const char **)btnm_map);
	lv_obj_set_size(btn_matrix, 100, 50);

	btn_matrix_group = lv_group_create();
	lv_group_add_obj(btn_matrix_group, btn_matrix);
	lv_indev_set_group(lvgl_input_get_indev(lvgl_keypad), btn_matrix_group);
#endif /* CONFIG_LV_Z_KEYPAD_INPUT */

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

		hello_world_button = lv_button_create(lv_screen_active());
		lv_obj_align(hello_world_button, LV_ALIGN_CENTER, 0, -15);
		lv_obj_add_event_cb(hello_world_button, lv_btn_click_callback, LV_EVENT_CLICKED,
				    NULL);
		hello_world_label = lv_label_create(hello_world_button);
	} else {
		hello_world_label = lv_label_create(lv_screen_active());
	}

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

	count_label = lv_label_create(lv_screen_active());
	lv_obj_align(count_label, LV_ALIGN_BOTTOM_MID, 0, 0);

	lv_timer_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_timer_handler();
		++count;
		k_sleep(K_MSEC(10));
	}
}

prj.conf

CONFIG_MAIN_STACK_SIZE=4096

CONFIG_GPIO=y
CONFIG_SPI=y

CONFIG_LS0XX=y

CONFIG_DISPLAY=y
CONFIG_DISPLAY_LOG_LEVEL_ERR=y

CONFIG_LOG=y

CONFIG_LVGL=y
CONFIG_LV_USE_LOG=y
CONFIG_LV_USE_LABEL=y
CONFIG_LV_USE_ARC=y
CONFIG_LV_USE_MONKEY=y
CONFIG_LV_FONT_MONTSERRAT_14=y

CONFIG_LV_Z_MEM_POOL_SIZE=16384

CONFIG_LV_Z_BITS_PER_PIXEL=1
CONFIG_LV_COLOR_DEPTH_1=y

CONFIG_PRINTK=y
CONFIG_LOG_BUFFER_SIZE=50240

app.overlay (had to edit the ls013b7dh03 board to match the nRF54L15 pinout)

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

&spi21 {
    compatible = "nordic,nrf-spim";
    status = "okay";
    cs-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
    pinctrl-0 = <&spi21_default>;
    pinctrl-1 = <&spi21_sleep>;
    pinctrl-names = "default", "sleep";

    ls0xx: ls0xx@0 {
        compatible = "sharp,ls0xx";
        spi-max-frequency = <2000000>;
        reg = <0>;
        width = <400>;
        height = <240>;
        extcomin-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>; /* D8 */
        extcomin-frequency = <60>; /* required if extcomin-gpios is defined */
        disp-en-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; /* D6 */
    };
};

&pinctrl {
    spi21_default: spi21_default {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 1, 11)>,
                    <NRF_PSEL(SPIM_MOSI, 1, 12)>/*,
                    <NRF_PSEL(SPIM_MISO, 1, 14)>*/;
        };
    };
    spi21_sleep: spi21_sleep {
        group1 {
            psels = <NRF_PSEL(SPIM_SCK, 1, 11)>,
                    <NRF_PSEL(SPIM_MOSI, 1, 12)>/*,
                    <NRF_PSEL(SPIM_MISO, 1, 14)>*/;
            low-power-enable;
        };
    };
};

A note is that after getting the bus fault, using addr2line, the error seems to spawn from display.h, notably this function: 

static inline int display_write(const struct device *dev, const uint16_t x,
				const uint16_t y,
				const struct display_buffer_descriptor *desc,
				const void *buf)
{
	struct display_driver_api *api =
		(struct display_driver_api *)dev->api;
	
	return api->write(dev, x, y, desc, buf);
}

I believe 'dev' is an invalid value, but I cannot understand how that happens.

Parents Reply Children
No Data
Related