STM32 Advanced Peripherals : LTDC Part 1: Introduction and Environment Setup

In this new guide series, we shall see the advanced peripheral that being offered by ST. The first part is LTDC which stands for LCD-TFT Display Controller (LTDC).

In this guide, we shall cover the following:

  • What is LTDC.
  • Basic of Embedded Display.
  • Environment Setup.

1. What is LTDC:

The evolution of the mobile, industrial, and consumer applications leads to a stronger need of graphical user interfaces (GUIs) and to an increase in the required hardware resources. These applications require higher quality graphics, more hardware and software resources (like memory for graphical primitives or framebuffer) and higher processing performances.

To respond to this increasing demand, microprocessor units are often used, which leads to a higher costs and to more complex designs with longer time to market. To face these requirements, the STM32 microcontrollers (MCUs) offer a large graphical portfolio.

Thanks to their embedded LCD-TFT display controller (LTDC), the STM32 MCUs allow high-resolution display panels to be directly driven, without any CPU intervention. In addition, the LTDC can access autonomously to internal memories or external memories to fetch pixel data.

Functional description
On every pixel clock-raising edge or clock-falling edge and within the screen active area, the
LTDC layer retrieves one pixel data from its FIFO, converts it to the internal ARGB8888 pixel
format and blends it with the background and/or with the other layer pixel color. The
resulting pixel, coded in the RGB888 format, goes through the dithering unit and is driven
into the RGB interface. The pixel is then displayed on the screen.

2. Basic of Embedded Display:

A basic embedded graphic system schematic is described in the figure below.

A basic embedded graphic system is composed of a microcontroller, a framebuffer, a display controller and a display glass.

• The MCU computes the image to be displayed in the framebuffer, assembling graphical primitives such as icons or images. The CPU performs this operation by running a graphical library software. This process can be accelerated by a dedicated hardware like the DMA2D Chrom-Art Accelerator, used by the graphical library. The more often the framebuffer is updated, the more fluent the animations are (animation fps).

• The framebuffer is a volatile memory used to store pixel data of the image to be displayed. This memory is usually called the graphic RAM (GRAM). The required size of the framebuffer depends on the resolution and color depth of the display.

• The display controller is continuously “refreshing” the display, transferring the framebuffer content to the display glass 60 times per second (60 Hz). The display controller can be embedded either in the display module or in the MCU.

• The display glass is driven by the display controller and is responsible to display the image that is composed of a matrix of pixels.

A display is characterized by:

– Display size (resolution): is defined by the number of pixels of the display that is represented by horizontal (pixels number) x vertical (lines number).

– Color depth: defines the number of colors in which a pixel can be drawn. It is represented in bits per pixel (bpp). For a color depth of 24 bpp (that can also be represented by RGB888) a pixel can be represented in 16777216 colors.

– Refresh rate (in Hz): is the number of times per second that the display panel is refreshed. A display must be refreshed 60 times per seconds (60 Hz) since lower refresh rate creates bad visual effects.

Display module categories

The display modules are classified in two main categories, depending on whether they embed or not an internal controller and a GRAM:

• The first category corresponds to the displays with an on-glass display controller and a GRAM (see the figure below).

• The second category corresponds to the displays with an on-glass display with no main controller and that have only a low-level timing controller.

For more information about LTDC and technology behind the embedded displays, please refer to this application note from ST.

3. Environment Setup:

Before we start adding the required header and source files, we need to setup the environment to work in bare metal by the following this guide here.

The modification is in defining type of STM32 which is:

STM32F429xx

Thats all for the project setup.

Now, create new source file with name of sys_init.c which will initialize the clock during the startup of the MCU.

For more details, please refer to this guide.

In the source file, include the main STM32F4 header file:

#include "stm32f4xx.h"

Declare a function named SystemInit and it contents as following:

