📄 doc_ecc.lst
字号:
259 2 {
260 3 j++;
261 3 blocs[j] = blocs[i];
262 3 bvals[j] = bvals[i];
263 3 }
264 2 }
265 1 return j+1;
266 1 }
267
268 /*----------------------------------------------------------------------------*/
269 static short deg512( short x )
270 {
271 1 short i;
272 1 short l,m;
273 1
274 1 l = flog(x);
275 1 for( i=0;i<9;i++)
276 1 {
277 2 m = 0;
278 2 if( (l & 0x200) )
279 2 m = 1;
280 2 l = ( ( l << 1 ) & 0x3FF ) | m;
281 2 }
282 1 return alog(l);
283 1 }
284
285 /*----------------------------------------------------------------------------*/
286 static short decoder_for_2_errors( short s[], short lerr[], short verr[] )
287 {
288 1 /* decoder for correcting up to 2 errors */
289 1 short i,j,k,temp,delta;
290 1 short ind, x1, x2;
291 1 short r1, r2, r3, j1, j2;
292 1 short sigma1, sigma2;
293 1 short xu[10], ku[10];
294 1 short yd, yn;
295 1
296 1 ind = 0;
297 1 for(i=0;i<SYND_LEN;i++)
298 1 if( s[i] != 0 )
299 1 ind++; /* ind = number of nonzero syndrom symbols */
300 1
301 1 if( ind == 0 ) return 0; /* no errors */
302 1
303 1 if( ind < 4 )
C51 COMPILER V7.20 DOC_ECC 02/25/2005 14:20:20 PAGE 6
304 1 goto two_or_more_errors;
305 1
306 1 /* checking s1/s0 = s2/s1 = s3/s2 = alpha**j for some j */
307 1
308 1 r1 = gfdiv( s[1], s[0] );
309 1 r2 = gfdiv( s[2], s[1] );
310 1 r3 = gfdiv( s[3], s[2] );
311 1
312 1 if( r1 != r2 || r2 != r3)
313 1 goto two_or_more_errors;
314 1
315 1 j = flog(r1);
316 1 if( j > 414 )
317 1 goto two_or_more_errors;
318 1
319 1 lerr[0] = j;
320 1
321 1 /* pattern = (s0/s1)**(510+1) * s1
322 1 or
323 1 pattern = (s0/s1)**(512 - 1 ) * s1 */
324 1
325 1 temp = gfi( r1 );
326 1 {
327 2 int i;
328 2
329 2 for (i = 0; i < 9; i++)
330 2 temp = gfmul( temp, temp ); /* deg = 512 */
331 2 }
332 1
333 1 verr[0] = gfmul( gfmul(temp, r1), s[1] );
334 1
335 1 return 1; /* 1 error */
336 1
337 1 two_or_more_errors:
338 1
339 1 delta = gfmul( s[0], s[2] ) ^ gfmul( s[1], s[1] );
340 1
341 1 if( delta == 0 )
342 1 return -1; /* uncorrectable error */
343 1
344 1 temp = gfmul( s[1], s[3] ) ^ gfmul( s[2], s[2] );
345 1
346 1 if( temp == 0 )
347 1 return -1; /* uncorrectable error */
348 1
349 1 sigma2 = gfdiv( temp, delta );
350 1
351 1 temp = gfmul( s[1], s[2] ) ^ gfmul( s[0], s[3] );
352 1
353 1 if( temp == 0 )
354 1 return -1; /* uncorrectable error */
355 1
356 1 sigma1 = gfdiv( temp, delta );
357 1
358 1 k = gfdiv( sigma2, gfmul( sigma1, sigma1 ) );
359 1
360 1 unpack( k, 10, ku );
361 1
362 1 if( ku[2] != 0 )
363 1 return -1;
364 1
365 1 xu[4] = ku[9];
C51 COMPILER V7.20 DOC_ECC 02/25/2005 14:20:20 PAGE 7
366 1 xu[5] = ku[0] ^ ku[1];
367 1 xu[6] = ku[6] ^ ku[9];
368 1 xu[3] = ku[4] ^ ku[9];
369 1 xu[1] = ku[3] ^ ku[4] ^ ku[6];
370 1 xu[0] = ku[0] ^ xu[1];
371 1 xu[8] = ku[8] ^ xu[0];
372 1 xu[7] = ku[7] ^ xu[3] ^ xu[8];
373 1 xu[2] = ku[5] ^ xu[7] ^ xu[5] ^ xu[0];
374 1 xu[9] = 0;
375 1
376 1 x1 = pack( xu, 10 );
377 1 x2 = x1 | 1;
378 1
379 1 x1 = gfmul( sigma1, x1 );
380 1 x2 = gfmul( sigma1, x2 );
381 1
382 1
383 1 j1 = flog(x1);
384 1 j2 = flog(x2);
385 1
386 1 if( (j1 > 414) || (j2 > 414) )
387 1 return -1;
388 1
389 1 r1 = x1 ^ x2;
390 1 r2 = deg512( x1 );
391 1 temp = gfmul( x1, x1 );
392 1 r2 = gfdiv( r2, temp );
393 1 yd = gfmul( r2, r1 );
394 1
395 1 if( yd == 0 )
396 1 return -1;
397 1
398 1 yn = gfmul( s[0], x2 ) ^ s[1];
399 1 if( yn == 0 )
400 1 return -1;
401 1
402 1 verr[0] = gfdiv( yn, yd );
403 1
404 1 r2 = deg512( x2 );
405 1 temp = gfmul( x2, x2 );
406 1 r2 = gfdiv( r2, temp );
407 1 yd = gfmul( r2, r1 );
408 1
409 1 if( yd == 0 )
410 1 return -1;
411 1
412 1 yn = gfmul( s[0], x1 ) ^ s[1];
413 1 if( yn == 0 )
414 1 return -1;
415 1
416 1 verr[1] = gfdiv( yn, yd );
417 1
418 1 if( j1 > j2 ) {
419 2 lerr[0] = j2;
420 2 lerr[1] = j1;
421 2 temp = verr[0];
422 2 verr[0] = verr[1];
423 2 verr[1] = temp;
424 2 }
425 1 else
426 1 {
427 2 lerr[0] = j1;
C51 COMPILER V7.20 DOC_ECC 02/25/2005 14:20:20 PAGE 8
428 2 lerr[1] = j2;
429 2 }
430 1
431 1 return 2;
432 1 }
433
434 /*------------------------------------------------------------------------------*/
435 /* Function Name: flDecodeEDC */
436 /* Purpose......: Trys to correct errors. */
437 /* errorSyndrom[] should contain the syndrom as 5 bytes and one */
438 /* parity byte. (identical to the output of calcEDCSyndrom()). */
439 /* Upon returning, errorNum will contain the number of errors, */
440 /* errorLocs[] will contain error locations, and */
441 /* errorVals[] will contain error values (to be XORed with the */
442 /* data). */
443 /* Parity error is relevant only if there are other errors, and */
444 /* the EDC code fails parity check. */
445 /* NOTE! Only the first errorNum indexes of the above two arrays */
446 /* are relevant. The others contain garbage. */
447 /* Returns......: The error status. */
448 /* NOTE! If the error status is NO_EDC_ERROR upon return, ignore */
449 /* the value of the arguments. */
450 /*------------------------------------------------------------------------------*/
451 EDCstatus flDecodeEDC(char *errorSyndrom, char *errorsNum,
452 short errorLocs[3*T], short errorVals[3*T])
453 {
454 1 short noferr; /* number of errors */
455 1 short dec_parity; /* parity byte of decoded word */
456 1 short rec_parity; /* parity byte of received word */
457 1 short realsynd[SYND_LEN]; /* real syndrom calculated from residue */
458 1 short locators[T], /* error locators */
459 1 values[T]; /* error values */
460 1 short reg[SYND_LEN]; /* register for main division procedure */
461 1 int i;
462 1
463 1 RTLeightToTen(errorSyndrom, (unsigned short *)reg);
464 1 rec_parity = errorSyndrom[5] & 0xFF; /* The parity byte */
465 1
466 1 residue_to_syndrom(reg, realsynd);
467 1 noferr = decoder_for_2_errors(realsynd, locators, values);
468 1
469 1 if(noferr == 0)
470 1 return NO_EDC_ERROR; /* No error found */
471 1
472 1 if(noferr < 0) /* If an uncorrectable error was found */
473 1 return UNCORRECTABLE_ERROR;
474 1
475 1 for (i=0;i<noferr;i++)
476 1 locators[i] = N512 - 1 - locators[i];
477 1
478 1 *errorsNum = (char)convert_to_byte_patterns(locators, values, noferr, errorLocs, errorVals);
479 1
480 1 for(dec_parity=i=0; i < *errorsNum; i++)/* Calculate the parity for all the */
481 1 { /* errors found: */
482 2 if(errorLocs[i] <= 512)
483 2 dec_parity ^= errorVals[i];
484 2 }
485 1
486 1 if(dec_parity != rec_parity)
487 1 return UNCORRECTABLE_ERROR; /* Parity error */
488 1 else
489 1 return CORRECTABLE_ERROR;
C51 COMPILER V7.20 DOC_ECC 02/25/2005 14:20:20 PAGE 9
490 1 }
491
492 /*------------------------------------------------------------------------------*/
493 /* Function Name: flCheckAndFixEDC */
494 /* Purpose......: Decodes the EDC syndrom and fixs the errors if possible. */
495 /* block[] should contain 512 bytes of data. */
496 /* NOTE! Call this function only if errors where detected by */
497 /* syndCalc or by the ASIC module. */
498 /* Returns......: The error status. */
499 /*------------------------------------------------------------------------------*/
500 EDCstatus flCheckAndFixEDC(char *block, char *syndrom, char byteSwap)
501 {
502 1 char errorsNum;
503 1 short errorLocs[3*T];
504 1 short errorVals[3*T];
505 1 EDCstatus status;
506 1
507 1 status = flDecodeEDC(syndrom, &errorsNum, errorLocs, errorVals);
508 1
509 1 if(status == CORRECTABLE_ERROR) /* Fix the errors if possible */
510 1 {
511 2 int i;
512 2
513 2 for (i=0; i < errorsNum; i++)
514 2 if( (errorLocs[i] ^ byteSwap) < PAGE_SIZE ) /* Fix only in Data Area */
515 2 block[errorLocs[i] ^ byteSwap] ^= errorVals[i];
516 2
517 2 return NO_EDC_ERROR; /* All errors are fixed */
518 2 }
519 1 else
520 1 return status; /* Uncorrectable error */
521 1 }
522
523 #endif /* EDC_MODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -