cancel
Showing results for 
Search instead for 
Did you mean: 

I want to know how NAND ECC works.

DJung.3
Associate II

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?

3 REPLIES 3

Pretty sure the ECC vector is wider than 32-bit. need a deeper array for eccWr / eccRd so you don't trash the stack

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
DJung.3
Associate II

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.

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.