📄 doc_ecc.c
字号:
}
}
return j+1;
}
/*----------------------------------------------------------------------------*/
static short deg512( short x )
{
short i;
short l,m;
l = flog(x);
for( i=0;i<9;i++)
{
m = 0;
if( (l & 0x200) )
m = 1;
l = ( ( l << 1 ) & 0x3FF ) | m;
}
return alog(l);
}
/*----------------------------------------------------------------------------*/
static short decoder_for_2_errors( short s[], short lerr[], short verr[] )
{
/* decoder for correcting up to 2 errors */
short i,j,k,temp,delta;
short ind, x1, x2;
short r1, r2, r3, j1, j2;
short sigma1, sigma2;
short xu[10], ku[10];
short yd, yn;
ind = 0;
for(i=0;i<SYND_LEN;i++)
if( s[i] != 0 )
ind++; /* ind = number of nonzero syndrom symbols */
if( ind == 0 ) return 0; /* no errors */
if( ind < 4 )
goto two_or_more_errors;
/* checking s1/s0 = s2/s1 = s3/s2 = alpha**j for some j */
r1 = gfdiv( s[1], s[0] );
r2 = gfdiv( s[2], s[1] );
r3 = gfdiv( s[3], s[2] );
if( r1 != r2 || r2 != r3)
goto two_or_more_errors;
j = flog(r1);
if( j > 414 )
goto two_or_more_errors;
lerr[0] = j;
/* pattern = (s0/s1)**(510+1) * s1
or
pattern = (s0/s1)**(512 - 1 ) * s1 */
temp = gfi( r1 );
{
int i;
for (i = 0; i < 9; i++)
temp = gfmul( temp, temp ); /* deg = 512 */
}
verr[0] = gfmul( gfmul(temp, r1), s[1] );
return 1; /* 1 error */
two_or_more_errors:
delta = gfmul( s[0], s[2] ) ^ gfmul( s[1], s[1] );
if( delta == 0 )
return -1; /* uncorrectable error */
temp = gfmul( s[1], s[3] ) ^ gfmul( s[2], s[2] );
if( temp == 0 )
return -1; /* uncorrectable error */
sigma2 = gfdiv( temp, delta );
temp = gfmul( s[1], s[2] ) ^ gfmul( s[0], s[3] );
if( temp == 0 )
return -1; /* uncorrectable error */
sigma1 = gfdiv( temp, delta );
k = gfdiv( sigma2, gfmul( sigma1, sigma1 ) );
unpack( k, 10, ku );
if( ku[2] != 0 )
return -1;
xu[4] = ku[9];
xu[5] = ku[0] ^ ku[1];
xu[6] = ku[6] ^ ku[9];
xu[3] = ku[4] ^ ku[9];
xu[1] = ku[3] ^ ku[4] ^ ku[6];
xu[0] = ku[0] ^ xu[1];
xu[8] = ku[8] ^ xu[0];
xu[7] = ku[7] ^ xu[3] ^ xu[8];
xu[2] = ku[5] ^ xu[7] ^ xu[5] ^ xu[0];
xu[9] = 0;
x1 = pack( xu, 10 );
x2 = x1 | 1;
x1 = gfmul( sigma1, x1 );
x2 = gfmul( sigma1, x2 );
j1 = flog(x1);
j2 = flog(x2);
if( (j1 > 414) || (j2 > 414) )
return -1;
r1 = x1 ^ x2;
r2 = deg512( x1 );
temp = gfmul( x1, x1 );
r2 = gfdiv( r2, temp );
yd = gfmul( r2, r1 );
if( yd == 0 )
return -1;
yn = gfmul( s[0], x2 ) ^ s[1];
if( yn == 0 )
return -1;
verr[0] = gfdiv( yn, yd );
r2 = deg512( x2 );
temp = gfmul( x2, x2 );
r2 = gfdiv( r2, temp );
yd = gfmul( r2, r1 );
if( yd == 0 )
return -1;
yn = gfmul( s[0], x1 ) ^ s[1];
if( yn == 0 )
return -1;
verr[1] = gfdiv( yn, yd );
if( j1 > j2 ) {
lerr[0] = j2;
lerr[1] = j1;
temp = verr[0];
verr[0] = verr[1];
verr[1] = temp;
}
else
{
lerr[0] = j1;
lerr[1] = j2;
}
return 2;
}
/*------------------------------------------------------------------------------*/
/* Function Name: flDecodeEDC */
/* Purpose......: Trys to correct errors. */
/* errorSyndrom[] should contain the syndrom as 5 bytes and one */
/* parity byte. (identical to the output of calcEDCSyndrom()). */
/* Upon returning, errorNum will contain the number of errors, */
/* errorLocs[] will contain error locations, and */
/* errorVals[] will contain error values (to be XORed with the */
/* data). */
/* Parity error is relevant only if there are other errors, and */
/* the EDC code fails parity check. */
/* NOTE! Only the first errorNum indexes of the above two arrays */
/* are relevant. The others contain garbage. */
/* Returns......: The error status. */
/* NOTE! If the error status is NO_EDC_ERROR upon return, ignore */
/* the value of the arguments. */
/*------------------------------------------------------------------------------*/
EDCstatus flDecodeEDC(char *errorSyndrom, char *errorsNum,
short errorLocs[3*T], short errorVals[3*T])
{
short noferr; /* number of errors */
short dec_parity; /* parity byte of decoded word */
short rec_parity; /* parity byte of received word */
short realsynd[SYND_LEN]; /* real syndrom calculated from residue */
short locators[T], /* error locators */
values[T]; /* error values */
short reg[SYND_LEN]; /* register for main division procedure */
int i;
RTLeightToTen(errorSyndrom, (unsigned short *)reg);
rec_parity = errorSyndrom[5] & 0xFF; /* The parity byte */
residue_to_syndrom(reg, realsynd);
noferr = decoder_for_2_errors(realsynd, locators, values);
if(noferr == 0)
return NO_EDC_ERROR; /* No error found */
if(noferr < 0) /* If an uncorrectable error was found */
return UNCORRECTABLE_ERROR;
for (i=0;i<noferr;i++)
locators[i] = N512 - 1 - locators[i];
*errorsNum = (char)convert_to_byte_patterns(locators, values, noferr, errorLocs, errorVals);
for(dec_parity=i=0; i < *errorsNum; i++)/* Calculate the parity for all the */
{ /* errors found: */
if(errorLocs[i] <= 512)
dec_parity ^= errorVals[i];
}
if(dec_parity != rec_parity)
return UNCORRECTABLE_ERROR; /* Parity error */
else
return CORRECTABLE_ERROR;
}
/*------------------------------------------------------------------------------*/
/* Function Name: flCheckAndFixEDC */
/* Purpose......: Decodes the EDC syndrom and fixs the errors if possible. */
/* block[] should contain 512 bytes of data. */
/* NOTE! Call this function only if errors where detected by */
/* syndCalc or by the ASIC module. */
/* Returns......: The error status. */
/*------------------------------------------------------------------------------*/
EDCstatus flCheckAndFixEDC(char *block, char *syndrom, char byteSwap)
{
char errorsNum;
short errorLocs[3*T];
short errorVals[3*T];
EDCstatus status;
status = flDecodeEDC(syndrom, &errorsNum, errorLocs, errorVals);
if(status == CORRECTABLE_ERROR) /* Fix the errors if possible */
{
int i;
for (i=0; i < errorsNum; i++)
if( (errorLocs[i] ^ byteSwap) < PAGE_SIZE ) /* Fix only in Data Area */
block[errorLocs[i] ^ byteSwap] ^= errorVals[i];
return NO_EDC_ERROR; /* All errors are fixed */
}
else
return status; /* Uncorrectable error */
}
#endif /* EDC_MODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -