Tft.c porting configuration for stm32h7


I have been trying to port lvgl to stm32h7b3i-dk based on the official demo for the stm32f746 discovery board for about 2 months. However, I still cannot get it to show anything other than a white screen. I believe the problem is with my tft.c file as my other files (touchscreen.c…) are more or less the same.

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


What LVGL version are you using?


What do you want to achieve?

To port LVGL to stm32h7b3i-dk.

What have you tried so far?

I have tried to edit the BSP lcd driver for stm32h7b3i-dk as I noticed that there official demo does not include the lcd driver as it is merged into the tft.c file. However, all I managed to do is display an empty white screen. Now I have included the BSP LCD driver file and am just calling the functions in the tft.c file as shown below. However, it still does not work and I am unsure why.

I would be grateful if anyone could provide me with some guidance here. Thank you for your time and help!

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

/* Includes ------------------------------------------------------------------*/
//#include "../../Core/Inc/main.h"
#include "../../lv_conf.h"
#include "../../lvgl/lvgl.h"
#include <string.h>
#include <stdlib.h>

#include "tft.h"
#include "../../Drivers/CMSIS/Device/ST/STM32H7xx/Include/stm32h7xx.h"
#include "../../Drivers/BSP/STM32H7B3I-DK/stm32h7b3i_discovery.h"
#include "../../Drivers/BSP/STM32H7B3I-DK/stm32h7b3i_discovery_lcd.h"
#include "../../Drivers/BSP/STM32H7B3I-DK/stm32h7b3i_discovery_sdram.h"
#include "../../Drivers/BSP/STM32H7B3I-DK/stm32h7b3i_discovery_ts.h"
#include "../../Drivers/BSP/Components/rk043fn48h/rk043fn48h.h"

 *      DEFINES
#define LCD_FB_START_ADDRESS 0xD0000000


/*These 3 functions are needed by LittlevGL*/
static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t * color_p);
static void ex_disp_clean_dcache(lv_disp_drv_t *drv);

static lv_disp_drv_t disp_drv;

#if LV_COLOR_DEPTH == 16
typedef uint16_t uintpixel_t;
#elif LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
typedef uint32_t uintpixel_t;

/* You can try to change buffer to internal ram by uncommenting line below and commenting
 * SDRAM one. */
//static uintpixel_t my_fb[TFT_HOR_RES * TFT_VER_RES];

static __IO uintpixel_t * my_fb = (__IO uintpixel_t*) (0x60000000);

static DMA_HandleTypeDef  DmaHandle;
static int32_t            x1_flush;
static int32_t            y1_flush;
static int32_t            x2_flush;
static int32_t            y2_fill;
static int32_t            y_fill_act;
static const lv_color_t * buf_to_flush;

static lv_disp_t *our_disp = NULL;

 *      MACROS
void tft_init(void)
	/* There is only one display on STM32 */
	if(our_disp != NULL)
    /* LCD Initialization */


    /* Enable the LCD */


	* Create a buffer for drawing

   /* LittlevGL requires a buffer where it draws the objects. The buffer's has to be greater than 1 display row*/

	static lv_disp_draw_buf_t disp_buf_1;
	static lv_color_t buf1_1[TFT_HOR_RES * 68];
	static lv_color_t buf1_2[TFT_HOR_RES * 68];
	lv_disp_draw_buf_init(&disp_buf_1, buf1_1, buf1_2, TFT_HOR_RES * 68);   /*Initialize the display buffer*/

	* Register the display in LittlevGL

	lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

	/*Set up the functions to access to your display*/

	/*Set the resolution of the display*/
	disp_drv.hor_res = 480;
	disp_drv.ver_res = 272;

	/*Used to copy the buffer's content to the display*/
	disp_drv.flush_cb = ex_disp_flush;
	disp_drv.clean_dcache_cb = ex_disp_clean_dcache;

	/*Set a display buffer*/
	disp_drv.draw_buf = &disp_buf_1;

	/*Finally register the driver*/
	our_disp = lv_disp_drv_register(&disp_drv);


/* Flush the content of the internal buffer the specific area on the display
 * You can use DMA or any hardware acceleration to do this operation in the background but
 * 'lv_flush_ready()' has to be called when finished
 * This function is required only when LV_VDB_SIZE != 0 in lv_conf.h*/
static void ex_disp_flush(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t * color_p)
	int32_t x1 = area->x1;
	int32_t x2 = area->x2;
	int32_t y1 = area->y1;
	int32_t y2 = area->y2;
    /*Return if the area is out the screen*/

    if(x2 < 0) return;
    if(y2 < 0) return;
    if(x1 > TFT_HOR_RES - 1) return;
    if(y1 > TFT_VER_RES - 1) return;

    /*Truncate the area to the screen*/
    int32_t act_x1 = x1 < 0 ? 0 : x1;
    int32_t act_y1 = y1 < 0 ? 0 : y1;
    int32_t act_x2 = x2 > TFT_HOR_RES - 1 ? TFT_HOR_RES - 1 : x2;
    int32_t act_y2 = y2 > TFT_VER_RES - 1 ? TFT_VER_RES - 1 : y2;

    x1_flush = act_x1;
    y1_flush = act_y1;
    x2_flush = act_x2;
    y2_fill = act_y2;
    y_fill_act = act_y1;
    buf_to_flush = color_p;

    /*##-7- Start the DMA transfer using the interrupt mode #*/
    /* Configure the source, destination and buffer size DMA fields and Start DMA Stream transfer */
    /* Enable All the DMA interrupts */
    HAL_StatusTypeDef err;
    uint32_t length = (x2_flush - x1_flush + 1);
#if LV_COLOR_DEPTH == 24 || LV_COLOR_DEPTH == 32
    length *= 2; /* STM32 DMA uses 16-bit chunks so multiply by 2 for 32-bit color */
    err = HAL_DMA_Start_IT(&DmaHandle,(uint32_t)buf_to_flush, (uint32_t)&my_fb[y_fill_act * TFT_HOR_RES + x1_flush],
    if(err != HAL_OK)
        while(1);	/*Halt on error*/

static void ex_disp_clean_dcache(lv_disp_drv_t *drv)

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.