/*****************************************************************************/
/* */
/* PROJECT : ECC for 256byte */
/* FILE : ECC.c */
/* PURPOSE : This file implements core ECC algorithms adopted */
/* Hamming Error Correction and Detection Algorithm */
/* */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/* */
/* NOTES */
/* */
/* - Make ECC parity code of 256bytes is represented */
/* And ECC compare & Correction code is also represented */
/* */
/*****************************************************************************/
££i nclude <stdio.h>
££i nclude <conio.h>
££i nclude <stdlib.h>
££i nclude <time.h>
££i nclude <sys/timeb.h>
££i nclude <string.h>
/*****************************************************************************/
/* Address Types */
/*****************************************************************************/
typedef unsigned char *address_t; /* address (pointer) */
typedef unsigned long address_value_t; /* address (for calculation) */
typedef unsigned long ULONG; /* address (for calculation) */
typedef unsigned int uint;
typedef unsigned char uchar;
/*****************************************************************************/
/* Integer Types */
/*****************************************************************************/
typedef unsigned int uint32_t; /* unsigned 4 byte integer */
typedef signed int int32_t; /* signed 4 byte integer */
typedef unsigned short uint16_t; /* unsigned 2 byte integer */
typedef signed short int16_t; /* signed 2 byte integer */
typedef unsigned char uint8_t; /* unsigned 1 byte integer */
typedef signed char int8_t; /* signed 1 byte integer */
typedef unsigned int UINT32; /* unsigned 4 byte integer */
typedef unsigned char UINT8; /* unsigned 1 byte integer */
typedef signed int INT32; /* signed 4 byte integer */
typedef unsigned int UINT; /* unsigned 4 byte integer */
typedef signed int INT; /* signed 4 byte integer */
typedef unsigned short USHORT; /* unsigned 2 byte integer */
typedef signed short SHORT; /* signed 2 byte integer */
typedef unsigned char UCHAR; /* unsigned 1 byte integer */
typedef signed char CHAR; /* signed 1 byte integer */
UCHAR ecc_gen[3];
typedef enum {
ECC_NO_ERROR = 0, /* no error */
ECC_CORRECTABLE_ERROR = 1, /* one bit data error */
ECC_ECC_ERROR = 2, /* one bit ECC error */
ECC_UNCORRECTABLE_ERROR = 3 /* uncorrectable error */
} eccdiff_t;
void make_ecc_256(unsigned char*, unsigned char*);
eccdiff_t compare_ecc(unsigned char*, unsigned char*, unsigned char*, int, unsigned char);
/*****************************************************************************/
/* */
/* NAME */
/* make_ecc_256 */
/* DESCRIPTION */
/* This function generates 3 byte ECC for 512 byte data. */
/* (Software ECC) */
/* PARAMETERS */
/* ecc_buf the location where ECC should be stored */
/* data_buf given data */
/* RETURN VALUES */
/* none */
/* */
/*****************************************************************************/
void make_ecc_256(unsigned char* ecc_buf, unsigned char* data_buf)
{
unsigned int i;
unsigned int tmp;
unsigned int uiparity = 0;
unsigned int parityCol, ecc = 0;
unsigned int parityCol4321 = 0, parityCol4343 = 0, parityCol4242 = 0, parityColTot = 0;
unsigned int* Data = (unsigned int*)(data_buf);
unsigned int Xorbit=0;
for( i = 0; i < 8; i++)
{
parityCol = *Data++;
tmp = *Data++; parityCol ^= tmp; parityCol4242 ^= tmp;
tmp = *Data++; parityCol ^= tmp; parityCol4343 ^= tmp;
tmp = *Data++; parityCol ^= tmp; parityCol4343 ^= tmp; parityCol4242 ^= tmp;
tmp = *Data++; parityCol ^= tmp; parityCol4321 ^= tmp;
tmp = *Data++; parityCol ^= tmp; parityCol4242 ^= tmp; parityCol4321 ^= tmp;
tmp = *Data++; parityCol ^= tmp; parityCol4343 ^= tmp; parityCol4321 ^= tmp;
tmp = *Data++; parityCol ^= tmp; parityCol4242 ^= tmp; parityCol4343 ^= tmp; parityCol4321 ^= tmp;
parityColTot ^= parityCol;
tmp = (parityCol >> 16) ^ parityCol;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = ((tmp >> 2) ^ tmp) & 0x03;
if ((tmp == 0x01) || (tmp == 0x02))
{
uiparity ^= i;
Xorbit ^= 0x01;
}
}
tmp = (parityCol4321 >> 16) ^ parityCol4321;
tmp = (tmp << 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x200; // p128
tmp = (parityCol4343 >> 16) ^ parityCol4343;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x80; // p64
tmp = (parityCol4242 >> 16) ^ parityCol4242;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x20; // p32
tmp = parityColTot & 0xFFFF0000;
tmp = tmp >> 16;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x08; // p16
tmp = parityColTot & 0xFF00FF00;
tmp = (tmp >> 16) ^ tmp;
tmp = (tmp >> 8);
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp >> 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x02; // p8
tmp = parityColTot & 0xF0F0F0F0 ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= ((tmp << 1) ^ tmp) & 0x800000; // p4
tmp = parityColTot & 0xCCCCCCCC ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp << 4) ^ tmp;
tmp = (tmp >> 2);
ecc |= ((tmp << 1) ^ tmp) & 0x200000; // p2
tmp = parityColTot & 0xAAAAAAAA ;
tmp = (tmp << 16) ^ tmp;
tmp = (tmp >> 8) ^ tmp;
tmp = (tmp >> 4) ^ tmp;
tmp = (tmp << 2) ^ tmp;
ecc |= (tmp & 0x80000); // p1
ecc |= (uiparity & 0x01) <<11; // parit256_1
ecc |= (uiparity & 0x02) <<12; // parit512_1
ecc |= (uiparity & 0x04) <<13; // parit1024_1
if (Xorbit)
{
ecc |= (ecc ^ 0x00A8AAAA)>>1;
}
else
{
ecc |= (ecc >> 1);
}
ecc = ~ecc;
*(ecc_buf + 2) = (unsigned char) (ecc >> 16);
*(ecc_buf + 1) = (unsigned char) (ecc >> 8);
*(ecc_buf + 0) = (unsigned char) (ecc);
}
/*****************************************************************************/
/* */
/* NAME */
/* compare_ecc_256 */
/* DESCRIPTION
评论0