Corrupted display stm32h743 when trying to optimize performance

Description

Corrupted display stm32h743 when trying to optimize performance

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

nucleo h743zi2
arduino ide
lcd 3.97inch 800x480 nt35510

What LVGL version are you using?

8.1.0

What do you want to achieve?

Error free display, optimized speed

What have you tried so far?

I’m working on piece of multifunctional test equipment, performance was sluggisch so i looked at the fps and cpu load, 33fps and close to 100% cpu load.
The touch screen routine seems to take about half of the load so i disabled that, when doing basically nothing cpu load was still up to 50%.

I eliminated as much as possible from my program including touch because that is taking a large portion of the cpu load in an attempt to find out why i have a high cpu load, code below is the core including display drivers,
Just a basic screen with one button and a number that counts up to get some action on the display.
I now get 0-1% cpu load which is great but the screen is distorted, the counter is not updated and next to it are random lines probably the counter updates. I get the same with the original code but with touch routines remarked out. So something in the touch screen routine makes it work.
I had this line in the touch driver:
lv_obj_invalidate(lv_scr_act());
If i add it to the loop, i dont get a corrupted screen but high cpu load, 50-60% instead of 0-1.
Second screen shows the project with the invalidate line remmed out, touch enabled, the voltage reading is not updated and a flickering block of lines are next to it.

Why would the invalidate call “make it work”?
I hate to use it because it increases the cpu load.

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:




#include <SPI.h>
#include <lvgl.h>



#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0

#include "STM32TimerInterrupt.h"
#include "STM32_ISR_Timer.h"

#define TIMER_INTERVAL_MS         5
#define HW_TIMER_INTERVAL_MS      3


// LCD driver start
typedef int32_t  s32;
typedef int16_t s16;
typedef int8_t  s8;

typedef const int32_t sc32;
typedef const int16_t sc16;
typedef const int8_t sc8;

typedef __IO int32_t  vs32;
typedef __IO int16_t  vs16;
typedef __IO int8_t   vs8;

typedef __I int32_t vsc32;
typedef __I int16_t vsc16;
typedef __I int8_t vsc8;

typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;

typedef const uint32_t uc32;
typedef const uint16_t uc16;
typedef const uint8_t uc8;

typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;

typedef __I uint32_t vuc32;
typedef __I uint16_t vuc16;
typedef __I uint8_t vuc8;

#define ON  1
#define OFF 0

static u32 fac_us = 0;

typedef struct
{
  u16 width;
  u16 height;
  u16 id;
  u8  dir;
  u16  wramcmd;
  u16  rramcmd;
  u16  setxcmd;
  u16  setycmd;
} _lcd_dev;

//#define USE_HORIZONTAL      1
#define LCD_H 480
#define LCD_W 800

#define LCD_REGION_NUMBER   MPU_REGION_NUMBER0
#define LCD_ADDRESS_START   (0X60000000)
#define LCD_REGION_SIZE     MPU_REGION_SIZE_256MB
#define LCD_RST   8         //         PB8
#define LCD_RST_SET() HAL_GPIO_WritePin(GPIOB,1<<LCD_RST ,GPIO_PIN_SET)//GPIO_TYPE->BSRRL=1<<LCD_LED                      
#define LCD_RST_CLR() HAL_GPIO_WritePin(GPIOB,1<<LCD_RST,GPIO_PIN_RESET)

typedef struct
{
  vu16 LCD_REG;
  vu16 LCD_RAM;
} LCD_TypeDef;

#define LCD_BASE        ((u32)(0x60000000 | 0x0007FFFE))
#define LCD             ((LCD_TypeDef *) LCD_BASE)

SRAM_HandleTypeDef SRAM_Handler;
_lcd_dev lcddev;

u16 POINT_COLOR = 0x0000, BACK_COLOR = 0xFFFF;
u16 DeviceCode;

// LCD driver end



TIM_HandleTypeDef htim2;

static uint32_t HAL_RCC_ADC12_CLK_ENABLED = 0;


#define LVGL_TICK_PERIOD 2

// general

unsigned long loop_timer;
unsigned long test_timer;


lv_obj_t *lbl_mv_value;

byte testcount = 0;

// Init STM32 timer TIM1
STM32Timer ITimer(TIM1);

// Init STM32_ISR_Timer
// Each STM32_ISR_Timer can service 16 different ISR-based timers
STM32_ISR_Timer ISR_Timer;

void TimerHandler()
{
  ISR_Timer.run();
}