void SystemInit (void)
{

	#define PLL_M      4
	#define PLL_N      180
	#define PLL_P      2
	#define PLL_Q      9

	__IO uint32_t StartUpCounter = 0, HSEStatus = 0;


	  RCC->CR |= ((uint32_t)RCC_CR_HSEON);


	  do
	  {
		HSEStatus = RCC->CR & RCC_CR_HSERDY;
		StartUpCounter++;
	  } while((HSEStatus == 0) && (StartUpCounter != 3000));

	  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
	  {
		HSEStatus = (uint32_t)0x01;
	  }
	  else
	  {
		HSEStatus = (uint32_t)0x00;
	  }

	  if (HSEStatus == (uint32_t)0x01)
	  {

		RCC->APB1ENR |= RCC_APB1ENR_PWREN;
		PWR->CR &= (uint32_t)~(PWR_CR_VOS);


		RCC->CFGR |= RCC_CFGR_HPRE_DIV1;


		RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;


		RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;


		RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
					   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);


		RCC->CR |= RCC_CR_PLLON;


		while((RCC->CR & RCC_CR_PLLRDY) == 0)
		{
		}

		/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
		FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

		/* Select the main PLL as system clock source */
		RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
		RCC->CFGR |= RCC_CFGR_SW_PLL;

		/* Wait till the main PLL is used as system clock source */
		while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL)
		{;}
	  }
	  else
	  { /* If HSE fails to start-up, the application will have wrong clock
			 configuration. User can add here some code to deal with this error */
	  }

	  /*Enable FPU*/
	  SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));

	  /*Enable cell compensation*/
	  RCC->APB2ENR|=RCC_APB2ENR_SYSCFGEN ;
	  SYSCFG->CMPCR|=(1<<0);
	  while(!((SYSCFG->CMPCR)&(1<<8))){;}

}

We shall add extra clock configurations later to deal with LTDC.

Now create pair delay.c and delay.h file.

In delay.h:

#ifndef DELAY_H_
#define DELAY_H_

#include "stdint.h"

void delay_init(uint32_t freq);
uint64_t millis();
void delay(uint32_t time);




#endif /* DELAY_H_ */

delay.c:

#include "delay.h"
#include "stm32f4xx.h"



#define	CTRL_ENABLE					(1U<<0)
#define CTRL_CLKSRC					(1U<<2)
#define CTRL_COUNTFLAG				(1U<<16)
#define CTRL_TICKINT				(1U<<1)


volatile uint64_t mil;

void delay_init(uint32_t freq)
{

	SysTick->LOAD  = (freq/1000) - 1;

	/*Clear systick current value register */
	SysTick->VAL = 0;

	/*Enable systick and select internal clk src*/
	SysTick->CTRL = CTRL_ENABLE | CTRL_CLKSRC ;

	/*Enable systick interrupt*/
	SysTick->CTRL  |= CTRL_TICKINT;

}



uint64_t millis()
	{
	__disable_irq();
	uint64_t ml=mil;
	__enable_irq();
	return ml;
	}



void delay(uint32_t time)
{

	uint64_t start=millis();
	while((millis() - start) < (time+1));
}

void SysTick_Handler(void)
{

	mil++;
}

Since we are dealing with the embedded display on STM32F429 discovery, we need to initialize the LCD to work in parallel mode.

First, we need to the LCD itself using SPI command.

First, refer to these two guides:

Create new source pair of source and header file with name of LCD_Pins.c and LCD_Pins.h.

Within the header file:

#ifndef LCD_PINS_H_
#define LCD_PINS_H_

#include "delay.h"
#include "stm32f4xx.h"

#define LCD_RES_HIGH(void)			GPIOA->BSRR=GPIO_BSRR_BS7
#define LCD_RES_LOW(void)			GPIOA->BSRR=GPIO_BSRR_BR7

#define LCD_CS_HIGH(void)			GPIOC->BSRR=GPIO_BSRR_BS2
#define LCD_CS_LOW(void)			GPIOC->BSRR=GPIO_BSRR_BR2

#define LCD_DC_HIGH(void)			GPIOD->BSRR=GPIO_BSRR_BS13
#define LCD_DC_LOW(void)			GPIOD->BSRR=GPIO_BSRR_BR13


/*SPI */
void LCD_Pin_Init(void);
void LCD_SPI_Init(void);

/*LCD*/
void LCD_RST(void);
void LCD_Write_Cmd(uint8_t cmd);
void LCD_Write_Data (uint8_t data);


#endif /* LCD_PINS_H_ */

Within the source file:

#include "stm32f4xx.h"
#include "LCD_Pins.h"

