cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with using LCD with FMC in SRAM mode. STM32H743.

Karl Lipnen
Associate II

Hello, Everyone!

I found issue with using my LCD (via i8080 mode) with FMC. My display requires HOLD after DATA set from 15 ns time.

But in all FMC modes HOLD fixed and it 1 FMC CLK. For my STM32H743 at 400 MHz - I set FMC clock 200 MHz. It is HOLD = 5ns = 1 FMC CLK. And display works not properly.

1) I tryed reduce FMC clock down to 66 MHz, display working properly. Because HOLD after Data was set 15 ns and it is enougth.

2) I enetered FMC to NAND mode and set HOLD directly. Display works correctly too.

Any another solutions? How to insert more long Hold timing after Data setup in SRAM mode?

Attached pictures:

1) Timing diagrams for my display.

2) And FMC timing in SRAM mode (jnly 1 CLK HOLD)

6 REPLIES 6

@ST Community​ Please have staff responsible for H7 engage

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

This is not H7-specific; this is how FSMC and FMC handle the static memories ever since, it has been discussed e.g. here https://community.st.com/s/question/0D50X00009XkZZNSA3/memory-with-long-write-recovery-time-with-fsmc-of-stm32f407ig . In some cases, not only data but also address need hold (or, in other words, the strobe signal - WR or CS - should end sooner); I know of no "regular" solution so far.

I don't quite understand how NAND mode would help, but I did not study that mode in depth and it may be workaround. Karl, can you please discuss that in more detail?

JW

Karl Lipnen
Associate II

waclawek.jan , FMC in NAND mode has the ability to set variable HOLD Time. See picture attached under this post.

I successfully tested my LCD with this code:

static void MX_FMC_Init(void)
{
  FMC_NAND_PCC_TimingTypeDef ComSpaceTiming;
  FMC_NAND_PCC_TimingTypeDef AttSpaceTiming;
 
  /** Perform the NAND1 memory initialization sequence
  */
  hnand1.Instance = FMC_NAND_DEVICE;
  /* hnand1.Init */
  hnand1.Init.NandBank = FMC_NAND_BANK3;
  hnand1.Init.Waitfeature = FMC_NAND_WAIT_FEATURE_DISABLE;
  hnand1.Init.MemoryDataWidth = FMC_NAND_MEM_BUS_WIDTH_8;
  hnand1.Init.EccComputation = FMC_NAND_ECC_DISABLE;
  hnand1.Init.ECCPageSize = FMC_NAND_ECC_PAGE_SIZE_256BYTE;
  hnand1.Init.TCLRSetupTime = 0;
  hnand1.Init.TARSetupTime = 0;
  /* hnand1.Config */
  hnand1.Config.PageSize      = 262144; //256kB >= 320x240x2
  hnand1.Config.SpareAreaSize = 262144; //256kB >= 320x240x2
  hnand1.Config.BlockSize = 1;
  hnand1.Config.BlockNbr = 1;
  hnand1.Config.PlaneNbr = 1;
  hnand1.Config.PlaneSize = 1;
  hnand1.Config.ExtraCommandEnable = ENABLE;
 
//�?дре�?а дл�? запи�?и:
  /* ComSpaceTiming: 0x80000000..0x83FFFFFF */
  ComSpaceTiming.SetupTime     = 0; //+1 1CLK =  5ns             >=  4ns
  ComSpaceTiming.WaitSetupTime = 3; //+1 4CLK = 20ns             >= 18ns 1CLK уже мало
  ComSpaceTiming.HoldSetupTime = 3; //+0 3CLK = 15ns             >= 15ns 1CLK уже мало
  ComSpaceTiming.HiZSetupTime  = 1; //+0 1CLK =  5ns (tSET=tHIZ) >=  4ns 0CLK работает (0CLK: данные по�?в�?т�?�? �?разу по�?ле падени�? NCE, 1CLK: по�?ле падени�? NWE, >1CLK: ещё позже)
 
//�?дре�?а дл�? чтени�?:
  /* AttSpaceTiming: 0x88000000..0x8BFFFFFF */
  AttSpaceTiming.SetupTime     = 254; //+1
  AttSpaceTiming.WaitSetupTime = 254; //+1
  AttSpaceTiming.HoldSetupTime = 254; //WR:+0 RD:+1
  AttSpaceTiming.HiZSetupTime  = 254; //+0
 
  if (HAL_NAND_Init(&hnand1, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
 
}
static void MPU_Conf(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
 
HAL_MPU_Disable();
 
MPU_InitStruct.Enable=MPU_REGION_ENABLE;
 
MPU_InitStruct.BaseAddress = 0x80000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256MB; //0x80000000..0x8FFFFFFF
 
MPU_InitStruct.AccessPermission=MPU_REGION_FULL_ACCESS;
 
MPU_InitStruct.TypeExtField=MPU_TEX_LEVEL0;
 
MPU_InitStruct.IsCacheable=MPU_ACCESS_NOT_CACHEABLE; //NOT CACHEABLE
MPU_InitStruct.IsBufferable=MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsShareable=MPU_ACCESS_SHAREABLE;
 
MPU_InitStruct.Number=MPU_REGION_NUMBER0;
MPU_InitStruct.SubRegionDisable=0x00;
MPU_InitStruct.DisableExec=MPU_INSTRUCTION_ACCESS_DISABLE;
 
HAL_MPU_ConfigRegion(&MPU_InitStruct);
 
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

And I got what I wanted.

0690X000006BuBbQAK.jpg

0690X000006BuB2QAK.jpg

Karl Lipnen
Associate II

LCD IO for write (fast timings):

#define LCD_WR_COM16 (*(volatile unsigned short int*) 0x80000000)

#define LCD_WR_DAT16 (*(volatile unsigned short int*) 0x80010000)

LCD IO for read (slow timings):

#define LCD_RD_COM16 (*(volatile unsigned short int*) 0x88000000)

#define LCD_RD_DAT16 (*(volatile unsigned short int*) 0x88010000)

Total speed in my case for LCD: 200MHz/(1+4+3)=25 MHz

Connection LCD and FMC:

D0..D7 - LCD D0..D7

NWAIT - not used

NOE - LCD !RD

NWE - LCD !WE

NCE - LCD !CS

A16 - CLE - LCD !RS

A17 - ALE - not used

Thanks, this sounds interesting.

JW

Karl Lipnen
Associate II

Early, I wrote about it here (most full description + pictures): https://electronix.ru/forum/index.php?showtopic=148029