void handle_timer_int()
{
  lv_tick_inc(LVGL_TICK_PERIOD);
}



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);
  uint32_t h = (area->y2 - area->y1);
  LCD_SetWindows(area->x1, area->y1, w, h);
  int32_t x;
  int32_t y;
  for (y = area->y1; y <= area->y2; y++) {
    for (x = area->x1; x <= area->x2; x++) {
      LCD->LCD_RAM = color_p->full;
      //   Lcd_WriteData_16Bit(color_p->full);
      color_p++;
    }
  }
  lv_disp_flush_ready(disp);
}

void my_touchpad_read(lv_indev_drv_t * indev, lv_indev_data_t * data)
{


}



static lv_obj_t *tabview;

void setup() {

  // setup LCD start
  SCB_EnableICache();
  SCB_DisableDCache();
  HAL_Init();
  Stm32_Clock_Init(120, 1, 2, 2);
  delay_init(400);
  LCD_Init();
  // setup LCD end

  MX_DMA_Init();
  MX_TIM2_Init();



  SPI.setMOSI(PB5);
  SPI.setMISO(PA6);
  SPI.setSCLK(PA5);

  SPI.begin();
  SPI.setClockDivider(128);



  lv_init();

  static lv_disp_draw_buf_t draw_buf;
  static lv_color_t buf1[800 * 480 / 10];                        /*Declare a buffer for 1/10 screen size*/
  lv_disp_draw_buf_init(&draw_buf, buf1, NULL, (800 * 480 / 10));  /*Initialize the display buffer.*/

  static 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.draw_buf = &draw_buf;          /*Assign the buffer to the display*/
  disp_drv.hor_res = 800;   /*Set the horizontal resolution of the display*/
  disp_drv.ver_res = 480;   /*Set the verizontal resolution of the display*/
  lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/

  static 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*/

  // Interval in microsecs
  ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler);
  // interval msec
  ISR_Timer.setInterval(3,  handle_timer_int);

  setupscreens();

  HAL_TIM_Base_Start(&htim2);

  __HAL_RCC_D2SRAM1_CLK_ENABLE();
  __HAL_RCC_D2SRAM2_CLK_ENABLE();
  __HAL_RCC_D2SRAM3_CLK_ENABLE();

  loop_timer = millis();
  test_timer = millis();
  lv_label_set_text(lbl_mv_value, "9");
}

void loop() {
  if (millis() - test_timer > 30) {
    switch (testcount) {
      case 0:
        lv_label_set_text(lbl_mv_value, "0");
        break;
      case 1:
        lv_label_set_text(lbl_mv_value, "1");
        break;
      case 2:
        lv_label_set_text(lbl_mv_value, "2");
        break;
      case 3:
        lv_label_set_text(lbl_mv_value, "3");
        break;
    }
    testcount++;
    if (testcount > 3) {
      testcount = 0;
    }

    //   lv_obj_invalidate(lv_scr_act());


    test_timer = millis();
  }

  if (millis() - loop_timer >= 5) {
    lv_task_handler(); /* let the GUI do its work */
    loop_timer = millis();
  }
}

void setupscreens(void) {
  lv_obj_t * label;
  // tabs
  tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 0);
  lv_obj_t *tabmain = lv_tabview_add_tab(tabview, "");
  lv_obj_set_style_bg_color (tabmain, lv_color_white(), LV_PART_MAIN | LV_STATE_DEFAULT );
  lv_obj_set_style_bg_opa( tabmain, LV_OPA_COVER , LV_PART_MAIN | LV_STATE_DEFAULT);

  lv_obj_clear_flag(tabview, LV_OBJ_FLAG_SCROLLABLE);

  static lv_style_t style12;
  lv_style_set_text_color(&style12,  lv_color_white());
  lv_style_set_text_font(&style12,  &lv_font_montserrat_28);

  // main screen
  lbl_mv_value = lv_label_create(tabmain);
  lv_obj_align(lbl_mv_value, LV_ALIGN_TOP_LEFT, 200, 200);

  lv_obj_t * btn1 = lv_btn_create(tabmain);
  // lv_obj_add_event_cb(btn1, event_sigtracerscr, LV_EVENT_ALL, NULL);
  lv_obj_align(btn1, LV_ALIGN_TOP_LEFT, 10, 0);
  label = lv_label_create(btn1);
  lv_label_set_text(label, "Button 1");
  lv_obj_add_style(label, &style12, 0);
  lv_obj_center(label);
  lv_obj_set_width(btn1, 200);
  lv_obj_set_height(btn1, 110);

}



