Display Issue with ST7789, fuzzy font and picture

Description

I have a 320x170 (ST7789V2) LCD screen , I want to use it to display a GUI, and used the LVGL 8.3.5 graphics library to implement it. I wrote a demo scene by using GUI Guider 1.5.1, but the actual displayed on the lcd is a bit different from what I expected. The text and the picture appear blurry.

expect

but

Has anyone encountered such a phenomenon?

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

NXP I.MXRT1051, IAR ARM 9.40.1, LCD 320x170 with ST7789

What do you want to achieve?

Porting LVGL to the project for the GUI

What have you tried so far?

Implemented a driver for the ST7789V2 by using SPI DMA, and imported the LVGL library into the project, wrote a simple demo scene for testing, worked but the screen seems strange.

Code to reproduce

Add the relevant code snippets here.

The code block(s) should be between ```c and ``` tags:

/*You code here*/

  ST7789 Initialize 
  //************* Start Initial Sequence **********//
  ///< Software Reset
  writeCommond(ST7789_SWRESET);
  wait_ms(200);

  ///< Disable sleep
  writeCommond(ST7789_SLPOUT);
  wait_ms(200);

  ///< Vertical Scrolling Definition
  writeCommond(ST7789_VSCRDEF);
  writeData(0x00);
  writeData(0x00);
  writeData(0x14);
  writeData(0x00);
  writeData(0x00);
  writeData(0x00);

  ///< Normal Display Mode On
  writeCommond(ST7789_NORON);
  wait_ms(10);

  //  Display Inversion: Invert the display colours (light becomes dark and vice versa) (ST7789 Datasheet Pages 188, 190)
  if (INVERTED) {
    writeCommond(ST7789_INVON);
  } else {
    writeCommond(ST7789_INVOFF);
  }

  // Set the read / write scan direction of the frame memory
  writeCommond(ST7789_MADCTL); // MX, MY, RGB mode
  writeData(0x70); // 0x08 set RGB

  /* RGB 5-6-5-bit  */
  writeCommond(ST7789_COLMOD);
  writeData(0x55);///< 65K, 16bit pixel

  /** Display On */
  writeCommond(ST7789_DISPON);
  wait_ms(200);

  /* Porch Setting */
  writeCommond(ST7789_PORCTRL);
  writeData(0x0C);
  writeData(0x0C);
  writeData(0x00);
  writeData(0x33);
  writeData(0x33);

  /* Gate Control */
  writeCommond(ST7789_GCTRL);
  writeData(0x35);

  /* VCOM Setting */
  writeCommond(ST7789_VCOMS);
  writeData(0x1A);

  /* LCM Control */
  writeCommond(ST7789_LCMCTRL);
  writeData(0x2C);

  /* VDV and VRH Command Enable */
  writeCommond(ST7789_VDVVRHEN);
  writeData(0x01);

  /* VRH Set */
  writeCommond(ST7789_VRHS);
  writeData(0x0B);

  /* VDV Set */
  writeCommond(ST7789_VDVSET);
  writeData(0x20);

  /* Frame Rate Control in Normal Mode */
  writeCommond(ST7789_FRCTR2);
  writeData(0x0F);//60MHZ

  /* Power Control 1 */
  writeCommond(ST7789_PWCTRL1);
  writeData(0xA4);
  writeData(0xA1);

  /* Positive Voltage Gamma Control */
  writeCommond(ST7789_PVGAMCTRL);
  writeData(0xF0);
  writeData(0x00);
  writeData(0x04);
  writeData(0x04);
  writeData(0x04);
  writeData(0x05);
  writeData(0x29);
  writeData(0x33);
  writeData(0x3E);
  writeData(0x38);
  writeData(0x12);
  writeData(0x12);
  writeData(0x28);
  writeData(0x30);

  /* Negative Voltage Gamma Control */
  writeCommond(ST7789_NVGAMCTRL);
  writeData(0xF0);
  writeData(0x07);
  writeData(0x0A);
  writeData(0x0D);
  writeData(0x0B);
  writeData(0x07);
  writeData(0x28);
  writeData(0x33);
  writeData(0x3E);
  writeData(0x36);
  writeData(0x14);
  writeData(0x14);
  writeData(0x29);
  writeData(0x32);

  /** Sleep Out */
  writeCommond(ST7789_SLPOUT);
  wait_ms(120);

  /** Display On */
  writeCommond(ST7789_DISPON);


