Principle and Implementation of NAND Flash ECC verification

Source: Internet
Author: User

Reference: http://blogimg.chinaunix.net/blog/upfile2/080702112233.pdf

Principle and Implementation of NAND Flash ECC verification

ECC Introduction
Because the process of NAND Flash cannot guarantee the reliability of the memory array in its life cycle, Bad blocks will be generated during the production and use of NAND. In order to check the data reliability, some bad zone management policies are usually used in the system that uses NAND Flash. The premise of managing bad zones is that the bad zone detection can be performed reliably.
If there is no problem with the Operation Sequence and circuit stability, the NAND Flash error generally does not cause the entire block, the page cannot be read, or all errors, but the whole page (such as 512 bytes) only one or several BITs have errors.
Common data verification methods include parity and CRC. In NAND Flash processing, ECC is a dedicated verification method. ECC can correct single-bit errors and detect dual-bit errors, and the computation speed is fast. However, it cannot correct errors of more than one bit, and it cannot detect errors of more than two bits.

ECC Principle
ECC generally generates 3-byte ECC verification data for each 256 bytes of raw data. The three-byte 24-bit data is divided into two parts: 6-bit column verification and 16-bit row verification, set the remaining two bits to 1, as shown in:

  
Shows the column verification and generation rules of ECC:

Expressed:
P4 = D7 (+) D6 (+) D5 (+) D4 P4 '= D3 (+) D2 (+) D1 (+) D0
P2 = D7 (+) D6 (+) D3 (+) D2 P2 '= D5 (+) D4 (+) D1 (+) D0
P1 = D7 (+) D5 (+) D3 (+) D1 P1 '= D6 (+) D4 (+) D2 (+) D0
Here (+) indicates "bitwise OR" Operation
  
Shows the row verification and generation rules of ECC:

Expressed:
P8 = bit7 (+) bit6 (+) bit5 (+) bit4 (+) bit3 (+) bit2 (+) bit1 (+) bit0 (+) p8
................................................................................................
Here (+) also indicates "bitwise OR" Operation
 
When data is written to the page of NAND Flash, an ECC checksum is generated every 256 bytes, which is called the original ECC checksum and saved to the OOB (out-of-band) of the page) data zone.
When reading data from NAND Flash, an ECC checksum is generated every 256 bytes, which is called a new ECC checksum.
During verification, based on the above ECC generation principle, it is not difficult to infer that the original ECC verification and the new ECC verification read from the OOB area are bitwise OR. If the result is 0, it indicates that there is no error (or an error that cannot be detected by ECC). If there are 11 bits in the 3-byte variance or the result is 1, it indicates that there is a bit error, it can be corrected. If only one bit in the three bytes is 1, an error occurs in the OOB area. Otherwise, an error cannot be corrected.

Implementation of ECC Algorithms
Static const u_char nand_ecc_precalc_table [] =
{
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
};

// Creates non-inverted ECC code from line parity
Static void nand_trans_result (u_char reg2, u_char reg3, u_char * ecc_code)
{
U_char A, B, I, tmp1, tmp2;

/* Initialize variables */
A = B = 0x80;
Tmp1 = tmp2 = 0;

/* Calculate first ECC byte */
For (I = 0; I <4; I ++)
{
If (reg3 & A)/* lp15, 13, 11, 9 --> ecc_code [0] */
Tmp1 | = B;
B> = 1;
If (reg2 & A)/* lp14, 12, 10, 8 --> ecc_code [0] */
Tmp1 | = B;
B> = 1;
A> = 1;
}

/* Calculate second ECC byte */
B = 0x80;
For (I = 0; I <4; I ++)
{
If (reg3 & A)/* lp7, 5, 3, 1 --> ecc_code [1] */
Tmp2 | = B;
B> = 1;
If (reg2 & A)/* lp6, 4,2, 0 --> ecc_code [1] */
Tmp2 | = B;
B> = 1;
A> = 1;
}

/* Store two of the ECC bytes */
Ecc_code [0] = tmp1;
Ecc_code [1] = tmp2;
}

// Calculate 3 byte ECC code for 256 byte Block
Void nand_calculate_ecc (const u_char * dat, u_char * ecc_code)
{
U_char idx, reg1, reg2, reg3;
Int J;

/* Initialize variables */
Reg1 = reg2 = reg3 = 0;
Ecc_code [0] = ecc_code [1] = ecc_code [2] = 0;

/* Build up column parity */
For (j = 0; j <256; j ++)
{

/* Get cp0-cp5 from table */
Idx = nand_ecc_precalc_table [dat [J];
Reg1 ^ = (idx & 0x3f );

/* All bit XOR = 1? */
If (idx & 0x40 ){
Reg3 ^ = (u_char) J;
Reg2 ^ = ~ (U_char) J );
}
}

/* Create non-inverted ECC code from line parity */
Nand_trans_result (reg2, reg3, ecc_code );

/* Calculate final ECC Code */
Ecc_code [0] = ~ Ecc_code [0];
Ecc_code [1] = ~ Ecc_code [1];
Ecc_code [2] = ((~ Reg1) <2) | 0x03;
}

// Detect and correct a 1 bit error for 256 byte Block
Int nand_correct_data (u_char * dat, u_char * read_ecc, u_char * calc_ecc)
{
U_char A, B, C, D1, D2, D3, add, bit, I;

/* Do error detection */
D1 = calc_ecc [0] ^ read_ecc [0];
D2 = calc_ecc [1] ^ read_ecc [1];
D3 = calc_ecc [2] ^ read_ecc [2];

If (d1 | D2 | D3) = 0)
{
/* No errors */
Return 0;
}
Else
{
A = (d1 ^ (D1> 1) & 0x55;
B = (D2 ^ (D2> 1) & 0x55;
C = (D3 ^ (D3> 1) & 0x54;

/* Found and will correct single bit error in the Data */
If (A = 0x55) & (B = 0x55) & (C = 0x54 ))
{
C = 0x80;
Add = 0;
A = 0x80;
For (I = 0; I <4; I ++)
{
If (d1 & C)
Add | =;
C> = 2;
A> = 1;
}
C = 0x80;
For (I = 0; I <4; I ++)
{
If (D2 & C)
Add | =;
C> = 2;
A> = 1;
}
Bit = 0;
B = 0x04;
C = 0x80;
For (I = 0; I <3; I ++)
{
If (D3 & C)
Bit | = B;
C> = 2;
B> = 1;
}
B = 0x01;
A = dat [add];
A ^ = (B <bit );
Dat [add] =;
Return 1;
}
Else
{
I = 0;
While (D1)
{
If (d1 & 0x01)
++ I;
D1> = 1;
}
While (D2)
{
If (D2 & 0x01)
++ I;
D2> = 1;
}
While (D3)
{
If (D3 & 0x01)
++ I;
D3> = 1;
}
If (I = 1)
{
/* ECC code error correction */
Read_ecc [0] = calc_ecc [0];
Read_ecc [1] = calc_ecc [1];
Read_ecc [2] = calc_ecc [2];
Return 2;
}
Else
{
/* Uncorrectable Error */
Return-1;
}
}
}

/* Shocould never happen */
Return-1;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.