#define AF05						0x05






void LCD_Pin_Init(void)
{
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN|RCC_AHB1ENR_GPIOCEN|RCC_AHB1ENR_GPIODEN|RCC_AHB1ENR_GPIOFEN;

	/*PA7*/
	GPIOA->MODER|=GPIO_MODER_MODE7_0;
	GPIOA->MODER&=~GPIO_MODER_MODE7_1;
	GPIOA->OSPEEDR|=GPIO_OSPEEDR_OSPEED7;
	GPIOA->ODR|=GPIO_ODR_OD7;

	/*PC2*/
	GPIOC->MODER|=GPIO_MODER_MODE2_0;
	GPIOC->MODER&=~GPIO_MODER_MODE2_1;
	GPIOC->OSPEEDR|=GPIO_OSPEEDR_OSPEED2;
	GPIOC->ODR|=GPIO_ODR_OD2;



	/*PD13*/
	GPIOD->MODER|=GPIO_MODER_MODE13_0;
	GPIOD->MODER&=~GPIO_MODER_MODE13_1;
	GPIOD->OSPEEDR|=GPIO_OSPEEDR_OSPEED13;
	GPIOD->ODR|=GPIO_ODR_OD13;

	/*PF7 and PF9 for SPI5*/

	GPIOF->MODER|=GPIO_MODER_MODE7_1|GPIO_MODER_MODE9_1;
	GPIOF->MODER&=~(GPIO_MODER_MODE7_0|GPIO_MODER_MODE9_0);

	GPIOF->OSPEEDR|=GPIO_OSPEEDR_OSPEED7|GPIO_OSPEEDR_OSPEED9;

	GPIOF->AFR[0]|=(AF05<<GPIO_AFRL_AFSEL7_Pos);
	GPIOF->AFR[1]|=(AF05<<GPIO_AFRH_AFSEL9_Pos);


}


void LCD_SPI_Init(void)
{
	RCC->APB2ENR|=RCC_APB2ENR_SPI5EN;
	SPI5->CR1|=SPI_CR1_MSTR|SPI_CR1_SSM|SPI_CR1_SSI|SPI_CR1_BR_2|SPI_CR1_BR_1|SPI_CR1_BR_0;

	SPI5->CR1|=SPI_CR1_SPE;

}


static void spi5_transmit(uint8_t data)
{

	/*Wait until TXE is set*/
	while(!(SPI5->SR & (SPI_SR_TXE))){}

	/*Write the data to the data register*/
	SPI5->DR = data;


	/*Wait until TXE is set*/
	while(!(SPI5->SR & (SPI_SR_TXE))){}

	/*Wait for BUSY flag to reset*/
	while((SPI5->SR & (SPI_SR_BSY))){}

	/*Clear OVR flag*/
	(void) SPI5->DR;
	(void) SPI5->SR;
}


void LCD_RST(void)
{
	LCD_RES_LOW();
	delay(50);
	LCD_RES_HIGH();
	delay(20);

}





void LCD_Write_Cmd(uint8_t cmd)
{
	LCD_CS_LOW();
	LCD_DC_LOW();
	spi5_transmit(cmd);
	LCD_CS_HIGH();
}


void LCD_Write_Data (uint8_t data)
{
	LCD_CS_LOW();
	LCD_DC_HIGH();
	spi5_transmit (data);
	LCD_CS_HIGH();
}

Now, we create new pair of source and header file with name of ILI9341.c and ILI9341.h

Within the header file:

#ifndef ILI9341_H_
#define ILI9341_H_

//List of includes

#include "delay.h"


//LCD dimensions defines
#define ILI9341_WIDTH       320
#define ILI9341_HEIGHT      240


#define ILI9341_PIXEL_COUNT	ILI9341_WIDTH * ILI9341_HEIGHT


#define  ILI9341_HSYNC            ((uint32_t)9)   /* Horizontal synchronization */
#define  ILI9341_HBP              ((uint32_t)29)    /* Horizontal back porch      */
#define  ILI9341_HFP              ((uint32_t)2)    /* Horizontal front porch     */
#define  ILI9341_VSYNC            ((uint32_t)1)   /* Vertical synchronization   */
#define  ILI9341_VBP              ((uint32_t)3)    /* Vertical back porch        */
#define  ILI9341_VFP              ((uint32_t)2)    /* Vertical front porch       */

