<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>nRF52840 + SSD1680 (mipi-dbi-spi) + LVGL</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/122065/nrf52840-ssd1680-mipi-dbi-spi-lvgl</link><description>Hi, 
 I&amp;#39;m working on a custom board based on nRF52840 and a 2.9&amp;quot; ePaper display (SSD1680) connected via SPI using the mipi-dbi-spi interface. I&amp;#39;m using nRF Connect SDK v3.0.0 (Zephyr) and LVGL for graphics rendering. 
 In the devicetree, the display is</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Fri, 06 Jun 2025 13:07:47 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/122065/nrf52840-ssd1680-mipi-dbi-spi-lvgl" /><item><title>RE: nRF52840 + SSD1680 (mipi-dbi-spi) + LVGL</title><link>https://devzone.nordicsemi.com/thread/538427?ContentTypeID=1</link><pubDate>Fri, 06 Jun 2025 13:07:47 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:c71bcfbc-6a10-4764-8155-e5f97fc50c11</guid><dc:creator>&amp;#216;yvind</dc:creator><description>&lt;p&gt;Hello, happy to hear that you got past one hurdle.&lt;/p&gt;
&lt;p&gt;Unfortunately we do not provide support for the LVGL library, this is something specific from the Zephyr community. You can &lt;a href="https://discord.com/invite/Ck7jw53nU2"&gt;reach out to them through Discord&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Good luck in getting a cool display up and running&lt;/p&gt;
&lt;p&gt;Kind regards,&lt;br /&gt;Øyvind&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: nRF52840 + SSD1680 (mipi-dbi-spi) + LVGL</title><link>https://devzone.nordicsemi.com/thread/538423?ContentTypeID=1</link><pubDate>Fri, 06 Jun 2025 12:58:21 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b5252b84-d8fa-4194-b749-cebb3d3141c6</guid><dc:creator>alex2103</dc:creator><description>&lt;p data-start="324" data-end="492"&gt;I want to share my progress and ask for advice about LVGL + Zephyr on a custom board with an SSD1680 E-Paper display (using mipi-dbi-spi), nRF52840 SoC, and NCS v3.0.2.&lt;/p&gt;
&lt;p data-start="494" data-end="530"&gt;Previously, I was getting the error:&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;&amp;lt;err&amp;gt; lvgl: Display device not ready.&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="577" data-end="673"&gt;This happened during startup because LVGL was trying to initialize before the display had power.&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;I fixed this by adding to my &lt;code data-start="704" data-end="714"&gt;prj.conf&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;CONFIG_LV_Z_AUTO_INIT=n&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="748" data-end="806"&gt;This stopped LVGL from initializing automatically at boot.&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="808" data-end="856"&gt;Now I initialize everything manually in my code:&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;void view_lvgl()
{
    LOG_DBG(&amp;quot;Begin&amp;quot;);
    gpio_pin_configure_dt(&amp;amp;out, GPIO_OUTPUT_ACTIVE);
    gpio_pin_set_dt(&amp;amp;out, 1);
    LOG_DBG(&amp;quot;PowerON Disp&amp;quot;);
    k_msleep(250);

    display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
    LOG_DBG(&amp;quot;Init Disp&amp;quot;);
    device_init(display_dev);

    while (!device_is_ready(display_dev)) {
        LOG_WRN(&amp;quot;Device not ready...\n&amp;quot;);
        k_msleep(100);
    }
    LOG_DBG(&amp;quot;Start lvgl_init&amp;quot;);

    lvgl_init();

    LOG_DBG(&amp;quot;LVGL started&amp;quot;);
    hello_world_label = lv_label_create(lv_scr_act());
    lv_label_set_text(hello_world_label, &amp;quot;Hello world!&amp;quot;);
    lv_obj_align(hello_world_label, LV_ALIGN_CENTER, 0, 0);
    LOG_DBG(&amp;quot;Label created&amp;quot;);

    LOG_DBG(&amp;quot;lv_task_handler starting&amp;quot;);
    lv_task_handler();
    display_blanking_off(display_dev);
    LOG_DBG(&amp;quot;lv_task_handler finish&amp;quot;);

    while (1) {
        printk(&amp;quot;view_lvgl loop\n&amp;quot;);
        k_msleep(1000);
    }
}&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="1783" data-end="1833"&gt;Now, the &amp;quot;Display device not ready&amp;quot; error is gone.&lt;/p&gt;
&lt;p data-start="1835" data-end="1971"&gt;However, I now have a new issue:&lt;br /&gt; &lt;strong data-start="1868" data-end="1971"&gt;As soon as &lt;code data-start="1881" data-end="1900"&gt;lv_task_handler()&lt;/code&gt; is called for the first time, the system crashes with a fatal error.&lt;/strong&gt;&lt;/p&gt;
&lt;p data-start="1973" data-end="2020"&gt;Here is the stack trace from the fault handler:&lt;br /&gt;&lt;pre class="ui-code" data-mode="text"&gt;k_sys_fatal_error_handler(unsigned int reason, const struct arch_esf * esf) (e:\krisrianna\git\nrf\blinky\build\zephyr\include\generated\zephyr\syscalls\log_ctrl.h:34)
z_fatal_error(unsigned int reason, const struct arch_esf * esf) (e:\Segger\ncs\v3.0.2\zephyr\kernel\fatal.c:119)
z_arm_fatal_error(unsigned int reason, const struct arch_esf * esf) (e:\Segger\ncs\v3.0.2\zephyr\arch\arm\core\fatal.c:86)
z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, _callee_saved_t * callee_regs) (e:\Segger\ncs\v3.0.2\zephyr\arch\arm\core\cortex_m\fault.c:1107)
z_arm_usage_fault() (e:\Segger\ncs\v3.0.2\zephyr\arch\arm\core\cortex_m\fault_s.S:102)
&amp;lt;signal handler called&amp;gt; (Unknown Source:0)
[Unknown code] (Unknown Source:0)
display_write(const void * buf, const struct display_buffer_descriptor * desc, const uint16_t y, const uint16_t x, const struct device * dev) (e:\Segger\ncs\v3.0.2\zephyr\include\zephyr\drivers\display.h:254)
lvgl_flush_cb_mono(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) (e:\Segger\ncs\v3.0.2\zephyr\modules\lvgl\lvgl_display_mono.c:103)
call_flush_cb(uint8_t * px_map, const lv_area_t * area, lv_display_t * disp) (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\core\lv_refr.c:1303)
draw_buf_flush(lv_display_t * disp) (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\core\lv_refr.c:1270)
refr_invalid_areas() (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\core\lv_refr.c:611)
lv_display_refr_timer(lv_timer_t * tmr) (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\core\lv_refr.c:405)
lv_timer_exec(lv_timer_t * timer) (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\misc\lv_timer.c:327)
lv_timer_handler() (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\misc\lv_timer.c:107)
lv_timer_handler() (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\misc\lv_timer.c:63)
lv_task_handler() (e:\Segger\ncs\v3.0.2\modules\lib\gui\lvgl\src\lv_api_map_v8.h:77)
view_lvgl() (e:\krisrianna\git\nrf\blinky\src\main.c:136)
z_thread_entry(k_thread_entry_t entry, void * p1, void * p2, void * p3) (e:\Segger\ncs\v3.0.2\zephyr\lib\os\thread_entry.c:48)&lt;/pre&gt;&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;It seems the crash occurs inside the display driver when LVGL tries to flush the buffer for the first time.&lt;code data-start="704" data-end="714"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I did more debugging and found that the crash is caused by a NULL pointer passed to the display driver.&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Just before the crash, in the function display_write() (from include/zephyr/drivers/display.h), the dev pointer is NULL:&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:224px;max-width:351px;" height="224" src="https://devzone.nordicsemi.com/resized-image/__size/702x448/__key/communityserver-discussions-components-files/4/pastedimage1749214636141v2.png" width="351" alt=" " /&gt;&lt;br /&gt;As you can see, when display_write() is called, dev == 0x0 (NULL). This leads to a crash when the API tries to dereference the device pointer.&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&amp;nbsp;&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="mcetoc_1it2kr87v0" data-start="3044" data-end="3061"&gt;My questions:&lt;/h3&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&lt;/code&gt;&lt;/p&gt;
&lt;ol data-start="3063" data-end="4110"&gt;
&lt;li data-start="3063" data-end="3230"&gt;
&lt;p data-start="3066" data-end="3230"&gt;Is it correct to call device_init(display_dev) directly?&lt;br data-start="3128" data-end="3131" /&gt; In most Zephyr examples, I don&amp;#39;t see this function being called.&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="3232" data-end="3426"&gt;
&lt;p data-start="3235" data-end="3426"&gt;Is my sequence of powering up, checking readiness, and then calling lvgl_init() correct?&lt;br data-start="3329" data-end="3332" /&gt; Do I need to wait longer after powering up the display, or do anything special for SSD1680?&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="3428" data-end="3743"&gt;
&lt;p data-start="3431" data-end="3743"&gt;What is the minimal recommended LVGL event/task handling loop?&lt;br data-start="3497" data-end="3500" /&gt; Right now I just call lv_task_handler() once before entering the main loop (which only prints a message). Should I be calling lv_task_handler() in the main loop with some interval, or do I need to process events differently for E-Paper?&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="3745" data-end="4004"&gt;
&lt;p data-start="3748" data-end="4004"&gt;What could be causing this crash in display_write()?&lt;br data-start="3806" data-end="3809" /&gt; Could it be a problem with my devicetree, buffer sizes, or driver configuration? What is the best way to debug or verify the display initialization and flush pipeline for this type of E-Paper?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;What could cause LVGL or the display pipeline to pass a NULL device pointer to display_write()?&lt;/p&gt;
&lt;p&gt;Am I missing some required initialization or assignment step for the display device when doing manual LVGL init?&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4006" data-end="4110"&gt;
&lt;p data-start="4009" data-end="4110"&gt;Anything else I should be aware of when using deferred LVGL init on Zephyr with E-Paper displays?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p data-start="4112" data-end="4206"&gt;Thanks for any tips or corrections!&lt;/p&gt;
&lt;p data-start="675" data-end="715"&gt;&lt;code data-start="704" data-end="714"&gt;&amp;nbsp;&lt;/code&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>