Stm32f4 and st7789 using with LittleVgl

Hi, i have stm32f407 disco board and st7789 tft screen. How can use littleVgl and i need a driver for st7789.

You will need to provide your own driver as lv_drivers does not have one for that controller.

1 Like

i found a driver for st7789. How can import littleVgl lib now ?

I recommend following the steps in the porting guide under “Set up a project” and “Display interface”.

1 Like

I finally setup lvgl in my project, but now the pixels coming very slowly on screen.
Seems in the video one example;

My flush code;

void st7789_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
	 	if(area->x2 < 0) return;
	    if(area->y2 < 0) return;
	    if(area->x1 > LV_HOR_RES_MAX - 1) return;
	    if(area->y1 > LV_VER_RES_MAX - 1) return;
    int16_t x, y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
        	uint16_t setColor = (uint16_t)color_p->full;
        	ST7789_DrawPixel((uint16_t)x,(uint16_t) y,setColor);
            color_p++;
        }
    }
    lv_disp_flush_ready(disp_drv);
}

and in main;

 lv_init();
  ST7789_Init();
  
  static lv_disp_buf_t disp_buf;
  static lv_color_t buf_1[LV_HOR_RES_MAX * 10];
  lv_disp_buf_init(&disp_buf, buf_1, NULL, LV_HOR_RES_MAX * 10);

  lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.buffer = &disp_buf;
  disp_drv.flush_cb = st7789_flush_cb;
  lv_disp_drv_register(&disp_drv);

lv_test_label(); // for screen test

  while (1)
  {
	  lv_task_handler();
	          lv_tick_inc(1);
	          HAL_Delay(1);
  }

how can i accelerate the update to screen?

Refactor the flush function so that you set the display window once, and then push all the pixels. Right now you are calling DrawPixel multiple times which is probably resetting the cursor and window every time.

You will have to look into how to do this for your particular platform as the specifics differ among drivers.

1 Like

I try a new method for send data but now my screen not true working.


This image with drawPixel metod.

st7789_flush_cb method with draw pixel in tft.c

int16_t x, y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
        	//ST7789_DrawPixel(x, y,color_p->full);
        	color_p++;
        }
    }


But the image from my new methot.

st7789_flush_cb method with send all data with pointer in tft.c

ST7789_Send_Data(area->x1, area->y1, area->x2, area->y2,(uint8_t *)color_p);

And ST7789_Send_Data method is here;

static void ST7789_SPI_Send(uint8_t *data, uint16_t size)
{
	HAL_SPI_Transmit(&ST7789_SPI_PORT,data,size,100);
}

void ST7789_Send_Data(uint16_t x, uint16_t y, uint16_t x_end, uint16_t y_end, uint8_t *p){
	ST7789_SetAddressWindow(x, y, x_end, y_end);
	ST7789_DC_Set();
	ST7789_SPI_Send(p,(x_end - x + 1) * (y_end - y + 1) * 2);
}

How can fix it?
ı modified for my project this driver:

Looks like the ST7789_Send_Data function expects a different color format than what you’re providing. Check if it wants BGR color instead of RGB.

i use rgb.

/* RGB/BGR Order ('0' = RGB, '1' = BGR) */
#define ST7789_MADCTL_RGB 0x00

If you’re using 16bpp color try toggling LV_COLOR_16_SWAP; it might help.

/* Swap the 2 bytes of RGB565 color.

  • Useful if the display has a 8 bit interface (e.g. SPI)*/
    #define LV_COLOR_16_SWAP 1
    now i get true colors thank u :slight_smile:

so how can i use dma? i tried but my lv_color_t buffer stack was overflow.
static lv_color_t buf_1[LV_HOR_RES_MAX * 240];
lv_disp_buf_init(&disp_buf, buf_1, NULL, LV_HOR_RES_MAX * 240);

You want to DMA the colors from color_p inside the flush function, not buf_1.

So i dont understant. I dont use buffer for dma?

DMA should be used to accelerate sending data to the display chip (ST7789). That means you would use DMA to replace ST7789_Send_Data.

Yes, i configured my functions for dma;

static void ST7789_SPI_Send_DMA(uint8_t *data, uint16_t size)
{
	HAL_SPI_Transmit_DMA(&ST7789_SPI_PORT,data,size);
}

void ST7789_Send_Data_DMA(uint16_t x, uint16_t y, uint16_t x_end, uint16_t y_end, uint8_t *p){
	ST7789_SetAddressWindow(x, y, x_end, y_end);
	ST7789_DC_Set();
	ST7789_SPI_Send_DMA(p,(x_end - x + 1) * (y_end - y + 1) * 2);
}

And my tft functions is here;

#include "tosTft.h"
#include "st7789.h"
#include "main.h"

static lv_disp_drv_t * st7789disp_p;

static void st7789_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p);
void tos_Tft_init(void){

	  ST7789_Init();
	  lv_init();
	 static lv_disp_buf_t disp_buf;
	 static lv_color_t buf[LV_HOR_RES_MAX * LV_VER_RES_MAX / 10];
	 lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * LV_VER_RES_MAX / 10);


	  lv_disp_drv_t disp_drv;
	  lv_disp_drv_init(&disp_drv);
	  disp_drv.buffer = &disp_buf;
	  disp_drv.flush_cb = st7789_flush_cb;
	  lv_disp_drv_register(&disp_drv);

}

static void st7789_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
	 	if(area->x2 < 0) return;
	    if(area->y2 < 0) return;
	    if(area->x1 > LV_HOR_RES_MAX - 1) return;
	    if(area->y1 > LV_VER_RES_MAX - 1) return;

	    //ST7789_Send_Data(area->x1, area->y1, area->x2, area->y2,(uint8_t *)color_p);

     ST7789_Send_Data_DMA(area->x1, area->y1, area->x2, area->y2,(uint8_t *)color_p);
 st7789disp_p=disp_drv;


    void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
    {
    	 lv_disp_flush_ready(st7789disp_p);
    }

    void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi){}
   // lv_disp_flush_ready(disp_drv);
}

But only geting first 40 rows and dont update new screen?

Not sure why that’s happening, but the first step is probably to try ST7789_Send_Data_DMA independently of LVGL and make it behave identically to ST7789_Send_Data.

Is it your real code?

You define the functions HAL_SPI_TxCpltCallback and HAL_SPI_ErrorCallback within st7789_flush_cb

I never thought this would compile without any error.
Your HAL_SPI_TxCpltCallback will never be called!

In STM Hal functions there is a weak HAL_SPI_TxCpltCallback which is called.

Put the two functions outside of st7789_flush_cb

Firstly was suprised me. I was examine another projects then i saw this method. I tried and only compiler gave warning. :slight_smile: BUt i checked on debug,were enter in the method. I ll try outside the methods, if i get a positive equal i write here.

Dont anything was changed .