2020-05-07 06:21 PM
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?
2020-05-07 06:42 PM
Pretty sure the ECC vector is wider than 32-bit. need a deeper array for eccWr / eccRd so you don't trash the stack
2020-05-07 07:18 PM
Thank you for your reply. I modified the code and checked it. Do you have any other ideas?
INT8U NAND_ReadWrite_Test(INT32U addr)
{
INT8U i, eccWr[64]={0}, eccRd[64]={0}, eccCmp[64] = {0};
...
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, (INT32U *)eccWr, HAL_MAX_DELAY); // ecc get
HAL_NAND_ECC_Disable(&hnand2); // ecc disable
if(HAL_NAND_Write_SpareArea_8b(&hnand2, &NAND_Address, eccWr, 1) != HAL_OK)
{
return _NAND_ERROR;
}
printk("Write ECC: ");
for(i=0; i<64; i++){
if((i&0xF) == 0) printk("\n");
printk("%02X ", eccWr[i]);
}
printk("\n");
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, (INT32U *)eccRd, HAL_MAX_DELAY); // ecc get
HAL_NAND_ECC_Disable(&hnand2); // ecc disable
if(HAL_NAND_Read_SpareArea_8b(&hnand2, &NAND_Address, eccCmp, 1) != HAL_OK)
{
return _NAND_ERROR;
}
printk("Read ECC: ");
for(i=0; i<64; i++){
if((i&0xF) == 0) printk("\n");
printk("%02X ", eccRd[i]);
}
printk("\n");
printk("Cmp ECC: ");
for(i=0; i<64; i++){
if((i&0xF) == 0) printk("\n");
printk("%02X ", eccCmp[i]);
}
printk("\n");
...
//---------------------------------------- Test Result
Nand-Flash Read Write Test
Maker_Id(C2), Device_Id(F1), Third_Id(80), Fourth_Id(95)
ONFI
Write ECC:
6A 66 55 55 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Read ECC:
F0 3F 03 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Cmp ECC:
6A 66 55 55 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Done.
2020-05-07 07:19 PM
Thank you for your reply. I modified the code and checked it. Do you have any other ideas?
INT8U NAND_ReadWrite_Test(INT32U addr)
{
INT8U i, eccWr[64]={0}, eccRd[64]={0}, eccCmp[64] = {0};
...
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, (INT32U *)eccWr, HAL_MAX_DELAY); // ecc get
HAL_NAND_ECC_Disable(&hnand2); // ecc disable
if(HAL_NAND_Write_SpareArea_8b(&hnand2, &NAND_Address, eccWr, 1) != HAL_OK)
{
return _NAND_ERROR;
}
printk("Write ECC: ");
for(i=0; i<64; i++){
if((i&0xF) == 0) printk("\n");
printk("%02X ", eccWr[i]);
}
printk("\n");
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, (INT32U *)eccRd, HAL_MAX_DELAY); // ecc get
HAL_NAND_ECC_Disable(&hnand2); // ecc disable
if(HAL_NAND_Read_SpareArea_8b(&hnand2, &NAND_Address, eccCmp, 1) != HAL_OK)
{
return _NAND_ERROR;
}
printk("Read ECC: ");
for(i=0; i<64; i++){
if((i&0xF) == 0) printk("\n");
printk("%02X ", eccRd[i]);
}
printk("\n");
printk("Cmp ECC: ");
for(i=0; i<64; i++){
if((i&0xF) == 0) printk("\n");
printk("%02X ", eccCmp[i]);
}
printk("\n");
...
//---------------------------------------- Test Result
Nand-Flash Read Write Test
Maker_Id(C2), Device_Id(F1), Third_Id(80), Fourth_Id(95)
ONFI
Write ECC:
6A 66 55 55 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Read ECC:
F0 3F 03 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Cmp ECC:
6A 66 55 55 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Done.