I want to know how NAND ECC works.
STM32CubeMX Version 4.23.0
STM32F2 Hal version 1.7.0
STM32F207ZGT6, MX30LF1G18AC-XKI (NAND)
//---------------------------------------- FSMC Setting
/** Perform the NAND2 memory initialization sequence
*/
hnand2.Instance = FSMC_NAND_DEVICE;
/* hnand2.Init */
hnand2.Init.NandBank = FSMC_NAND_BANK2;
hnand2.Init.Waitfeature = FSMC_NAND_PCC_WAIT_FEATURE_DISABLE;
hnand2.Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8;
hnand2.Init.EccComputation = FSMC_NAND_ECC_DISABLE;
hnand2.Init.ECCPageSize = FSMC_NAND_ECC_PAGE_SIZE_2048BYTE;
hnand2.Init.TCLRSetupTime = 0;
hnand2.Init.TARSetupTime = 0;
/* hnand2.Config */
hnand2.Config.PageSize = 2048;
hnand2.Config.SpareAreaSize = 64;
hnand2.Config.BlockSize = 64;
hnand2.Config.BlockNbr = 1024;
hnand2.Config.PlaneNbr = 1;
hnand2.Config.PlaneSize = 1024;
hnand2.Config.ExtraCommandEnable = ENABLE;
/* ComSpaceTiming */
ComSpaceTiming.SetupTime = 4;
ComSpaceTiming.WaitSetupTime = 3;
ComSpaceTiming.HoldSetupTime = 3;
ComSpaceTiming.HiZSetupTime = 4;
/* AttSpaceTiming */
AttSpaceTiming.SetupTime = 4;
AttSpaceTiming.WaitSetupTime = 3;
AttSpaceTiming.HoldSetupTime = 3;
AttSpaceTiming.HiZSetupTime = 4;
if (HAL_NAND_Init(&hnand2, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
//---------------------------------------- Test Code
INT8U NAND_ReadWrite_Test(INT32U addr)
{
INT32U eccWr, eccRd;
/*##-1- Configure the NAND device
/* Read NAND memory ID */
if(HAL_NAND_Read_ID(&hnand2, &NAND_ID) != HAL_OK)
{
/* NAND read ID Error */
return _NAND_ERROR;
}
printk("Maker_Id(%02X), Device_Id(%02X), Third_Id(%02X), Fourth_Id(%02X)\n",
NAND_ID.Maker_Id, NAND_ID.Device_Id, NAND_ID.Third_Id, NAND_ID.Fourth_Id);
/*##-2- Convert Address to NAND
NAND_GetAddress(addr, &NAND_Address);
/*##-3- Erase NAND memory
if(HAL_NAND_Erase_Block(&hnand2, &NAND_Address) != HAL_OK)
{
printk("Block Erase Fail!!\n");
return _NAND_ERROR;
}
/*##-4- NAND memory read/write
/* Fill the buffer to write */
Fill_Buffer(nand_aTxBuffer, NAND_BUFFER_SIZE, 0xD200);
HAL_NAND_ECC_Enable(&hnand2); // ecc enable
/* Write data to the NAND memory */
if(HAL_NAND_Write_Page_8b(&hnand2, &NAND_Address, nand_aTxBuffer, NB_PAGE) != HAL_OK)
{
printk("Block Write Fail!!\n");
return _NAND_ERROR;
}
HAL_NAND_GetECC(&hnand2, &eccWr, HAL_MAX_DELAY); // ecc get
HAL_NAND_ECC_Disable(&hnand2); // ecc disable
if(HAL_NAND_Write_SpareArea_8b(&hnand2, &NAND_Address, (INT8U *)&eccWr, 1) != HAL_OK)
{
return _NAND_ERROR;
}
printk("written ECC = %#X\n", eccWr);
HAL_NAND_ECC_Enable(&hnand2); // ecc enable
/* Read back data from the NAND memory */
if(HAL_NAND_Read_Page_8b(&hnand2, &NAND_Address, nand_aRxBuffer, NB_PAGE) != HAL_OK)
{
printk("Block Read Fail!!\n");
return _NAND_ERROR;
}
HAL_NAND_GetECC(&hnand2, &eccRd, HAL_MAX_DELAY); // ecc get
HAL_NAND_ECC_Disable(&hnand2); // ecc disable
if(HAL_NAND_Read_SpareArea_8b(&hnand2, &NAND_Address, (INT8U *)&eccCmp, 1) != HAL_OK)
{
return _NAND_ERROR;
}
if(eccRd != eccCmp) printk("ECC Fail!! %#X != %#X\n", eccRd, eccCmp);
else printk("ECC Ok. %#X == %#X\n", eccRd, eccCmp);
/*##-5- Checking data integrity
if(Buffercmp(nand_aTxBuffer, nand_aRxBuffer, NAND_BUFFER_SIZE) != _NAND_OK)
{
printk("Buffer compare Fail!!\n");
return _NAND_ERROR;
}
return _NAND_OK;
}
//---------------------------------------- Test Result
Nand-Flash Read Write Test
Maker_Id(C2), Device_Id(F1), Third_Id(80), Fourth_Id(95)
written ECC = 0X5555666A
ECC Fail!! 0XCF33 != 0X5555666A
Done.
What is the reason for the difference between the value of ECC when writing and the value of ECC when reading? What am I missing?