cancel
Showing results for 
Search instead for 
Did you mean: 

Custom board based on STM32F429I-DISCO and ILI9488 based Display [TouchGFX]

SProg
Associate III

Hello,

We have a device using the STM32F103 mC, driving an 320x480 display for basic shapes etc. We used SPI and then we moved to FSMC to increase speed.

Now since STM32F103 is not dedicated for much applications and need more speed/better graphics, we are going to move into STM32F429ZIT6 (and discovery hardware) which is more powerful + TouchGFX library supported.

We are using the attached display, which we cannot change for now.

The main problem is that i'm not sure if i can drive this display using LTDC and RGB666.

8 REPLIES 8
berendi
Principal

Looks like it supports RGB666 mode. Just connect the lines like they are connected on the discovery board, which has a TFT panel with a very similar interface.

Configure it to use SPI 4-wire mode (IM0=IM1=IM2=high), and use SPI commands (documented in the ILI9488 datasheet) to activate the RGB interface.

SPI 3-wire mode could theoretically work on an USART port.

SKokk.1
Associate II

Hello,

My custom board based on 429i-Disco arrived and i am trying to import the TouchGFX library. I am using the CubeIDE + TouchGFX 4.12.13.

I checked hardware and everything seems working without issues but i am stucked on the ILI9488 configuration for RGB666.

I have communication with the screen using SPI (IM0:2 = HIGH) but i can not set correctly the the RGB. Anyone was able to set the ILI9488 and could share some code or directions?

So far i am testing the below configuration (ignore the ili9341 name):