#define LCD_WIDTH             320
#define LCD_HEIGHT            170
#define LCD_FB_BYTE_PER_PIXEL 2
#define LCD_VIRTUAL_BUF_SIZE   (LCD_WIDTH * LCD_HEIGHT)

///< LVGL porting func
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t s_frameBuffer[2][LCD_VIRTUAL_BUF_SIZE * LCD_FB_BYTE_PER_PIXEL], 32);


void lv_port_disp_init(void)
{
  static lv_disp_draw_buf_t disp_buf;

  lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_VIRTUAL_BUF_SIZE);

  /*-------------------------
    * Initialize your display
    * -----------------------*/
  InitializeLCD();

  /*-----------------------------------
    * Register the display in LittlevGL
    *----------------------------------*/

  static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
  lv_disp_drv_init(&disp_drv);   /*Basic initialization*/

  /*Set the resolution of the display*/
  disp_drv.hor_res = LCD_WIDTH;
  disp_drv.ver_res = LCD_HEIGHT;

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

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

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

static void my_disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
  int16_t w = (area->x2 - area->x1 + 1);
  int16_t h = (area->y2 - area->y1 + 1);
  uint32_t size = w * h * sizeof(lv_color_t);

    // g_lcd_screen.ResetAddrWindow();
  g_lcd_screen.setAddrWindow(area->x1, area->y1, area->x2, area->y2);

  g_lcd_screen.writeData16Dma((uint8_t*)color_p, size);
  lv_disp_flush_ready(disp_drv);
}


