2018-07-23 08:43 PM
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)
2018-08-08 09:50 AM
@ST Community Please have staff responsible for H7 engage
2018-08-09 12:50 PM
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
2018-08-17 04:47 AM
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.
2018-08-17 04:50 AM
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
2018-08-17 06:15 AM
Thanks, this sounds interesting.
JW
2018-08-17 06:33 AM
Early, I wrote about it here (most full description + pictures): https://electronix.ru/forum/index.php?showtopic=148029