Littlevgl STM32F429 ILI9341 Rotate Landscape Solved

STM32F429-DISC1 evalboard
littlevgl/lvgl/releases/tag/v6.0

See how I have fixed the rotation screen problem on my STM32F429 with littlevgl.

As many other folks in this community, I tried to rotate my STM32F429 TFT for landscape and I have almost encountered about all the problems reported on the web for this topic.Finally I have managed to fix all the issues, this information is provided as is without warranty of any kind, it is your responsibility to test and validate all the changes provided in this blog for your application.
Have fun …

Four steps:
1-ILI9341 configuration
2-STM32 LTDC configuration
3-Littlevgl Parameters
4-Littlevgl touchpad (to match new landscape orientaion)


Step 1- First TFT configuration Landscape (SF-TC240T-9370A-T-Saef with ILI9341)
/hal_stm_lvgl/tft/ili9341.c

void ili9341_Init(void)
{
  /* Initialize ILI9341 low level bus layer
  LCD_IO_Init();
  
  // software reset
  ili9341_WriteReg(LCD_SWRESET);

  // display out of sleep mode
  ili9341_WriteReg(LCD_SLEEP_OUT);

  ili9341_WriteReg(LCD_RGB_INTERFACE); // RGB Interface Signal Control
  ili9341_WriteData(0xC0); // ByPass_MODE = 1, RCM [1:0] = "10" (RGB Mode = DE mode)

  ili9341_WriteReg(LCD_INTERFACE);
  ili9341_WriteData(0x01); // WEMODE = 0 => avoid white triangles
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x02); //RM = 1 (Interface for RAM Access = RGB interface)

  // set memory access control
  ili9341_WriteReg(LCD_MAC);
  // Next EVB Top view, USB-LINK is on the right
  ili9341_WriteData(0x68);
  // Next EVB Top view, USB-LINK is on the left
  // Must also modify touchpad file to match this new position
  //ili9341_WriteData(0xA8);  

  // Column address set
  ili9341_WriteReg(LCD_COLUMN_ADDR);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x00); 
  ili9341_WriteData(0x01); 
  ili9341_WriteData(0x40); 

  // Page address set
  // Makes height on screen to 240 in landscape
  ili9341_WriteReg(LCD_PAGE_ADDR);
  ili9341_WriteData(0x00); 
  ili9341_WriteData(0x00); 
  ili9341_WriteData(0x00);
  ili9341_WriteData(0xF0); 

  // set frame rate control
  ili9341_WriteReg(LCD_FRMCTR1);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x1B);

  ili9341_WriteReg(LCD_WRITE_MEM_CONTINUE);
  ili9341_WriteData(0x10);
  ili9341_WriteData(0x10);
  ili9341_WriteData(0x10);

  // set display function control
  ili9341_WriteReg(LCD_DFC);
  ili9341_WriteData(0x0A);
  ili9341_WriteData(0xA7);
  ili9341_WriteData(0x27);
  ili9341_WriteData(0x04);

  // select pixel data format
  ili9341_WriteReg(LCD_PIXEL_FORMAT);
  ili9341_WriteData(0x66);

  // configure RGB interface
  ili9341_WriteReg(LCD_RGB_INTERFACE);
  ili9341_WriteData(0xC2);

  // enable display
  ili9341_WriteReg(LCD_DISPLAY_ON);

  // delay
  HAL_Delay(120);

  // select RGB interface
  ili9341_WriteReg(LCD_INTERFACE);
  ili9341_WriteData(0x00);  
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x06);

2-STM32 LTDC configuration
/hal_stm_lvgl/tft/tft.c

static void LCD_Config(void)
{
  LTDC_LayerCfgTypeDef pLayerCfg;

  /* Initialization of ILI9341 component*/
  ili9341_Init();

  /* LTDC Initialization ----------------------------------------------*/

  /* Polarity configuration */
  /* Initialize the horizontal synchronization polarity as active low */
  LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
  /* Initialize the vertical synchronization polarity as active low */
  LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AL;
  /* Initialize the data enable polarity as active low */
  LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
  /* Initialize the pixel clock polarity as input pixel clock */
  LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;

  #define TFT_HSYNC		0x7
  #define TFT_HBP			0x12
  #define TFT_HAWIDTH	0x140
  #define TFT_HFP			0x10

  #define TFT_VSYNC		0x2
  #define TFT_VBP			0x8
  #define TFT_VAWIDTH	0x140
  #define TFT_VFP			0x04

  #define HSW				(TFT_HSYNC - 1)
  #define AHBP 			(TFT_HSYNC + TFT_HBP -1)
  #define AAW 				(TFT_HSYNC + TFT_HBP + TFT_HAWIDTH - 1)
  #define TOTALW 			(TFT_HSYNC + TFT_HBP + TFT_HAWIDTH + TFT_HFP - 1)

  #define VSH 				(TFT_VSYNC - 1)
  #define AVPB 			(TFT_VSYNC + TFT_VBP - 1)
  #define AAH  			(TFT_VSYNC + TFT_VBP + TFT_VAWIDTH - 1)
  #define TOTALH 			(TFT_VSYNC + TFT_VBP + TFT_VAWIDTH + TFT_VFP - 1)


  /* Horizontal synchronization width = Hsync - 1 */
  LtdcHandle.Init.HorizontalSync = HSW;
  /* Vertical synchronization height = Vsync - 1 */
  LtdcHandle.Init.VerticalSync = VSH;
  /* Accumulated horizontal back porch = Hsync + HBP - 1 */
  LtdcHandle.Init.AccumulatedHBP = AHBP; 
  /* Accumulated vertical back porch = Vsync + VBP - 1 */
  LtdcHandle.Init.AccumulatedVBP = AVPB; 
  /* Accumulated active width = Hsync + HBP + Active Width - 1 */
  LtdcHandle.Init.AccumulatedActiveW = AAW;  
  /* Accumulated active height = Vsync + VBP + Active Height - 1 */
  LtdcHandle.Init.AccumulatedActiveH = AAH;  
  /* Total width = Hsync + HBP + Active Width + HFP - 1 */
  LtdcHandle.Init.TotalWidth = TOTALW;
  /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
  LtdcHandle.Init.TotalHeigh = TOTALH;

  /* Configure R,G,B component values for LCD background color */
  LtdcHandle.Init.Backcolor.Blue = 0;
  LtdcHandle.Init.Backcolor.Green = 0;
  LtdcHandle.Init.Backcolor.Red = 0;

  LtdcHandle.Instance = LTDC;

  /* Layer1 Configuration ------------------------------------------------------*/

  memset((void*)my_fb, 0x1234, TFT_HOR_RES * TFT_VER_RES);
  /* Windowing configuration */
  pLayerCfg.WindowX0 = 0;
  pLayerCfg.WindowX1 = TFT_HOR_RES;
  pLayerCfg.WindowY0 = 0;
  pLayerCfg.WindowY1 = TFT_VER_RES;

  /* Pixel Format configuration*/
  pLayerCfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;

  /* Start Address configuration : frame buffer is located at FLASH memory */
  pLayerCfg.FBStartAdress = (uint32_t)my_fb;

  /* Alpha constant (255 totally opaque) */
  pLayerCfg.Alpha = 255;

  /* Default Color configuration (configure A,R,G,B component values) */
  pLayerCfg.Alpha0 = 0;
  pLayerCfg.Backcolor.Blue = 0;
  pLayerCfg.Backcolor.Green = 0;
  pLayerCfg.Backcolor.Red = 0;

  /* Configure blending factors */
  pLayerCfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
  pLayerCfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;

  /* Configure the number of lines and number of pixels per line */
  pLayerCfg.ImageWidth = TFT_HOR_RES;
  pLayerCfg.ImageHeight = TFT_VER_RES;

  /* Configure the LTDC */
  if(HAL_LTDC_Init(&LtdcHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }

  /* Configure the Background Layer*/
  if(HAL_LTDC_ConfigLayer(&LtdcHandle, &pLayerCfg, 0) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler();
  }
}

3-Littlevgl Parameters
/lvgl/src/-v_conf_template.h

/*====================
   Graphical settings
 *====================*/
#define LV_HOR_RES_MAX   (320) 
#define LV_VER_RES_MAX   (240) 

/lv_conf.h

/*====================
   Graphical settings
 *====================*/
#define LV_HOR_RES_MAX   (320) 
#define LV_VER_RES_MAX   (240) 

/hal_stm_lvgl/tft/tft.h

/*********************
 *      DEFINES
 *********************/
#define TFT_HOR_RES 	320 
#define TFT_VER_RES 		240

4-Littlevgl touchpad
/hal_stm_lvgl/touchpad/touchpad.c

// To comment the next two lines
/* Update the X and Y position */
//*x = _x; // org
//*y = _y;

// For EVB Top view with USB-LINK on the right
*x = 320 - _y;
*y = _x;

// For EVB Top view with USB-LINK on the left
To be done ...

5 Likes

Thank you for sharing! I’m sure a lot of users will be grateful for this! :slight_smile:

1 Like

Any idea how to rotate the display 180 degrees? I have mine in landscape but it’s facing the wrong way. Thanks!

Hi Querist,
Change the line in /hal_stm_lvgl/ili9341.c
from:
ili9341_WriteData(0x68);
to
ili9341_WriteData(0xA8);
and it should be fine as per you are looking for.

Now it is not finish, the display touchpad must also be changed to match the new orientation …
Check the file /hal_stm_lvgl/touchpad/touchpad.c
You will have to change this file and write the code for that, I have not done it…

Thanks for your interest and good luck,

Best regards,
Supergdx

Thanks!
For some reason I didn’t receive an email telling me that you replied. I’ll test this out and let you know how it works.

Interesting - I can’t find that file. I have an ili9341.cpp but I can’t find that directory, either.

I think I found the issue - the only version of LittleVGL I have uses MbedOS. If there is one that will work on an stm32f407 without an OS (since LittlevGL has its own file system mechanism) I’d love to see it so I can reduce the size of my executable.

Hi Querist,

You have to enable a preference in your profil to get automatic update when somebody reply.
I have started with the project STM32F429 provided by Littlevgl without OS. I don’t know
you’re application but if you can run with no OS you will for sure reduce the size of your code.
Good luck,

Supergdx

Thanks,
for now I’ve put the rotating the screen on hold - it’s a minor issue that I can fix later.

Hi @supergdx,

Very interesting solution! I was wondering if you could get rid of the dead pixels in the right bottom corner of the display. It looks like these only appear when rotating to Landscape mode, but not in Portrait (0 or 180), weird! I have tried different timing changes but nothing has worked.

Hi ,
Why did you set both TFT_HAWIDTH and TFT_VAWIDTH as 0x140 (320)?