// LCD routines start
void Stm32_Clock_Init(u32 plln, u32 pllm, u32 pllp, u32 pllq)
{
  HAL_StatusTypeDef ret = HAL_OK;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

  RCC_OscInitStruct.PLL.PLLN = plln;
  RCC_OscInitStruct.PLL.PLLM = pllm;
  RCC_OscInitStruct.PLL.PLLP = pllp;
  RCC_OscInitStruct.PLL.PLLQ = pllq;

  RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
  ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | \
                                 RCC_CLOCKTYPE_HCLK | \
                                 RCC_CLOCKTYPE_D1PCLK1 | \
                                 RCC_CLOCKTYPE_PCLK1 | \
                                 RCC_CLOCKTYPE_PCLK2 | \
                                 RCC_CLOCKTYPE_D3PCLK1);

  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV4;
  ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
  if (ret != HAL_OK) while (1);

  __HAL_RCC_CSI_ENABLE() ;
  __HAL_RCC_SYSCFG_CLK_ENABLE() ;
  HAL_EnableCompensationCell();

  // test voor adc
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
  /** Initializes the peripherals clock
  */
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInitStruct.PLL2.PLL2M = 1;
  PeriphClkInitStruct.PLL2.PLL2N = 18;
  PeriphClkInitStruct.PLL2.PLL2P = 2;
  PeriphClkInitStruct.PLL2.PLL2Q = 2;
  PeriphClkInitStruct.PLL2.PLL2R = 2;
  PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3;
  PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM;
  PeriphClkInitStruct.PLL2.PLL2FRACN = 6144;
  PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

}

void delay_init(u16 SYSCLK)
{
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  fac_us = SYSCLK;
}

void delay_us(u32 nus)
{
  u32 ticks;
  u32 told, tnow, tcnt = 0;
  u32 reload = SysTick->LOAD;
  ticks = nus * fac_us;
  told = SysTick->VAL;
  while (1)
  {
    tnow = SysTick->VAL;
    if (tnow != told)
    {
      if (tnow < told)tcnt += told - tnow;
      else tcnt += reload - tnow + told;
      told = tnow;
      if (tcnt >= ticks)break;
    }
  };
}

void delay_ms(u16 nms)
{
  u32 i;
  for (i = 0; i < nms; i++) delay_us(1000);
}

u16 LCD_read(void)
{
  vu16 data;
  data = LCD->LCD_RAM;
  return data;
}

/*****************************************************************************
   @name       :void LCD_WR_REG(u16 data)
    @function   :Write an 16-bit command to the LCD screen
   @parameters :data:Command value to be written
   @retvalue   :None
******************************************************************************/
void LCD_WR_REG(vu16 data)
{
  data = data;
  LCD->LCD_REG = data;
}

/*****************************************************************************
   @name       :void LCD_WR_DATA(u16 data)
   @function   :Write an 16-bit data to the LCD screen
   @parameters :data:data value to be written
   @retvalue   :None
******************************************************************************/
void LCD_WR_DATA(vu16 data)
{
  data = data;
  LCD->LCD_RAM = data;
}

/*****************************************************************************
   @name       :u16 LCD_RD_DATA(void)
   @function   :Read an 16-bit value from the LCD screen
   @parameters :None
   @retvalue   :read value
******************************************************************************/
u16 LCD_RD_DATA(void)
{
  return LCD_read();
}

/*****************************************************************************
   @name       :void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)
   @function   :Write data into registers
   @parameters :LCD_Reg:Register address
                LCD_RegValue:Data to be written
   @retvalue   :None
******************************************************************************/
void LCD_WriteReg(u16 LCD_Reg, u16 LCD_RegValue)
{
  LCD->LCD_REG = LCD_Reg;
  LCD->LCD_RAM = LCD_RegValue;
}

/*****************************************************************************
   @name       :void LCD_ReadReg(u16 LCD_Reg,u16 *Rval,int n)
   @function   :read value from specially registers
   @parameters :LCD_Reg:Register address
   @retvalue   :read value
******************************************************************************/
void LCD_ReadReg(u16 LCD_Reg, u16 * Rval, int n)
{
  LCD_WR_REG(LCD_Reg);
  while (n--)
  {
    *(Rval++) = LCD_RD_DATA();
    delay_us(5);
  }
}

/*****************************************************************************
   @name       :void LCD_WriteRAM_Prepare(void)
   @function   :Write GRAM
   @parameters :None
   @retvalue   :None
******************************************************************************/
void LCD_WriteRAM_Prepare(void)
{
  LCD_WR_REG(lcddev.wramcmd);
}

