STM32 Discovery F746NG on MbedOS, troubles with the Demo

Hi there,


I want to porting to STM32 Discovery F746NG runned on MBedOS5 but I had only black screen and after 10hours I have no idea where to continue. I am sure i misunderstood something.

What MCU/Processor/Board and compiler are you using?

Discovery F746NG

What do you want to achieve?

I want to use the LittlevGL together with the Mbed on the ST boards but for a start I want to see a simple label or a button. Later I want to share on Mbed web because sometimes users ask about a GUI library. I found few discussions where someone tried to do that but still not finished and after 6 months no updates.

What have you tried so far?

Because the ST published drivers for that board on the Mbed I have tested the touchscreen and I know is working.
I tried to follow instructions from this web or from the github but without successful = black screen. Only touch working well.

However I had a problem because compiler show me an error and then I found a different struct type as argument in the my_disp_flush example from Quick overview page.
The flush_cb of the struct _disp_drv_t wants as parametr a pointer to the _disp_drv_t type
void (*flush_cb)(struct _disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
But the my_disp_flush function have a pointer to the lv_disp_t type as parametr.

void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p)
    /*rest of code*/
    lv_disp_flush_ready(disp);         /* Indicate you are ready with the flushing*/

I need to know what is correct because I replace it with struct _disp_drv_t and that of course solve my problem with the compiler’s error but I have black screen :slight_smile:

If you were kind and send me to the correct direction, I would be very grateful.

Code to reproduce

#include "mbed.h"
#include "TS_DISCO_F746NG.h"
#include "LCD_DISCO_F746NG.h"
#include "lvgl/lvgl.h"
#include "lv_conf.h"
#include "demo.h"

#define TICK_DEF 10
#define TICKER_TIME 0.001 * TICK_DEF

Ticker ticker;                                             /*Initialize your system tick*/
LCD_DISCO_F746NG lcd;                      /*Initialize your display driver*/
TS_DISCO_F746NG ts;                          /*Initialize your touchpad driver*/                      
TS_StateTypeDef TS_State;                   /*Initialize your touch state sctruct*/

void lv_ticker_func();
void my_disp_flush(lv_disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p);
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data);
static void event_handler(lv_obj_t * obj, lv_event_t event);

int main()
    printf("Example of MbedOS5 with LittlevGL on Disco F746NI \n");
    //lcd.DisplayStringAt(0, LINE(5), (uint8_t *)"LittlevGL DEMO", CENTER_MODE);
    lv_init();                                  /*Initialize the LittlevGL*/
    static lv_disp_buf_t disp_buf;
    static lv_color_t buf[LV_HOR_RES_MAX * 10]**strong text**; /*Declare a buffer for 10 lines*/
    lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10); /*Initialize the display buffer*/
    /*Implement and register a function which can copy a pixel array to an area of your display*/
    lv_disp_drv_t disp_drv;               /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);          /*Basic initialization*/
    disp_drv.flush_cb = my_disp_flush;    /*Set your driver function*/
    disp_drv.buffer = &disp_buf;          /*Assign the buffer to the display*/
    lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/
    /*Implement and register a function which can read an input device. E.g. for a touch pad*/
    ts.Init(lcd.GetXSize(), lcd.GetYSize());   /*ST touch initialization*/
    lv_indev_drv_t indev_drv;                  /*Descriptor of a input device driver*/
    lv_indev_drv_init(&indev_drv);             /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
    indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
    lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/

    while(1) {
        lv_task_handler(); /*Call lv_task_handler() periodically every few milliseconds. It will redraw the screen if required, handle input devices etc.*/

void lv_ticker_func(){
    lv_tick_inc(TICK_DEF); /*Call lv_tick_inc(x) every x milliseconds in a Timer or Task (x should be between 1 and 10). It is required for the internal timing of LittlevGL.*/

void my_disp_flush(lv_disp_drv_t* disp_drv, const lv_area_t* area, lv_color_t* color_p)
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
    uint16_t x, y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            //put_px(x, y, *color_p)
            lcd.DrawPixel( x, y, color_p->full);

    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/

bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
    static lv_coord_t last_x = 0;
    static lv_coord_t last_y = 0;

    /*Save the state and save the pressed coordinate*/

    if(TS_State.touchDetected == 0){
        data->state = LV_INDEV_STATE_PR;
        data->state = LV_INDEV_STATE_REL;
    //data->state = tttt ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
    if(data->state == LV_INDEV_STATE_PR){
         //touchpad_get_xy(&last_x, &last_y);
        last_x = TS_State.touchX[0];
        last_y = TS_State.touchY[0];
    /*Set the coordinates (if released use the last pressed coordinates)*/
    data->point.x = last_x;
    data->point.y = last_y;

    return false; /*Return `false` because we are not buffering and no more data to read*/

static void event_handler(lv_obj_t * obj, lv_event_t event)
    if(event == LV_EVENT_CLICKED) {
    else if(event == LV_EVENT_VALUE_CHANGED) {

Thank you

BR, Jan

I have used lvGL also with Mbed, but some other board. Maybe this works for you (not used or tested by me):

1 Like

Technically, both are correct (because lv_disp_drv_t is the first member of the lv_disp_t structure). But I would suggest using lv_disp_drv_t as that is what you would pass to lv_disp_flush_ready.

Why did you comment out color_p++ in my_disp_flush? The color_p pointer is a pointer to an array of color values. Right now you will just write the same color over and over which is not correct.

@JojoS Thank you for your response. I know about that repository but here is a problem - the code is 5-9 months old with old version of the LittlevGL probably. So I chose to followed the documentaion for some basics and later I will take an inspiration from others.

@embeddedt Thank you for your response. Thank you for the explanation.
I commented out that because previously I tried it on DiscoF469NI and with with color_p++ I had many very small rectangles on the display and it looks like a nonsense, then I commented out that and display was black. Later I switched to the DiscoF746NG.
However I uncommented that and nothing change, the display is still black.

Do you have LV_COLOR_DEPTH set correctly? Can you print out the values of color_p->full whenever you run through the loop?

1 Like

I feel embarrassed, it is working now but You made my day!
The problem was a combination of both things what you wrote.

  • Commented out the color_p++
  • Wrongly set the color’s format macro LV_COLOR_DEPTH - 16 instead of 32.
    Of course I tried to set it to 32 but with commented out color_p++ had it no effect.
    I apologize for my dump and your wasted time. Thank you so much.

PS: The LittlevGL project is very great and I supported your work with some Donation.

1 Like