/**
  * @brief  ILI9341 Registers
  */

/* Level 1 Commands */
/* Level 1 Commands */
#define ILI9341_SWRESET             0x01U   /* Software Reset */
#define ILI9341_READ_DISPLAY_ID     0x04U   /* Read display identification information */
#define ILI9341_RDDST               0x09U   /* Read Display Status */
#define ILI9341_RDDPM               0x0AU   /* Read Display Power Mode */
#define ILI9341_RDDMADCTL           0x0BU   /* Read Display MADCTL */
#define ILI9341_RDDCOLMOD           0x0CU   /* Read Display Pixel Format */
#define ILI9341_RDDIM               0x0DU   /* Read Display Image Format */
#define ILI9341_RDDSM               0x0EU   /* Read Display Signal Mode */
#define ILI9341_RDDSDR              0x0FU   /* Read Display Self-Diagnostic Result */
#define ILI9341_SPLIN               0x10U   /* Enter Sleep Mode */
#define ILI9341_SLEEP_OUT           0x11U   /* Sleep out register */
#define ILI9341_PTLON               0x12U   /* Partial Mode ON */
#define ILI9341_NORMAL_MODE_ON      0x13U   /* Normal Display Mode ON */
#define ILI9341_DINVOFF             0x20U   /* Display Inversion OFF */
#define ILI9341_DINVON              0x21U   /* Display Inversion ON */
#define ILI9341_GAMMA               0x26U   /* Gamma register */
#define ILI9341_DISPLAY_OFF         0x28U   /* Display off register */
#define ILI9341_DISPLAY_ON          0x29U   /* Display on register */
#define ILI9341_CASET               0x2AU   /* Column address register */
#define ILI9341_RASET               0x2BU   /* Page address register */
#define ILI9341_GRAM                0x2CU   /* GRAM register */
#define ILI9341_RGBSET              0x2DU   /* Color SET */
#define ILI9341_RAMRD               0x2EU   /* Memory Read */
#define ILI9341_PLTAR               0x30U   /* Partial Area */
#define ILI9341_VSCRDEF             0x33U   /* Vertical Scrolling Definition */
#define ILI9341_TEOFF               0x34U   /* Tearing Effect Line OFF */
#define ILI9341_TEON                0x35U   /* Tearing Effect Line ON */
#define ILI9341_MAC                 0x36U   /* Memory Access Control register*/
#define ILI9341_VSCRSADD            0x37U   /* Vertical Scrolling Start Address */
#define ILI9341_IDMOFF              0x38U   /* Idle Mode OFF */
#define ILI9341_IDMON               0x39U   /* Idle Mode ON */
#define ILI9341_PIXEL_FORMAT        0x3AU   /* Pixel Format register */
#define ILI9341_WRITE_MEM_CONTINUE  0x3CU   /* Write Memory Continue */
#define ILI9341_READ_MEM_CONTINUE   0x3EU   /* Read Memory Continue */
#define ILI9341_SET_TEAR_SCANLINE   0x44U   /* Set Tear Scanline */
#define ILI9341_GET_SCANLINE        0x45U   /* Get Scanline */
#define ILI9341_WDB                 0x51U   /* Write Brightness Display register */
#define ILI9341_RDDISBV             0x52U   /* Read Display Brightness */
#define ILI9341_WCD                 0x53U   /* Write Control Display register*/
#define ILI9341_RDCTRLD             0x54U   /* Read CTRL Display */
#define ILI9341_WRCABC              0x55U   /* Write Content Adaptive Brightness Control */
#define ILI9341_RDCABC              0x56U   /* Read Content Adaptive Brightness Control */
#define ILI9341_WRITE_CABC          0x5EU   /* Write CABC Minimum Brightness */
#define ILI9341_READ_CABC           0x5FU   /* Read CABC Minimum Brightness */
#define ILI9341_READ_ID1            0xDAU   /* Read ID1 */
#define ILI9341_READ_ID2            0xDBU   /* Read ID2 */
#define ILI9341_READ_ID3            0xDCU   /* Read ID3 */

