📄 reedsol.c
字号:
LTRarrayEightToTen(block, (unsigned short *)packed_symbol); /* Calculate the parity value of the 512 */ /* bytes array, and store it in the 8 */ /* lsb of the 410'th 10-bit value: */ packed_symbol[410] |= (resolveParity(block, 512) & 0xFF); /* Calculate the EDC code: */ register_division(reg, packed_symbol, K512); /* Convert the EDC code from four */ /* 10-bit values, into five bytes: */ LTRtenToEight((unsigned short *)reg, code); /* Store the parity byte in the last */ /* element of code[]: */ code[5] = (char)(packed_symbol[410] & 0xFF);}/*------------------------------------------------------------------------------*//* Function Name: flCalcEDCSyndrom *//* Purpose......: Trys to detect errors. *//* block[] should contain 512 bytes of data. *//* code[] should contain the EDC code as 5 bytes, and one *//* parity byte (identical to the output of EDCencode::resolve()).*//* Upon returning errorSyndrom[] will contain the syndrom as *//* 5 bytes and one parity byte (identical to the input of *//* EDCdecode::resolve()). *//* Returns......: The error status. *//* NOTE! If the error status is NO_EDC_ERROR upon return, ignore *//* the value of the arguments. *//*------------------------------------------------------------------------------*/EDCstatus flCalcEDCSyndrom(char FAR1 *block, char code[6], char errorSyndrom[6]){ short nonZero, i; short residue[SYND_LEN]; short reg[SYND_LEN]; /* register for main division procedure */ /* Convert block[] into a 10-bit values */ /* array: */ LTRarrayEightToTen(block, (unsigned short *)packed_symbol); packed_symbol[410] |= code[5] & 0xFF; /* Copy the parity value from code[] */ /* into the 8 lsb of the 410'th */ /* 10-bit value */ /* Copy the EDC code into the last four */ /* 10-bit values of packed_symbol: */ LTReightToTen(code, (unsigned short *)&packed_symbol[411]); /* Calculate the syndrom (the result */ /* is in reg[]): */ register_division( reg, packed_symbol, N512 ); for(i=nonZero=0; i<SYND_LEN; i++) /* Chack if reg[] is all zeroes */ if(reg[i]) nonZero++; if(nonZero == 0) /* If reg[] is all zeroes, there is */ { /* no error */ return NO_EDC_ERROR; /* No error found */ } for( i = 0; i < SYND_LEN; i++ ) /* reverse the order of reg[] */ residue[SYND_LEN-1-i] = reg[ i ]; /* into residue[] */ /* Convert the syndrom (in residue[]) */ /* from four 10-bit values into five */ /* bytes: */ RTLtenToEight((unsigned short *)residue, errorSyndrom); /* Calculate the parity byte for the */ /* original 512 bytes plus the parity */ /* byte that was received in code[]: */ errorSyndrom[5] = resolveParity(block, 512) ^ (code[5] & 0xFF); return EDC_ERROR; /* An error was detected */}#endif /* EDC_IN_SOFTWARE *//*----------------------------------------------------------------------------*/static short convert_to_byte_patterns( short *locators, short *values, short noferr, short *blocs, short *bvals ){ static short mask[] = { 0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff }; short i,j,n, n0, n1, tmp; short n_bit, n_byte, k_bit, nb; for( i = 0, nb = 0; i< noferr; i++) { n = locators[i]; tmp = values[i]; n_bit = n *10 - 6 ; n_byte = n_bit >> 3; k_bit = n_bit - (n_byte<<3); n_byte++; if( k_bit == 7 ) { /* 3 corrupted bytes */ blocs[nb] = n_byte+1; bvals[nb++] = tmp & 1 ? 0x80 : 0; tmp >>= 1; blocs[nb] = n_byte; bvals[nb++] = tmp & 0xff; tmp >>= 8; bvals[nb++] = tmp & 0xff; } else { n0 = 8 - k_bit; n1 = 10 - n0; blocs[nb] = n_byte; bvals[nb++] = (tmp & mask[n1]) << (8 - n1); tmp >>= n1; blocs[nb] = n_byte - 1; bvals[nb++] = (tmp & mask[n0]); } } for( i = 0, j = -1; i < nb; i++ ) { if( bvals[i] == 0 ) continue; if( (blocs[i] == blocs[j]) && ( j>= 0 ) ) { bvals[j] |= bvals[i]; } else { j++; blocs[j] = blocs[i]; bvals[j] = bvals[i]; } } 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 FAR1 *block, char *syndrom, FLBoolean 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++) block[errorLocs[i] ^ byteSwap] ^= errorVals[i]; return NO_EDC_ERROR; /* All errors are fixed */ } else return status; /* Uncorrectable error */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -