How to run LVGL on M5Stack



  • Here is what I came up with (and works with lvgl/lvgl 8.1 on my Core 2).

    #include <M5Core2.h>
    #include <Arduino.h>
    #include <lvgl.h>
    #include <Wire.h>
    #include <SPI.h>
    
    // init the tft espi
    static lv_disp_draw_buf_t draw_buf;
    static lv_disp_drv_t disp_drv;  // Descriptor of a display driver
    static lv_indev_drv_t indev_drv; // Descriptor of a touch driver
    
    M5Display *tft;
    
    static void ta_event_cb(lv_event_t * e);
    static lv_obj_t * kb;
    
    static void ta_event_cb(lv_event_t * e)
    {
        lv_event_code_t code = lv_event_get_code(e);
        lv_obj_t * ta = lv_event_get_target(e);
        if(code == LV_EVENT_CLICKED || code == LV_EVENT_FOCUSED) {
            /*Focus on the clicked text area*/
            if(kb != NULL) lv_keyboard_set_textarea(kb, ta);
        }
    
        else if(code == LV_EVENT_READY) {
            LV_LOG_USER("Ready, current text: %s", lv_textarea_get_text(ta));
        }
    }
    
    static void btnPowerOff_event(lv_event_t * event)
    {
        M5.Axp.PowerOff();
    }
    
    void tft_lv_initialization() {
      M5.begin();
    
      lv_init();
    
      static lv_color_t buf1[(LV_HOR_RES_MAX * LV_VER_RES_MAX) / 10];  // Declare a buffer for 1/10 screen siz
      static lv_color_t buf2[(LV_HOR_RES_MAX * LV_VER_RES_MAX) / 10];  // second buffer is optionnal
    
      // Initialize `disp_buf` display buffer with the buffer(s).
      lv_disp_draw_buf_init(&draw_buf, buf1, buf2, (LV_HOR_RES_MAX * LV_VER_RES_MAX) / 10);
    
      tft = &M5.Lcd;
    }
    
    // Display flushing
    void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
      uint32_t w = (area->x2 - area->x1 + 1);
      uint32_t h = (area->y2 - area->y1 + 1);
    
      tft->startWrite();
      tft->setAddrWindow(area->x1, area->y1, w, h);
      tft->pushColors((uint16_t *)&color_p->full, w * h, true);
      tft->endWrite();
    
      lv_disp_flush_ready(disp);
    }
    
    void init_disp_driver() {
      lv_disp_drv_init(&disp_drv);  // Basic initialization
    
      disp_drv.flush_cb = my_disp_flush;  // Set your driver function
      disp_drv.draw_buf = &draw_buf;      // Assign the buffer to the display
      disp_drv.hor_res = LV_HOR_RES_MAX;  // Set the horizontal resolution of the display
      disp_drv.ver_res = LV_VER_RES_MAX;  // Set the vertical resolution of the display
    
      lv_disp_drv_register(&disp_drv);                   // Finally register the driver
      lv_disp_set_bg_color(NULL, lv_color_hex3(0x000));  // Set default background color to black
    }
    
    void my_touchpad_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
    {
      TouchPoint_t pos = M5.Touch.getPressPoint();
      bool touched = ( pos.x == -1 ) ? false : true;  
    
      if(!touched) {    
        data->state = LV_INDEV_STATE_RELEASED;
      } else {
        data->state = LV_INDEV_STATE_PRESSED; 
        data->point.x = pos.x;
        data->point.y = pos.y;
      }
    }
    
    void init_touch_driver() {
      lv_disp_drv_register(&disp_drv);
    
      lv_indev_drv_init(&indev_drv);
      indev_drv.type = LV_INDEV_TYPE_POINTER;
      indev_drv.read_cb = my_touchpad_read;
      lv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);  // register
    }
    
    void setup()
    {
      tft_lv_initialization();
      init_disp_driver();
      init_touch_driver();
    
      lv_obj_t * btn1 = lv_btn_create(lv_scr_act());
      lv_obj_t * label = lv_label_create(btn1);
      lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0);
      lv_label_set_text(label, "Power Off");
      lv_obj_center(label);
      lv_obj_add_event_cb(btn1, btnPowerOff_event, LV_EVENT_CLICKED, NULL);
    }
    
    void loop()
    {
      M5.update();
      lv_task_handler();
    }
    


  • @jackrazors Thanks for sharing!



  • I'm struggling with edgline but just realized the code which is automatically generated is not compatible with LVGL 8.x, only version 7.
    Looks like they have not updated the tools since a while, not even sure if they still want to maintain it.
    I am going back to old school manual coding...I don't mind writing lines of code but I am bad at designing UIs and EdgeLine seemed to be my savior (but not anymore unfortunately)



  • @jackrazors hello, I tried to run your code, but the function my_touchpad_read is never called..

    Would be possible for you to share the repo ?
    Thanks !!



  • @lunard said in How to run LVGL on M5Stack:

    @jackrazors hello, I tried to run your code, but the function my_touchpad_read is never called..

    Would be possible for you to share the repo ?
    Thanks !!

    Ok @JackRazors was missing lv_tick_inc(1); in the loop function



  • Hello@erich

    LVGL 8.0.2 is listed below.

    LVGL 8.0.2
    LVGL 8 demo with M5Stack , M5Stamp C3
    https://forum.m5stack.com/topic/4161/lvgl-8-demo-with-m5stack-m5stamp-c3



  • Would be perfect to use with the M5Stack Atom Display with a 7 inch display.

    But does it run on an Atom ?



  • Hello,

    I have try to run the the sketch "drawing-board" on my Core2.
    Have some problem with the lv_config.h file. My question is where to store exactly this file?
    Have tried several locations but always the error messages

    /Users/jankromhout/Documents/Arduino/libraries/lvgl/src/../src/misc/../lv_conf_internal.h:46:120: note: #pragma message: Possible failure to include lv_conf.h, please read the comment in this file if you get errors
    #pragma message("Possible failure to include lv_conf.h, please read the comment in this file if you get errors")

    And with changes needed to be done.

    I'm using the latest version of lvgl.

    Any help is welcome.
    Cheers,
    Jan



  • Hello@powersoft

    lv_conf.h

    0_1673751414986_lv_conf.jpg



  • Thanks for this. Do I need make changes in lv_config.h to run it on my the core2