void setup_scr_startup(lv_ui *ui){

	//Write codes startup
	ui->startup = lv_obj_create(NULL);
	lv_obj_set_scrollbar_mode(ui->startup, LV_SCROLLBAR_MODE_OFF);

	//Set style for startup. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
	lv_obj_set_style_bg_color(ui->startup, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_color(ui->startup, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->startup, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_opa(ui->startup, 255, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes startup_startup_ip
	ui->startup_startup_ip = lv_label_create(ui->startup);
	lv_obj_set_pos(ui->startup_startup_ip, 23, 19);
	lv_obj_set_size(ui->startup_startup_ip, 278, 32);
	lv_obj_set_scrollbar_mode(ui->startup_startup_ip, LV_SCROLLBAR_MODE_OFF);
	lv_label_set_text(ui->startup_startup_ip, "IP:\n");
	lv_label_set_long_mode(ui->startup_startup_ip, LV_LABEL_LONG_WRAP);

	//Set style for startup_startup_ip. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
	lv_obj_set_style_radius(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->startup_startup_ip, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_color(ui->startup_startup_ip, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->startup_startup_ip, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_opa(ui->startup_startup_ip, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_color(ui->startup_startup_ip, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_opa(ui->startup_startup_ip, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_spread(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_ofs_x(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_ofs_y(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->startup_startup_ip, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->startup_startup_ip, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_letter_space(ui->startup_startup_ip, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_line_space(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->startup_startup_ip, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_left(ui->startup_startup_ip, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_right(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_top(ui->startup_startup_ip, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_bottom(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes startup_startup_name
	ui->startup_startup_name = lv_label_create(ui->startup);
	lv_obj_set_pos(ui->startup_startup_name, 23, 60);
	lv_obj_set_size(ui->startup_startup_name, 172, 32);
	lv_obj_set_scrollbar_mode(ui->startup_startup_name, LV_SCROLLBAR_MODE_OFF);
	lv_label_set_text(ui->startup_startup_name, "Name:");
	lv_label_set_long_mode(ui->startup_startup_name, LV_LABEL_LONG_WRAP);

	//Set style for startup_startup_name. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
	lv_obj_set_style_radius(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->startup_startup_name, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_color(ui->startup_startup_name, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->startup_startup_name, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_opa(ui->startup_startup_name, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_color(ui->startup_startup_name, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_opa(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_spread(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_ofs_x(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_ofs_y(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->startup_startup_name, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->startup_startup_name, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_letter_space(ui->startup_startup_name, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_line_space(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->startup_startup_name, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_left(ui->startup_startup_name, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_right(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_top(ui->startup_startup_name, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_bottom(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes startup_startup_version
	ui->startup_startup_version = lv_label_create(ui->startup);
	lv_obj_set_pos(ui->startup_startup_version, 23, 102);
	lv_obj_set_size(ui->startup_startup_version, 100, 32);
	lv_obj_set_scrollbar_mode(ui->startup_startup_version, LV_SCROLLBAR_MODE_OFF);
	lv_label_set_text(ui->startup_startup_version, "Version:\n");
	lv_label_set_long_mode(ui->startup_startup_version, LV_LABEL_LONG_WRAP);

	//Set style for startup_startup_version. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
	lv_obj_set_style_radius(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_color(ui->startup_startup_version, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_color(ui->startup_startup_version, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_grad_dir(ui->startup_startup_version, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_bg_opa(ui->startup_startup_version, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_width(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_color(ui->startup_startup_version, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_opa(ui->startup_startup_version, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_spread(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_ofs_x(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_shadow_ofs_y(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_color(ui->startup_startup_version, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_font(ui->startup_startup_version, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_letter_space(ui->startup_startup_version, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_line_space(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_text_align(ui->startup_startup_version, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_left(ui->startup_startup_version, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_right(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_top(ui->startup_startup_version, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_pad_bottom(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);

	//Write codes startup_img_1
	ui->startup_img_1 = lv_img_create(ui->startup);
	lv_obj_set_pos(ui->startup_img_1, 281, 8);
	lv_obj_set_size(ui->startup_img_1, 32, 33);
	lv_obj_set_scrollbar_mode(ui->startup_img_1, LV_SCROLLBAR_MODE_OFF);

	//Set style for startup_img_1. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
	lv_obj_set_style_img_recolor(ui->startup_img_1, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_img_recolor_opa(ui->startup_img_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_set_style_img_opa(ui->startup_img_1, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
	lv_obj_add_flag(ui->startup_img_1, LV_OBJ_FLAG_CLICKABLE);
	lv_img_set_src(ui->startup_img_1,&_heart_alpha_32x33);
	lv_img_set_pivot(ui->startup_img_1, 50,50);
	lv_img_set_angle(ui->startup_img_1, 0);

	//Init events for screen
	events_init_startup(ui);
}

Color setting in lv_conf.h
/*====================
  COLOR SETTINGS
 *====================*/

/*Maximal horizontal resolution*/
#define LV_HOR_RES_MAX (320)
#define LV_VER_RES_MAX (170)
#define LV_COLOR_DEPTH 16
#define LV_COLOR_16_SWAP 1
#define LV_COLOR_SCREEN_TRANSP 1
#define LV_COLOR_MIX_ROUND_OFS 64
#define LV_DPI_DEF 100
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00)
#define LV_DRAW_COMPLEX 1
#define LV_SHADOW_CACHE_SIZE 0
#define LV_CIRCLE_CACHE_SIZE 4

#define LV_BIG_ENDIAN_SYSTEM 0
#define LV_ATTRIBUTE_TICK_INC
#define LV_ATTRIBUTE_TIMER_HANDLER
#define LV_ATTRIBUTE_FLUSH_READY
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 64

#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1

Screenshot and/or video

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

primary search trouble here

Hi, Marian_M
Thanks a lot. It caused by incorrect handling of color data inside the SPI transfer function. Now it worked.