Успешно запустил контроллер NAND Flash и прикрутил к нему проблемный дисплей.
Получил ещё одно подтверждение того, что дисплей хочет длинный HOLD.
Частота FMC=200 МГц. 1 CLK = 5 нс.
Первым делом, настроил MPU, для отключения кеширования диапазона адресов: 0x80000000...0x8FFFFFFF (256 МБ). Позже объясню, зачем так много.
Код
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);
}
Затем проинитил FMC , NAND. Здесь разные времянки для PMEM и PATT - использую первую для записи, вторую для чтения в регистры LCD (времянки на чтение всегда более длинные):
Код
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__);
}
}
Почитал референс-мануал на H743, внимательно расставил параметры времянок с учётом того, что к некоторым добавляется +1 CLK.
Код
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: ещё позже)
Всё согласно времянкам проблемного дисплея:
Нажмите для просмотра прикрепленного файлаУточнения:
1)
tHIZ выбрано равным tSETUP. Чтобы данные выкидывались на шину сразу же после падения строба записи NWE.
Можно сделать вообще tHIZ=0, тогда данные будут выдаваться сразу же после падения NCE - проверил: тоже работает!
2)
Если tWAIT меньше 2, то кадр в дисплее начинает перекручиваться и периодически переставлять байты цвета (идут пропуски байтов)
3)
Если tHOLD меньше 2, то дисплей повисает.
Как раз тот случай, что с NOR/PSRAM контроллером - tHOLD там всегда 1 CLK ! 4)
Если tWAIT=2 и tHOLD=2, то дисплей работает, но очень редко зависает (времянка не соответствует приведённой в даташите на LCD).
Код что выше, обеспечивает необходимую времянку. Дисплей проработал 1.5 часа без сбоя. Дальше не тестировал.
Порты для записи в LCD:
Код
#define LCD_WR_COM16 (*(volatile unsigned short int*) 0x80000000)
#define LCD_WR_DAT16 (*(volatile unsigned short int*) 0x80010000)
Для чтения:
Код
#define LCD_RD_COM16 (*(volatile unsigned short int*) 0x88000000)
#define LCD_RD_DAT16 (*(volatile unsigned short int*) 0x88010000)
Итоговая скорость записи в дисплей: 200MHz/(1+4+3)=25 MHz
Соединение дисплея с FMC:
Цитата
D0..D7 - LCD D0..D7
NWAIT - не используется
NOE - LCD !RD
NWE - LCD !WE
NCE - LCD !CS
A16 - CLE - LCD !RS
A17 - ALE - не используется