We have been having issues with NAND flash corruption using the Freescale Windows CE 6.0 BSP. We use a Toshiba TC58NVG1S3EBAI5 part with 2Gb arranged as 2048+64 pages x 64 pages/block x 2048 blocks. To implement this I have followed the guides on the forums to add to the nandtypes.h structure and also used the Freescale timing sheet to set up the GPMI timings. I have also fixed the issues regarding the flash write line being set to 1.8V in the BSP.
I have been investigating how the code determines the bad blocks. In the nandtypes.h file you can just specify the bad block pages but not the byte location within the page. For the Toshiba NAND the factory blocks are at either column 0 or 2048 of the first or second page of each erase block. If !=0xFF then they are bad.
Initially I was a bit confused about some strange byte swapping going on within the CSPNAND_ReadSector and CSPNAND_WriteSector functions. The code seems to swap a byte from the data section with the spare section of flash and do some bit shifting. I believe this is due to 'BBISwap' required because the physical layout of the flash is interleaved with parity due to the BCH ECC layout used. Also I found this:
According to nand_ecc.h in the BSP the offset byte in the NAND layout that requires swapping is calculated as follows:
typedef enum _nand_ecc_type
BCH_Ecc_0bit = 0,
#define ECCN_2K64_PAGE (BCH_Ecc_4bit)
#define ECCN_4K128_PAGE (BCH_Ecc_4bit)
#define ECCN_4K218_PAGE (BCH_Ecc_8bit)
#define ECC0_2K4K_PAGE (BCH_Ecc_8bit)
#define METADATA_EXTRA (2)
#define METADATA_SIZE (METADATA_EXTRA + sizeof(SectorInfo))
//= int(2048 - ((METADATA_SIZE + ECC0_2K4K_PAGE * 13 / 8) + (512 + ECCN_2K64_PAGE * 13 / 8) * 3) + 512 * 3)
#define BBMarkByteOffsetInPageData_2K64 2005
#define BBMarkBitOffset_2K64 4 // ECCN_2K64_PAGE * 2 % 8
So it seems that the byte offset would be at 2005. I have read the BCH section of the iMX28 reference manual and I am not sure this is correct. For one the code seems to use the value of the register x 13 for the number of ECC parity bits, but the register is the correctable ecc bits / 2.
The ECC is initilaised with:
if(PageSize == 2048 && SpareSize == 64)
HW_BCH_FLASH0LAYOUT0_WR(BF_BCH_FLASH0LAYOUT0_NBLOCKS(0x4) | BF_BCH_FLASH0LAYOUT0_META_SIZE(METADATA_SIZE) | BF_BCH_FLASH0LAYOUT0_ECC0(ECC0_2K4K_PAGE));
HW_BCH_FLASH0LAYOUT1_WR(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(2048+64) | BF_BCH_FLASH0LAYOUT1_ECCN(ECCN_2K64_PAGE) | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(512));
I need some help interpreting how the NAND layout will be defined for these settings:
Data 0 Size = 0 - metadata has its own block and parity
ECC0 = 8-bit (value 4 to register)
Meta Data Size = 10 bytes
Nblocks = 4
DataN size = 512
Page size = 2112 (2048 + 64)
ECCN = 4-bit (value 2 to register)
I need to understand how many physical bytes are used in the layout for the ECC bits. According to the reference manual there are 13xt bits where t is the number of correctable ECC bits (not value of register as shown in above code sample).
So for 8-bit ECC on block 0 I would assume 13 x 8 = 13 bytes
For 4-bit ECC on the data blocks it is 13 x 4 = 6.5 bytes - does this occupy 7 bytes in the physical flash layout after each block? Is it padded to the next dword?
My interpretation of the layout is below. So I need to find out where in the 2048 byte data buffer maps to the ECC layout data blocks to determine which byte to swap.
According to the above (and assuming the 6.5 byte parity uses 7 bytes) the total bytes used are 2+8+13+(4x(512+7)) = 2099 bytes out of the 2112 available on each page. So where does the remaining 13 spare bytes sit in the physical layout?
Once I know the physical ECC layout I can then figure out the byte offset into the data buffer. Please can someone help me understand the physical ECC layout?