void ili9341_Init(void)
{
  /* Initialize ILI9341 low level bus layer ----------------------------------*/
  LCD_IO_Init();
  
  HAL_Delay(10);
  LCD_RDX_HIGH();
 
  /* LCD Reset high */
  HAL_GPIO_WritePin(LCD_RESET_GPIO_Port, LCD_RESET_Pin, GPIO_PIN_SET);
  /* LCD chip select high */
  LCD_CS_HIGH();
  LCD_CS_LOW();
  HAL_Delay(100);
  /* LCD chip select high */
  LCD_CS_HIGH();
  HAL_Delay(10);
 
  /* Configure LCD */
  ili9341_WriteReg(0x00);
 
  /* Out of sleep mode, 0 args, no delay */
  ili9341_WriteRegData(LCD_SLEEP_OUT, 0x00);
  HAL_Delay(10);
  //LCD_Delay(110);
 
  /* Frame rate ctrl - normal mode, 3 args:Rate = fosc/(1x2+40) * (LINE+2C+2D)*/
  ili9341_WriteRegData(LCD_FRMCTR1, 0xA0);
  HAL_Delay(10);
 
  /* Display inversion ctrl, 1 arg, no delay: 2-dot */
  ili9341_WriteRegData(LCD_INVTR, 0x02);
  HAL_Delay(10);
 
  ili9341_WriteRegData(LCD_DINVON, 0x00);
  HAL_Delay(10);
 
  /* Power control, 2 args, no delay: -4.6V , AUTO mode */
  LCD_CS_LOW();
  ili9341_WriteReg(LCD_POWER1);
  ili9341_WriteData(0x0F); //Fire
  ili9341_WriteData(0x0C);
 
  LCD_CS_HIGH();
  HAL_Delay(10);
 
  /* Power control, 1 arg, no delay: VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD */
  ili9341_WriteRegData(LCD_POWER2, 0x41);
  HAL_Delay(10);
 
  /* Power control, 3 args, no delay: Opamp current small, Boost frequency */
  LCD_CS_LOW();
  ili9341_WriteReg(0xC2); /* In normal mode (Full colors): PWCTR3 */
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x25);
  ili9341_WriteData(0x80);
  LCD_CS_HIGH();
  HAL_Delay(10);
 
  /* Memory Access */
  // Landscape: MY=1, MX=0, MV=1
  ili9341_WriteRegData(LCD_MAC, 0x40);
  HAL_Delay(10);
 
  // Pixel format: 16bit
 
  ili9341_WriteRegData(LCD_PIXEL_FORMAT, 0x66);
 
  //ili9341_WriteRegData(COLMOD, 0x55);
  HAL_Delay(10);
 
   ili9341_WriteRegData(LCD_RGB_INTERFACE, 0xC2);  //Fire
  //ili9341_WriteRegData(IFMOD, 0x80);
  HAL_Delay(10);
 
  ili9341_WriteRegData(0xE9, 0x00); // Set Image Function: SETIMAGE
  HAL_Delay(10);
 
  LCD_CS_LOW();
  ili9341_WriteReg(LCD_PRC);
  ili9341_WriteData(0xA9);
  ili9341_WriteData(0x51);
  ili9341_WriteData(0x2C);
  ili9341_WriteData(0x82);
  LCD_CS_HIGH();
  HAL_Delay(10);
 
  //  /* Magical unicorn dust, 15 args, no delay */
  LCD_CS_LOW();
  ili9341_WriteReg(LCD_PGAMMA);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x10);
  ili9341_WriteData(0x14);
  ili9341_WriteData(0x01);
  ili9341_WriteData(0x0E);
  ili9341_WriteData(0x04);
  ili9341_WriteData(0x33);
  ili9341_WriteData(0x56);
  ili9341_WriteData(0x48);
  ili9341_WriteData(0x03);
  ili9341_WriteData(0x0C);
  ili9341_WriteData(0x0B);
  ili9341_WriteData(0x2B);
  ili9341_WriteData(0x34);
  ili9341_WriteData(0x0F);
  LCD_CS_HIGH();
  HAL_Delay(10);
 
  ////  /* Sparkles and rainbows, 15 args, no delay */
  LCD_CS_LOW();
  ili9341_WriteReg(LCD_NGAMMA);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x12);
  ili9341_WriteData(0x18);
  ili9341_WriteData(0x05);
  ili9341_WriteData(0x12);
  ili9341_WriteData(0x06);
  ili9341_WriteData(0x40);
  ili9341_WriteData(0x34);
  ili9341_WriteData(0x57);
  ili9341_WriteData(0x06);
  ili9341_WriteData(0x10);
  ili9341_WriteData(0x0C);
  ili9341_WriteData(0x3B);
  ili9341_WriteData(0x3F);
  ili9341_WriteData(0x0F);
  LCD_CS_HIGH();
  HAL_Delay(10);
 
 
 
  /* Normal display on, no args, no delay */
  LCD_CS_LOW();
  ili9341_WriteRegData(LCD_NORMAL_MODE_ON, 0x00);
  HAL_Delay(10);
 
  /* Main screen turn on, no delay */
  LCD_CS_LOW();
  ili9341_WriteRegData(LCD_DISPLAY_ON, 0x00);
  HAL_Delay(10);
  LCD_CS_LOW();
 
  ili9341_WriteRegData(LCD_WCD, 0x2C);
  HAL_Delay(10);
  ili9341_WriteRegData(LCD_WDB, 0xff);
  HAL_Delay(10);
 
  //Check ID
  LCD_CS_LOW();
  ili9341_WriteReg(0x04);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x00);
  ili9341_WriteData(0x00);
  LCD_CS_HIGH();
 
  LCD_CS_LOW();
  ili9341_WriteReg(LCD_DFC);
  ili9341_WriteData(0x02);
  ili9341_WriteData(0x02);
  LCD_CS_HIGH();
  HAL_Delay(50);
 
  ili9341_DisplayCheck(0x00FC0000); // Custom function clears screen with RED bgnd - Works
  HAL_Delay(500);
 
  LCD_CS_LOW();
  ili9341_WriteReg(DISCTRL);
  ili9341_WriteData(0x32);
  ili9341_WriteData(0x02);
  LCD_CS_HIGH();
  HAL_Delay(50);
 
}

berendi
Principal

Is there any sure sign that the SPI communication works? Can you read back registers?

> i can not set correctly the the RGB

What does it mean?

Have you verified the LTDC registers and signals? How?

SKokk.1
Associate II

Is there any sure sign that the SPI communication works? Can you read back registers?

Yes, SPI is working.

i can not set correctly the the RGB

I have worked with this LCD on 8bit Parallel,16bit Parallel or SPI but never using RGB/LTDC. I am not sure what should i change on initialization in order to set ILI9488 working with RGB666

Have you verified the LTDC registers and signals? How?

How should i test it without being sure that ILI9488 is configured correctly?

SKokk.1
Associate II

It's hard working without first testing on evaluation/discovery board but finally it worked =)

I am attaching the changes i made to work with ILI9488 on custom board with 480*320 display.

https://www.youtube.com/watch?v=7NgRC72vje8

Are you using the method mentioned above where you start in SPI mode and then set it up for RGB input?

I ask because looking at the zip you shared, I don't see any SPI commands and am wondering if that is done and where?

Are you using the method mentioned above where you start in SPI mode and then set it up for RGB input?

