/*
文件名:EccTest.c
功 能:对2048个字节进行ECC检验
作 者:吕氏春秋8266 v1.0
函 数:CreatEccTabe 生成0~256数值的ECC码,
其中bit7=0,bit6=行检验码,bit5=p4_0,bit4=p4_1,bit3=p2_0,bit2=p2_1,bit1=p1_0,bit0=p1_1
*/
//用VC6编译通过
#include "stdio.h"
unsigned int BIT0(unsigned char x) { return (x&1)>>0;}
unsigned int BIT1(unsigned char x) { return (x&2)>>1;}
unsigned int BIT2(unsigned char x) { return (x&4)>>2;}
unsigned int BIT3(unsigned char x) { return (x&8)>>3;}
unsigned int BIT4(unsigned char x) { return (x&16)>>4;}
unsigned int BIT5(unsigned char x) { return (x&32)>>5;}
unsigned int BIT6(unsigned char x) { return (x&64)>>6;}
unsigned int BIT7(unsigned char x) { return (x&128)>>7;}
//生成256个字节的Ecc码
void CreatEccTabe(unsigned char *Ecc_Table)
{
unsigned int i;
unsigned char xData;
for (i=0;i<256;i++)
{
xData=0;
if(BIT1(i)^BIT3(i)^BIT5(i)^BIT7(i)) {xData|=0x1; } //bit0 P1_1
if(BIT0(i)^BIT2(i)^BIT4(i)^BIT6(i)) {xData|=0x2; } //bit1 P1_0
if(BIT2(i)^BIT3(i)^BIT6(i)^BIT7(i)) {xData|=0x4; } //bit2 P2_1
if(BIT0(i)^BIT1(i)^BIT4(i)^BIT5(i)) {xData|=0x8; } //bit3 P2_0
if(BIT4(i)^BIT5(i)^BIT6(i)^BIT7(i)) {xData|=0x10;} //bit4 P4_1
if(BIT0(i)^BIT1(i)^BIT2(i)^BIT3(i)) {xData|=0x20;} //bit5 P4_0
if(BIT0(i)^BIT1(i)^BIT2(i)^BIT3(i)^BIT4(i)^BIT5(i)^BIT6(i)^BIT7(i)) //bit6
{
xData|=0x40;
}
Ecc_Table[i]=xData;
}
}
/*
static const char Ecc_Table[256] = {
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
};
*/
/*
Ecc_Make生成2048个字节的ECC校验码,其中,list用来保存列检验码,row0,row1保存行检验码
bit10 bit9 bit8 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
row0为p8192_0 p4096_0 p2048_0 p1024_0 p512_0 p256_0 p128_0 p64_0 p32_0 p16_0 p8_0
row1为p8192_1 p4096_1 p2048_1 p1024_1 p512_1 p256_1 p128_1 p64_1 p32_1 p16_1 p8_1
说 明:s3c2440中ECC表如下:
BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
MECCN_0 P64_0 P64_1 P32_0 P32_1 P16_0 P16_1 P8_0 P8_1
MECCN_1 P1024_0 P1024_1 P512_0 P512_1 P256_0 P256_1 P128_0 P128_1
MECCN_2 P4_0 P4_1 P2_0 P2_1 P1_0 P1_1 P2048_0 P2048_1
MECCN_3 P8192_0 P8192_1 P4096_0 P4096_1 - - - -
*/
void Ecc_Make(unsigned char *pData,unsigned char *Ecc_Table,unsigned long *EccData0,unsigned long *EccData1)
{
unsigned int i,j;
unsigned char byte=0,list=0;
unsigned long row0=0,row1=0,temp=0 ;
for(i=0;i<2048;i++)
{
j=pData[i]; //得到要检验的数值
byte=Ecc_Table[j]; //查表得到ECC结果
list^=(byte&0x3f); //得到列检验码
if(byte&0x40) //判断第6位为行检验码
{
row0^=((~i)&0x7ff);
row1^=(i&0x7ff);
}
}
//将得到的校验码按s3c2440要求的格式排列
temp|=(row0&1)<<1 ; //p8_1->temp[0]
temp|=(row1&1)<<0 ; //p8_0->temp[1]
temp|=(row0&2)<<2 ; //p16_1->temp[2]
temp|=(row1&2)<<1 ; //p16_0->temp[3]
temp|=(row0&4)<<3 ; //p32_1->temp[4]
temp|=(row1&4)<<2 ; //p32_0->temp[5]
temp|=(row0&8)<<4 ; //p64_1->temp[6]
temp|=(row1&8)<<3 ; //p64_0->temp[7]
temp|=(row0&16)<<5 ; //p128_1->temp[8]
temp|=(row1&16)<<4 ; //p128_0->temp[9]
temp|=(row0&32)<<6 ; //p256_1->temp[10]
temp|=(row1&32)<<5 ; //p256_0->temp[11]
temp|=(row0&64)<<7 ; //p512_1->temp[12]
temp|=(row1&64)<<6 ; //p512_0->temp[13]
temp|=(row0&128)<<8 ; //p1024_1->temp[14]
temp|=(row1&128)<<7 ; //p1024_0->temp[15]
*EccData0=temp ;
temp=0;
temp=list<<2; //将列校验码加入到EccData1[2~7]
temp|=(row0&256)>>7 ; //p2048_1->temp[0]
temp|=(row1&256)>>8 ; //p2048_0->temp[1]
temp|=(row0&512)<<4 ; //p4096_1->temp[12]
temp|=(row1&512)<<3 ; //p4096_0->temp[13]
temp|=(row0&1024)<<5 ; //p8192_1->temp[14]
temp|=(row1&1024)<<4 ; //p8192_0->temp[15]
*EccData1=temp;
return;
}
/*得取ECC码中1的个数*/
unsigned long EccCheckNumber(unsigned long Err_Data0,unsigned long Err_Data1)
{
unsigned long i,number=0;
for(i=0;i<16;i++)
{
if(((Err_Data0>>i)&0x1)==1) number++;
if(((Err_Data1>>i)&0x1)==1) number++;
}
return number;
}
/*判断数据是否正确,返回值0,正确,1,有一位错误,可纠正 2,校验码错误3.错误,*/
unsigned long ErrCheckEcc(unsigned long *Ecc_data0,unsigned long *Ecc_data1,
unsigned long *Ecc_data2,unsigned long *Ecc_data3)
{
unsigned long Err_Data0,Err_Data1,Err_number,Ecc_Flag=0;
Err_Data0=(*Ecc_data0)^(*Ecc_data2);
Err_Data1=(*Ecc_data1)^(*Ecc_data3);
printf("Ecc Err_Data is 0x%x%x\n",Err_Data1,Err_Data0);
Err_number=EccCheckNumber(Err_Data0,Err_Data1);
if(Err_number==0) return 0;
if(Err_number==14) //一位数据错误,可修正
{
Ecc_Flag|=0x1; //错误码Ecc_Flag[1~0]
Ecc_Flag|=(Err_Data1&0x4)>>0; //p1_1->Ecc_Flag[2]
Ecc_Flag|=(Err_Data1&0x10)>>1; //p2_1->Ecc_Flag[3]
Ecc_Flag|=(Err_Data1&0x40)>>2; //p3_1->Ecc_Flag[4]
Ecc_Flag|=(Err_Data0&0x1)<<5; //p8_1->Ecc_Flag[5]
Ecc_Flag|=(Err_Data0&0x4)<<4; //p16_1->Ecc_Flag[6]
Ecc_Flag|=(Err_Data0&0x10)<<3; //p32_1->Ecc_Flag[7]
Ecc_Flag|=(Err_Data0&0x40)<<2; //p64_1->Ecc_Flag[8]
Ecc_Flag|=(Err_Data0&0x100)<<1; //p128_1->Ecc_Flag[9]
Ecc_Flag|=(Err_Data0&0x400)>>0; //p256_1->Ecc_Flag[10]
Ecc_Flag|=(Err_Data0&0x1000)>>1; //p512_1->Ecc_Flag[11]
Ecc_Flag|=(Err_Data0&0x4000)>>2; //p1024_1->Ecc_Flag[12]
Ecc_Flag|=(Err_Data1&0x1)<<13; //p2048_1->Ecc_Flag[13]
Ecc_Flag|=(Err_Data1&0x1000)<<2; //p4096_1->Ecc_Flag[14]
Ecc_Flag|=(Err_Data1&0x4000)<<1; //p8192_1->Ecc_Flag[15]
return Ecc_Flag;
}
if(Err_number==1) return 2; //校验码错误
return 3; //超过一位或其它错误,无法修正
}
- 1
- 2
前往页