/*****************************************************************************
   @name       :void LCD_ReadRAM_Prepare(void)
   @function   :Read GRAM
   @parameters :None
   @retvalue   :None
******************************************************************************/
void LCD_ReadRAM_Prepare(void)
{
  LCD_WR_REG(lcddev.rramcmd);
}

/*****************************************************************************
   @name       :void Lcd_WriteData_16Bit(u16 Data)
   @function   :Write an 16-bit command to the LCD screen
   @parameters :Data:Data to be written
   @retvalue   :None
******************************************************************************/
void Lcd_WriteData_16Bit(u16 Data)
{
  LCD->LCD_RAM = Data;
}

u16 Color_To_565(u8 r, u8 g, u8 b)
{
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xF8) >> 3);
}

/*****************************************************************************
   @name       :u16 Lcd_ReadData_16Bit(void)
   @function   :Read an 16-bit value from the LCD screen
   @parameters :None
   @retvalue   :read value
******************************************************************************/
u16 Lcd_ReadData_16Bit(void)
{
  u16 r, g, b;
  //dummy data
  r = LCD_RD_DATA();
  delay_us(1);
  //16bit:red and green data
  r = LCD_RD_DATA();
  delay_us(1);
  //16bit:blue data
  g = LCD_RD_DATA();
  b = g >> 8;
  g = r & 0xFF;
  r = r >> 8;
  return Color_To_565(r, g, b);
}



/*****************************************************************************
   @name       :void LCD_Clear(u16 Color)
   @function   :Full screen filled LCD screen
   @parameters :color:Filled color
   @retvalue   :None
******************************************************************************/
void LCD_Clear(u16 Color)
{
  unsigned int i;
  u32 total_point = lcddev.width * lcddev.height;
  LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1);
  for (i = 0; i < total_point; i++)
  {
    LCD->LCD_RAM = Color;
  }
}

/*****************************************************************************
   @name       :void LCD_MPU_Config(void)
   @function   :Configure the region of the MPU, and configure
                the external SRAM area to be in write-through mode.
   @parameters :None
   @retvalue   :None
******************************************************************************/
void LCD_MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_Initure;

  HAL_MPU_Disable();
  MPU_Initure.Enable = MPU_REGION_ENABLE;
  MPU_Initure.Number = LCD_REGION_NUMBER;
  MPU_Initure.BaseAddress = LCD_ADDRESS_START;
  MPU_Initure.Size = LCD_REGION_SIZE;
  MPU_Initure.SubRegionDisable = 0X00;
  MPU_Initure.TypeExtField = MPU_TEX_LEVEL0;
  MPU_Initure.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_Initure.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_Initure.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_Initure.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_Initure.IsBufferable = MPU_ACCESS_BUFFERABLE;
  HAL_MPU_ConfigRegion(&MPU_Initure);
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*****************************************************************************
   @name       :void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram)
   @function   :SRAM underlying driver, clock enable, pin assignment
                This function will be called by HAL_SRAM_Init ()
   @parameters :hsram:SRAM handle
   @retvalue   :None
******************************************************************************/
void HAL_SRAM_MspInit(SRAM_HandleTypeDef * hsram)
{
  GPIO_InitTypeDef GPIO_Initure;

  __HAL_RCC_FMC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();

  //PD0,1,4,5,7,8,9,10,13,14,15
  GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7 | GPIO_PIN_8 | \
                     GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
  GPIO_Initure.Mode = GPIO_MODE_AF_PP;  //¸´ÓÃ
  GPIO_Initure.Pull = GPIO_PULLUP;    //ÉÏÀ­
  GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; //¸ßËÙ
  GPIO_Initure.Alternate = GPIO_AF12_FMC; //¸´ÓÃΪFMC
  HAL_GPIO_Init(GPIOD, &GPIO_Initure);

  //PE7,8,9,10,11,12,13,14,15
  GPIO_Initure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \
                     GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
  HAL_GPIO_Init(GPIOE, &GPIO_Initure);
}