It starts on SPI mode (screen pins IM0-IM1-IM2 set to HIGH) and then sets the driver to work with RGB input.

 I don't see any SPI commands and am wondering if that is done and where

 If you created a new project using CubeMX, check the BoardConfiguration.cpp

#include <common/TouchGFXInit.hpp>
#include <touchgfx/hal/BoardConfiguration.hpp>
#include <touchgfx/hal/GPIO.hpp>
#include <platform/driver/lcd/LCD16bpp.hpp>
 
#include <STM32F4HAL.hpp>
#include <STM32F4DMA.hpp>
 
#include <STM32F4Instrumentation.hpp>
#include <STM32F4TouchController.hpp>
 
/* USER CODE BEGIN user includes */
 
/* USER CODE END user includes */
 
/***********************************************************
 ******   Single buffer in internal RAM              *******
 ***********************************************************
 * On this platform, TouchGFX is able to run using a single
 * frame buffer in internal SRAM, thereby avoiding the need
 * for external SDRAM.
 * This feature was introduced in TouchGFX 4.7.0. To enable it,
 * uncomment the define below. The function touchgfx_init()
 * later in this file will check for this define and configure
 * TouchGFX accordingly.
 * For details on the single buffer strategy, please refer to
 * the knowledge base article "Single vs double buffering in TouchGFX"
 * on our support site.
 */
//#define SINGLE_FRAME_BUFFER_INTERNAL
 
/***********************************************************
 ******         24 Bits Per Pixel Support            *******
 ***********************************************************
 *
 * The default bit depth of the framebuffer is 16bpp. If you want 24bpp support, define the symbol "USE_BPP" with a value
 * of "24", e.g. "USE_BPP=24". This symbol affects the following:
 *
 * 1. Type of TouchGFX LCD (16bpp vs 24bpp)
 * 2. Bit depth of the framebuffer(s)
 * 3. TFT controller configuration.
 *
 * WARNING: Remember to modify your image formats accordingly in app/config/. Please see the following knowledgebase article
 * for further details on how to choose and configure the appropriate image formats for your application:
 *
 * https://touchgfx.zendesk.com/hc/en-us/articles/206725849
 */
 
 #include "HW_Init.hpp"
 
extern "C"
{
 
#include "stm32f4xx.h"
#include "stm32f4xx_hal_dma.h"
#include "stm32f4xx_hal_rcc_ex.h"
#include "stm32f4xx_hal_tim.h"
 
}
 
