Question
why nand flash doesn't respond properly to stm32f429igt6?
I designed a board for stm32f429 discovery which has a nand flash on it and use fmc for working with.
The nand flash part number is K9F2G08U0C. I've worked with it before and use it with stm32f103zet6 by fsmc.
But now seems that the fmc can not interact with it correctly.
Here is my fmc init function:
static void MX_FMC_Init(void)
{
FMC_NAND_PCC_TimingTypeDef ComSpaceTiming;
FMC_NAND_PCC_TimingTypeDef AttSpaceTiming;
FMC_SDRAM_TimingTypeDef SdramTiming;
/** Perform the NAND1 memory initialization sequence
*/
hnand1.Instance = FMC_NAND_DEVICE;
/* hnand1.Init */
hnand1.Init.NandBank = FMC_NAND_BANK2;
hnand1.Init.Waitfeature = FMC_NAND_PCC_WAIT_FEATURE_ENABLE;
hnand1.Init.MemoryDataWidth = FMC_NAND_PCC_MEM_BUS_WIDTH_8;
hnand1.Init.EccComputation = FMC_NAND_ECC_DISABLE;
hnand1.Init.ECCPageSize = FMC_NAND_ECC_PAGE_SIZE_512BYTE;
hnand1.Init.TCLRSetupTime = 2;
hnand1.Init.TARSetupTime = 2;
/* hnand1.Config */
hnand1.Config.PageSize = 2048;
hnand1.Config.SpareAreaSize = 64;
hnand1.Config.BlockSize = 64;
hnand1.Config.BlockNbr = 2048;
hnand1.Config.PlaneNbr = 2;
hnand1.Config.PlaneSize = 1024;
hnand1.Config.ExtraCommandEnable = DISABLE;
/* ComSpaceTiming */
ComSpaceTiming.SetupTime = 4;
ComSpaceTiming.WaitSetupTime = 2;
ComSpaceTiming.HoldSetupTime = 2;
ComSpaceTiming.HiZSetupTime = 4;
/* AttSpaceTiming */
AttSpaceTiming.SetupTime = 4;
AttSpaceTiming.WaitSetupTime = 2;
AttSpaceTiming.HoldSetupTime = 2;
AttSpaceTiming.HiZSetupTime = 4;
if (HAL_NAND_Init(&hnand1, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
{
Error_Handler( );
}
/** Perform the SDRAM1 memory initialization sequence
*/
hsdram1.Instance = FMC_SDRAM_DEVICE;
/* hsdram1.Init */
hsdram1.Init.SDBank = FMC_SDRAM_BANK2;
hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
/* SdramTiming */
SdramTiming.LoadToActiveDelay = 2;
SdramTiming.ExitSelfRefreshDelay = 7;
SdramTiming.SelfRefreshTime = 4;
SdramTiming.RowCycleDelay = 7;
SdramTiming.WriteRecoveryTime = 3;
SdramTiming.RPDelay = 2;
SdramTiming.RCDDelay = 2;
if (HAL_SDRAM_Init(&hsdram1, &SdramTiming) != HAL_OK)
{
Error_Handler( );
}
}and this is the code I wrote for testing it:
{
static NAND_AddressTypeDef WriteReadAddr;
static NAND_IDTypeDef NAND_ID;
static uint8_t TxBuffer [2048];
static uint8_t RxBuffer [2048];
HAL_NAND_Reset(&hnand1);
HAL_Delay(100);
/* Read the NAND memory ID */
HAL_NAND_Read_ID(&hnand1, &NAND_ID);
HAL_Delay(100);
/* Fill the buffer to send */
for (int i = 0; i < 2048; i++ )
{
RxBuffer[i] = 0;
}
/* Fill the buffer to send */
for (int i = 0; i < 2048; i++ )
{
TxBuffer[i] = i;
}
/* NAND memory address to write to */
WriteReadAddr.Plane = 0;
WriteReadAddr.Block = 2;
WriteReadAddr.Page = 0;
/* Erase the NAND first Block */
if( HAL_NAND_Erase_Block(&hnand1, &WriteReadAddr) != HAL_OK)
{
while(1);
}
HAL_Delay(100);
/* Write data to FMC NAND memory */
if(HAL_NAND_Write_Page(&hnand1, &WriteReadAddr, TxBuffer, 1) != HAL_OK)
{
while(1);
}
HAL_Delay(100);
/* Read data from FMC NAND memory */
if(HAL_NAND_Read_Page(&hnand1, &WriteReadAddr, RxBuffer, 1) != HAL_OK)
{
while(1);
}
/* check date */
if(memcmp(TxBuffer,RxBuffer,sizeof(TxBuffer)) == 0 )
printf("\r\n\r\n NandFlash Read Write Test OK\r\n");
else
{
printf("\r\n\r\n NandFlash Read Write False\r\n");
while(1);
}
}