AnsweredAssumed Answered

STM32F2 FSMC ILI9341

Question asked by ThomasW on Oct 12, 2015
Latest reply on Oct 13, 2015 by ThomasW

Hi,

I want to control a TFT (with a ILI9341) display via the 16 bit FSMC interface of a STM32F205VET6. Therefore I am using the emWin library v5.30 provided by Keil. I got the application working and all the display content is drawn properly on the TFT. 
But now I want to use the blinking cursor functionality of the EDIT widget and therefore the emWin library performs a multiple read operation (µC reads from display GRAM). Here I get into trouble. It seems like I have some timing problems. If the code writes data to the TFT I immediately read back the written data but the read data differs from the written data in approx. 30% of the write attempts. I already played around with the FSMC timings but without any changes. I calculated the timings according to AN2790 DATAST = 355ns and ADDSET = 67ns. Which makes DATAST = 22 and ADDSET = 4 @ fFSMC = 60MHz.

Hope that anybody can help me.

Here is my initialization code.

void LCD_X_Init(void) {
  GPIO_InitTypeDef GPIO_InitStruct;
  FSMC_NORSRAMInitTypeDef hsram1;
  FSMC_NORSRAMTimingInitTypeDef Timing;


  /* GPIO Ports Clock Enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,    ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);


  /** FSMC GPIO Configuration  
  PE7   ------> FSMC_D4
  PE8   ------> FSMC_D5
  PE9   ------> FSMC_D6
  PE10   ------> FSMC_D7
  PE11   ------> FSMC_D8
  PE12   ------> FSMC_D9
  PE13   ------> FSMC_D10
  PE14   ------> FSMC_D11
  PE15   ------> FSMC_D12
  PD8   ------> FSMC_D13
  PD9   ------> FSMC_D14
  PD10   ------> FSMC_D15
  PD11   ------> FSMC_A16
  PD14   ------> FSMC_D0
  PD15   ------> FSMC_D1
  PD0   ------> FSMC_D2
  PD1   ------> FSMC_D3
  PD4   ------> FSMC_NOE
  PD5   ------> FSMC_NWE
  PD7   ------> FSMC_NE1
  */
  /* GPIOE configuration */
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource15, GPIO_AF_FSMC);
  
  GPIO_InitStruct.GPIO_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;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOE, &GPIO_InitStruct);
  
  /* GPIOD configuration */
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource7, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);


  GPIO_InitStruct.GPIO_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_11|GPIO_Pin_14|GPIO_Pin_15;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOD, &GPIO_InitStruct);


  /* Configuration of the reset pin */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;  
  GPIO_Init(GPIOD, &GPIO_InitStruct);
  
  GPIO_WriteBit(GPIOD, GPIO_Pin_13, Bit_RESET);
  
  /* Enable FSMC peripheral clock */
  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);


  /* SRAM1 memory initialization */
  hsram1.FSMC_Bank = FSMC_Bank1_NORSRAM1;
  hsram1.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
  hsram1.FSMC_MemoryType = FSMC_MemoryType_SRAM;
  hsram1.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
  hsram1.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
  hsram1.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
  hsram1.FSMC_WrapMode = FSMC_WrapMode_Disable;
  hsram1.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
  hsram1.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
  hsram1.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
  hsram1.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
  hsram1.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
  hsram1.FSMC_WriteBurst = FSMC_WriteBurst_Disable;


/* @todo: Check timing */
  Timing.FSMC_AddressSetupTime = 1;
  Timing.FSMC_AddressHoldTime = 4;
  Timing.FSMC_DataSetupTime = 22;
  Timing.FSMC_BusTurnAroundDuration = 0;
  Timing.FSMC_CLKDivision = 0;
  Timing.FSMC_DataLatency = 0;
  Timing.FSMC_AccessMode = FSMC_AccessMode_A;
  
  hsram1.FSMC_ReadWriteTimingStruct = &Timing;
  hsram1.FSMC_WriteTimingStruct = &Timing;


  FSMC_NORSRAMInit(&hsram1);
  
  /* Enable FSMC_Bank1_NORSRAM1 */
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
  
  /* Turn LCD Backlight On, release display from reset */
  GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
  GPIO_WriteBit(GPIOD, GPIO_Pin_13, Bit_SET);
}

regards Thomas

Outcomes