static uint32_t frameBuf0 = (uint32_t)(0xd0000000);
extern "C" {
 
extern void MX_SPI5_Init(void);
extern SPI_HandleTypeDef  hspi5;
 
extern void MX_SPI5_Init(void);
extern SPI_HandleTypeDef  hspi5;
 
/* In case of use of STM32429-DISCO board */
 
/* Chip Select macro definition */
#define LCD_CS_LOW()       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET)
#define LCD_CS_HIGH()      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET)
 
/* Set WRX High to send data */
#define LCD_WRX_LOW()       HAL_GPIO_WritePin(GPIOD,  GPIO_PIN_13, GPIO_PIN_RESET)
#define LCD_WRX_HIGH()      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET)
 
/* Set RDX High to send data */
#define LCD_RDX_LOW()       HAL_GPIO_WritePin(GPIOD,  GPIO_PIN_12, GPIO_PIN_RESET)
#define LCD_RDX_HIGH()      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET)
 
/**
  * @brief  SPIx error treatment function.
  */
static void SPIx_Error(void)
{
  /* De-initialize the SPI communication BUS */
  HAL_SPI_DeInit(&hspi5);
  
  /* Re- Initialize the SPI communication BUS */
   MX_SPI5_Init();
}
 
/**
  * @brief  Reads 4 bytes from device.
  * @param  ReadSize: Number of bytes to read (max 4 bytes)
  * @retval Value read on the SPI
  */
static uint32_t SPIx_Read(uint8_t ReadSize)
{
  HAL_StatusTypeDef status = HAL_OK;
  uint32_t readvalue;
  
  status = HAL_SPI_Receive(&hspi5, (uint8_t*) &readvalue, ReadSize, 0x1000);
  
  /* Check the communication status */
  if(status != HAL_OK)
  {
    /* Re-Initialize the BUS */
    SPIx_Error();
  }
  
  return readvalue;
}
 
/**
  * @brief  Writes a byte to device.
  * @param  Value: value to be written
  */
static void SPIx_Write(uint16_t Value)
{
  HAL_StatusTypeDef status = HAL_OK;
  
  status = HAL_SPI_Transmit(&hspi5, (uint8_t*) &Value, 1, 0x1000);
  
  /* Check the communication status */
  if(status != HAL_OK)
  {
    /* Re-Initialize the BUS */
    SPIx_Error();
  }
}
 
/**
  * @brief  Configures the LCD_SPI interface.
  */
__weak void LCD_IO_Init(void)
{
   /* Set or Reset the control line */
    LCD_CS_LOW();
    LCD_CS_HIGH();
    MX_SPI5_Init();
}
 
/**
  * @brief  Writes register address.
  */
__weak void LCD_IO_WriteReg(uint8_t Reg) 
{
  /* Reset WRX to send command */
  LCD_WRX_LOW();
  
  /* Reset LCD control line(/CS) and Send command */
  LCD_CS_LOW();
  SPIx_Write(Reg);
  
  /* Deselect: Chip Select high */
  LCD_CS_HIGH();
}
/**
  * @brief  Writes register value.
  */
 
__weak void LCD_IO_WriteData(uint16_t RegValue) 
{
  /* Set WRX to send data */
  LCD_WRX_HIGH();
  
  /* Reset LCD control line(/CS) and Send data */  
  LCD_CS_LOW();
  SPIx_Write(RegValue);
  
  /* Deselect: Chip Select high */
  LCD_CS_HIGH();
}
 
/**
  * @brief  Reads register value.
  * @param  RegValue Address of the register to read
  * @param  ReadSize Number of bytes to read
  * @retval Content of the register value
  */
 
__weak uint32_t LCD_IO_ReadData(uint16_t RegValue, uint8_t ReadSize) 
{
  uint32_t readvalue = 0;
 
  /* Select: Chip Select low */
  LCD_CS_LOW();
 
  /* Reset WRX to send command */
  LCD_WRX_LOW();
  
  SPIx_Write(RegValue);
  
  readvalue = SPIx_Read(ReadSize);
 
  /* Set WRX to send data */
  LCD_WRX_HIGH();
 
  /* Deselect: Chip Select high */
  LCD_CS_HIGH();
  
  return readvalue;
}
 
/**
  * @brief  Wait for loop in ms.
  * @param  Delay in ms.
  */
void LCD_Delay(uint32_t Delay)
{
  HAL_Delay(Delay);
}
 
uint32_t LCD_GetXSize(void)
{
  return 320;
}
 
uint32_t LCD_GetYSize(void)
{
  return 480;
}
}
 
void GRAPHICS_HW_Init()
{
    
 
    /* Initialize the SDRAM */
    MX_FMC_Init();
    MX_SDRAM_InitEx();
 
    /* Configure LCD */
    MX_LCD_Init();
    GPIO::init();
 
}
 
STM32F4DMA dma;
STM32F4TouchController tc;
STM32F4Instrumentation mcuInstr;
 
static LCD16bpp display;
static uint16_t bitdepth = 16;
 
namespace touchgfx
{
void touchgfx_init()
{
  uint16_t dispWidth = 320;
  uint16_t dispHeight = 480;  
  
  HAL& hal = touchgfx_generic_init<STM32F4HAL>(dma, display, tc, dispWidth, dispHeight,(uint16_t*) 0, 
                                               0, 0); 
 
    hal.setFrameBufferStartAddress((uint16_t*)frameBuf0, bitdepth ,true , true);
 
    hal.setTouchSampleRate(2);
    hal.setFingerSize(1);
 
    // By default frame rate compensation is off.
    // Enable frame rate compensation to smooth out animations in case there is periodic slow frame rates.
    hal.setFrameRateCompensation(false);
 
    // This platform can handle simultaneous DMA and TFT accesses to SDRAM, so disable lock to increase performance.
    hal.lockDMAToFrontPorch(false);
 
    mcuInstr.init();
 
    //Set MCU instrumentation and Load calculation
    hal.setMCUInstrumentation(&mcuInstr);
    hal.enableMCULoadCalculation(true);
}
}
 
void GRAPHICS_Init()
{
   touchgfx::touchgfx_init();
}
 
void GRAPHICS_MainTask(void)
{
    touchgfx::HAL::getInstance()->taskEntry();
}

I'm using a 429 DISC1 board. I will be removing the ILI9341 display and wiring the ILI9488 to it with jumper wires.

I'm using CubeIDE but with a ready made project folder from LVGL. I want to modify it to work with the ILI9488 and FT6306 Capacitive Touch controller