/*****************************************************************************
   @name       :void LCD_GPIOInit(void)
   @date       :2018-08-09
   @function   :Initialization LCD screen GPIO
   @parameters :None
   @retvalue   :None
******************************************************************************/
void LCD_GPIOInit(FMC_NORSRAM_TimingTypeDef FWT)
{
  GPIO_InitTypeDef GPIO_Initure;
  FMC_NORSRAM_TimingTypeDef FSMC_ReadWriteTim;
  //    FMC_NORSRAM_TimingTypeDef FSMC_WriteTim;
  __HAL_RCC_GPIOB_CLK_ENABLE();     //¿ªÆôGPIOBʱÖÓ
  GPIO_Initure.Pin = GPIO_PIN_5 | GPIO_PIN_8;        //PB5,±³¹â¿ØÖÆ PB8,¸´Î»
  GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; //ÍÆÍìÊä³ö
  GPIO_Initure.Pull = GPIO_PULLUP;        //ÉÏÀ­
  GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  //¸ßËÙ
  HAL_GPIO_Init(GPIOB, &GPIO_Initure);


  LCD_MPU_Config();
  SRAM_Handler.Instance = FMC_NORSRAM_DEVICE; //BANK1
  SRAM_Handler.Extended = FMC_NORSRAM_EXTENDED_DEVICE;

  SRAM_Handler.Init.NSBank = FMC_NORSRAM_BANK1;   //ʹÓÃNE1
  SRAM_Handler.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; //²»¸´     ÓÃÊý¾ÝÏß
  SRAM_Handler.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;            //SRAM
  SRAM_Handler.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; //16λÊý¾Ý¿í¶È
  SRAM_Handler.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; //ÊÇ·ñʹÄÜÍ»·¢·ÃÎÊ,½ö¶Ôͬ²½Í»·¢´æ´¢Æ÷ÓÐЧ,´Ë´¦Î´Óõ½
  SRAM_Handler.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; //µÈ´ýÐźŵļ«ÐÔ,½öÔÚÍ»·¢Ä£Ê½·ÃÎÊÏÂÓÐÓÃ
  SRAM_Handler.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; //´æ´¢Æ÷ÊÇÔڵȴýÖÜÆÚ֮ǰµÄÒ»¸öʱÖÓÖÜÆÚ»¹ÊǵȴýÖÜÆÚÆÚ¼äʹÄÜNWAIT
  SRAM_Handler.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;  //´æ´¢Æ÷дʹÄÜ
  SRAM_Handler.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;         //µÈ´ýʹÄÜλ,´Ë´¦Î´Óõ½
  SRAM_Handler.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE;      //¶ÁдʹÓò»Í¬µÄʱÐò
  SRAM_Handler.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; //ÊÇ·ñʹÄÜͬ²½´«ÊäģʽϵĵȴýÐźÅ,´Ë´¦Î´Óõ½
  SRAM_Handler.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;         //½ûֹͻ·¢Ð´
  SRAM_Handler.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC;

  //FSMC
  FSMC_ReadWriteTim.AddressSetupTime = 0x11;  //µØÖ·½¨Á¢Ê±¼ä(ADDSET)Ϊ17¸öHCLK 1/216M=4.6ns*17=78ns
  FSMC_ReadWriteTim.AddressHoldTime = 0x00;
  FSMC_ReadWriteTim.DataSetupTime = 0x55;     //Êý¾Ý±£´æʱ¼ä(DATAST)Ϊ85¸öHCLK  =4.6*85=391ns
  FSMC_ReadWriteTim.AccessMode = FMC_ACCESS_MODE_A; //ģʽA
  //FSMC
  FWT.AddressSetupTime = 0x15;
  FWT.AddressHoldTime = 0x00;
  FWT.DataSetupTime = 0x15;
  FWT.AccessMode = FMC_ACCESS_MODE_A;   //ģʽA

  HAL_SRAM_Init(&SRAM_Handler, &FSMC_ReadWriteTim, &FWT);

}

void LCD_FSMC_Write_Time_Set(FMC_NORSRAM_TimingTypeDef FWT, uint32_t AST, uint32_t DST)
{
  //  FMC_NORSRAM_TimingTypeDef FSMC_WriteTim;
  FWT.AddressSetupTime = AST;
  FWT.DataSetupTime = DST;
  FMC_NORSRAM_Extended_Timing_Init(SRAM_Handler.Extended, &FWT, SRAM_Handler.Init.NSBank, SRAM_Handler.Init.ExtendedMode);
}

/*****************************************************************************
   @name       :void LCD_RESET(void)
   @function   :Reset LCD screen
   @parameters :None
   @retvalue   :None
******************************************************************************/
void LCD_RESET(void)
{
  LCD_RST_CLR();
  delay_ms(100);
  LCD_RST_SET();
  delay_ms(50);
}

 




Screenshot and/or video

I managed to get the cpu load down by optimizing my code a bit and removing delays out of the touch screen code, still no solution to the garbled screen when screen is not invalidated

Problem solved!
Kicking myself for not finding it earlier, the lcd windows routine needs start and end coordinates, the flush routine supplied start and dimensions.
With an invalidation of the screen these match but not with partial redraws.

This line fixed that:
LCD_SetWindows(area->x1, area->y1, area->x2, area->y2);