/* Level 2 Commands */
#define ILI9341_RGB_INTERFACE       0xB0U   /* RGB Interface Signal Control */
#define ILI9341_FRMCTR1             0xB1U   /* Frame Rate Control (In Normal Mode) */
#define ILI9341_FRMCTR2             0xB2U   /* Frame Rate Control (In Idle Mode) */
#define ILI9341_FRMCTR3             0xB3U   /* Frame Rate Control (In Partial Mode) */
#define ILI9341_INVTR               0xB4U   /* Display Inversion Control */
#define ILI9341_BPC                 0xB5U   /* Blanking Porch Control register */
#define ILI9341_DFC                 0xB6U   /* Display Function Control register */
#define ILI9341_ETMOD               0xB7U   /* Entry Mode Set */
#define ILI9341_BACKLIGHT1          0xB8U   /* Backlight Control 1 */
#define ILI9341_BACKLIGHT2          0xB9U   /* Backlight Control 2 */
#define ILI9341_BACKLIGHT3          0xBAU   /* Backlight Control 3 */
#define ILI9341_BACKLIGHT4          0xBBU   /* Backlight Control 4 */
#define ILI9341_BACKLIGHT5          0xBCU   /* Backlight Control 5 */
#define ILI9341_BACKLIGHT7          0xBEU   /* Backlight Control 7 */
#define ILI9341_BACKLIGHT8          0xBFU   /* Backlight Control 8 */
#define ILI9341_POWER1              0xC0U   /* Power Control 1 register */
#define ILI9341_POWER2              0xC1U   /* Power Control 2 register */
#define ILI9341_VCOM1               0xC5U   /* VCOM Control 1 register */
#define ILI9341_VCOM2               0xC7U   /* VCOM Control 2 register */
#define ILI9341_NVMWR               0xD0U   /* NV Memory Write */
#define ILI9341_NVMPKEY             0xD1U   /* NV Memory Protection Key */
#define ILI9341_RDNVM               0xD2U   /* NV Memory Status Read */
#define ILI9341_READ_ID4            0xD3U   /* Read ID4 */
#define ILI9341_PGAMMA              0xE0U   /* Positive Gamma Correction register */
#define ILI9341_NGAMMA              0xE1U   /* Negative Gamma Correction register */
#define ILI9341_DGAMCTRL1           0xE2U   /* Digital Gamma Control 1 */
#define ILI9341_DGAMCTRL2           0xE3U   /* Digital Gamma Control 2 */
#define ILI9341_INTERFACE           0xF6U   /* Interface control register */

/* Extend register commands */
#define ILI9341_POWERA               0xCBU   /* Power control A register */
#define ILI9341_POWERB               0xCFU   /* Power control B register */
#define ILI9341_DTCA                 0xE8U   /* Driver timing control A */
#define ILI9341_DTCB                 0xEAU   /* Driver timing control B */
#define ILI9341_POWER_SEQ            0xEDU   /* Power on sequence register */
#define ILI9341_3GAMMA_EN            0xF2U   /* 3 Gamma enable register */
#define ILI9341_PRC                  0xF7U   /* Pump ratio control register */

#define MADCTL_MY 0x80  ///< Bottom to top
#define MADCTL_MX 0x40  ///< Right to left
#define MADCTL_MV 0x20  ///< Reverse Mode
#define MADCTL_ML 0x10  ///< LCD refresh Bottom to top
#define MADCTL_RGB 0x00 ///< Red-Green-Blue pixel order
#define MADCTL_BGR 0x08 ///< Blue-Green-Red pixel order
#define MADCTL_MH 0x04  ///< LCD refresh right to left

/* Size of read registers */
#define LCD_READ_ID4_SIZE        3      /* Size of Read ID4 */

void ILI9341_Init(void);

#endif

In the source file:

#include "ILI9341.h"
#include "LCD_Pins.h"
#include "stdlib.h"



