SLC的那算法我是看明白了的
就是下面这段代码里面有部分没看明白
下面是代码,原帖地址在http://blog.2@1ic.com/user1/3633/33493.html#
ECC算法的实现
??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 reg2 怎么的就跟j来运算出来就是行累加啊 /* // 下面的注释里面的值是我根据nand_trans_result函数倒推出来的 BIT7 BIT7 BIT7 BIT7 BIT7 BIT7 BIT7 BIT7 reg2 !P64’ !P32’ !P16’ !P8’ !P1024’ !P512’ !P256’ !P128’ reg3 !P64 !P32 !P16 !P8 !P1024 !P512 !P256 !P128 */ ????????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 |= a; ??????????c >>= 2;
??????????a >>= 1;
????????}
????????c = 0x80;
????????for (i=0; i<4; i++) ????????{ ??????????if (d2 & c) ????????????add |= a; ??????????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] = a; ????????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;
????????}
??????}
????}
????/* Should never happen */
????return -1;
??}