⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doc_ecc.c

📁 8051单片机系统中对DISKONCHIP的操作
💻 C
📖 第 1 页 / 共 2 页
字号:
    }
  }
  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 + -