//initialize the tft
void ILI9341_Init(void)
{
	LCD_RST();
	LCD_Write_Cmd(ILI9341_SWRESET);
	delay(10);
	LCD_Write_Cmd(ILI9341_POWERB);
	delay(10);
	LCD_Write_Data(0x00);;
	LCD_Write_Data(0xD9);
	LCD_Write_Data(0x30);


	LCD_Write_Cmd(ILI9341_POWER_SEQ);
	LCD_Write_Data(0x64);
	LCD_Write_Data(0x03);
	LCD_Write_Data(0X12);
	LCD_Write_Data(0X81);


	LCD_Write_Cmd(ILI9341_DTCA);
	LCD_Write_Data(0x85);
	LCD_Write_Data(0x10);
	LCD_Write_Data(0x7A);


	LCD_Write_Cmd(ILI9341_POWERA);
	LCD_Write_Data(0x39);
	LCD_Write_Data(0x2C);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x34);
	LCD_Write_Data(0x02);


	LCD_Write_Cmd(ILI9341_PRC);
	LCD_Write_Data(0x20);


	LCD_Write_Cmd(ILI9341_DTCB);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x00);


	LCD_Write_Cmd(ILI9341_POWER1);
	LCD_Write_Data(0x1B);


	LCD_Write_Cmd(ILI9341_POWER2);
	LCD_Write_Data(0x12);


	LCD_Write_Cmd(ILI9341_VCOM1);
	LCD_Write_Data(0x08);
	LCD_Write_Data(0x26);


	LCD_Write_Cmd(ILI9341_VCOM2);
	LCD_Write_Data(0XB7);



	LCD_Write_Cmd(ILI9341_PIXEL_FORMAT);
	LCD_Write_Data(0x55); //select RGB565

	LCD_Write_Cmd(ILI9341_FRMCTR1);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x1B);//frame rate = 70


	LCD_Write_Cmd(ILI9341_DFC);    // Display Function Control
	LCD_Write_Data(0x0A);
	LCD_Write_Data(0xA2);


	LCD_Write_Cmd(ILI9341_3GAMMA_EN);    // 3Gamma Function Disable
	LCD_Write_Data(0x02);


	LCD_Write_Cmd(ILI9341_GAMMA);
	LCD_Write_Data(0x01);


	LCD_Write_Cmd(ILI9341_PGAMMA);    //Set Gamma
	LCD_Write_Data(0x0F);
	LCD_Write_Data(0x1D);
	LCD_Write_Data(0x1A);
	LCD_Write_Data(0x0A);
	LCD_Write_Data(0x0D);
	LCD_Write_Data(0x07);
	LCD_Write_Data(0x49);
	LCD_Write_Data(0X66);
	LCD_Write_Data(0x3B);
	LCD_Write_Data(0x07);
	LCD_Write_Data(0x11);
	LCD_Write_Data(0x01);
	LCD_Write_Data(0x09);
	LCD_Write_Data(0x05);
	LCD_Write_Data(0x04);


	LCD_Write_Cmd(ILI9341_NGAMMA);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x18);
	LCD_Write_Data(0x1D);
	LCD_Write_Data(0x02);
	LCD_Write_Data(0x0F);
	LCD_Write_Data(0x04);
	LCD_Write_Data(0x36);
	LCD_Write_Data(0x13);
	LCD_Write_Data(0x4C);
	LCD_Write_Data(0x07);
	LCD_Write_Data(0x13);
	LCD_Write_Data(0x0F);
	LCD_Write_Data(0x2E);
	LCD_Write_Data(0x2F);
	LCD_Write_Data(0x05);

	LCD_Write_Cmd(ILI9341_RGB_INTERFACE);
	LCD_Write_Data(0xC2); //Data is fetched during falling edge of DOTCLK


	LCD_Write_Cmd(ILI9341_INTERFACE);
	LCD_Write_Data(0x01);
	LCD_Write_Data(0x00);
	LCD_Write_Data(0x06);


	LCD_Write_Cmd(ILI9341_MAC);    // Memory Access Control command
	LCD_Write_Data(MADCTL_BGR);


	LCD_Write_Cmd(ILI9341_SLEEP_OUT); //Exit Sleep
	delay(100);
	LCD_Write_Cmd(ILI9341_DISPLAY_ON); //display on
	delay(100);

}

In part two, we shall initialize the LTDC and fill the screen with colors pixel by pix.

Stay tuned.

Happy coding 🙂

Add Comment

Your email address will not be published. Required fields are marked *