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

📄 hamming.c

📁 ATMEL单片机可用的文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  ** bit 4: checksum of all odd 128-bit groups of 1st interleave plane
  ** bit 5: checksum of all odd 128-bit groups of 2nd interleave plane
  ** bit 6: checksum of all odd 128-bit groups of 3rd interleave plane
  ** bit 7: checksum of all odd 128-bit groups of 4th interleave plane
  */

  /*-------------------------------------------------------------------*/
  /* Calculate the "every 256 bits" checksums (every 32 longs).        */
  /*-------------------------------------------------------------------*/
  tmp.half[0] = (ui16)(every32[0].half[0] ^ every32[0].half[1]);
  tmp.byte[0] ^= tmp.byte[1];
  tmp.half[1] = (ui16)(every32[1].half[0] ^ every32[1].half[1]);
  tmp.byte[2] ^= tmp.byte[3];
  ecc[8] = (ui8)(NibXor[tmp.byte[0]] | (NibXor[tmp.byte[2]] << 4));
  /*
  ** ecc[8] contains
  ** bit 0: checksum of all even 256-bit groups of 1st interleave plane
  ** bit 1: checksum of all even 256-bit groups of 2nd interleave plane
  ** bit 2: checksum of all even 256-bit groups of 3rd interleave plane
  ** bit 3: checksum of all even 256-bit groups of 4th interleave plane
  ** bit 4: checksum of all odd 256-bit groups of 1st interleave plane
  ** bit 5: checksum of all odd 256-bit groups of 2nd interleave plane
  ** bit 6: checksum of all odd 256-bit groups of 3rd interleave plane
  ** bit 7: checksum of all odd 256-bit groups of 4th interleave plane
  */

  /*-------------------------------------------------------------------*/
  /* Calculate the "every 512 bits" checksums (every 64 longs).        */
  /*-------------------------------------------------------------------*/
  tmp.half[0] = (ui16)(every64[0].half[0] ^ every64[0].half[1]);
  tmp.byte[0] ^= tmp.byte[1];
  tmp.half[1] = (ui16)(every64[1].half[0] ^ every64[1].half[1]);
  tmp.byte[2] ^= tmp.byte[3];
  ecc[9] = (ui8)(NibXor[tmp.byte[0]] | (NibXor[tmp.byte[2]] << 4));
  /*
  ** ecc[9] contains
  ** bit 0: checksum of all even 512-bit groups of 1st interleave plane
  ** bit 1: checksum of all even 512-bit groups of 2nd interleave plane
  ** bit 2: checksum of all even 512-bit groups of 3rd interleave plane
  ** bit 3: checksum of all even 512-bit groups of 4th interleave plane
  ** bit 4: checksum of all odd 512-bit groups of 1st interleave plane
  ** bit 5: checksum of all odd 512-bit groups of 2nd interleave plane
  ** bit 6: checksum of all odd 512-bit groups of 3rd interleave plane
  ** bit 7: checksum of all odd 512-bit groups of 4th interleave plane
  */
}

/***********************************************************************/
/*   DecodeEcc: Correct 512 bytes of user data using specified ECC     */
/*                                                                     */
/*      Inputs: data = pointer to 512 bytes of user data               */
/*              ecc = original ECC encoding performed on data          */
/*                                                                     */
/*     Returns: 0 if decoding successful, else -1                      */
/*                                                                     */
/***********************************************************************/
int DecodeEcc(ui32 *data, const ui8 *ecc)
{
  int byte0 = 0, byte1 = 0, byte2 = 0, byte3 = 0, i;
  int bit0 = 0, bit1 = 0, bit2 = 0, bit3 = 0;
  int err0 = 0, err1 = 0, err2 = 0, err3 = 0;
  ui8 curr[10], diff, tmp_byte;

  /*-------------------------------------------------------------------*/
  /* Get the current parity for the data.                              */
  /*-------------------------------------------------------------------*/
  EncodeEcc(data, curr);

  /*-------------------------------------------------------------------*/
  /* Get the error byte and bit for all 4 interleavings.               */
  /*-------------------------------------------------------------------*/
  for (i = 9; i >= 0; --i)
  {
    /*-----------------------------------------------------------------*/
    /* Get the difference between the original and current parity.     */
    /*-----------------------------------------------------------------*/
    diff = (ui8)(ecc[i] ^ curr[i]);

    /*-----------------------------------------------------------------*/
    /* Do first interleaving.                                          */
    /*-----------------------------------------------------------------*/
    tmp_byte = (ui8)(diff & MASK1);

    /*-----------------------------------------------------------------*/
    /* If both bits, 0 and 4, are 1, uncorrectable error.              */
    /*-----------------------------------------------------------------*/
    if (tmp_byte == MASK1)
      return -1;

    /*-----------------------------------------------------------------*/
    /* Else if one of the bits is 1, correctable or code error.        */
    /*-----------------------------------------------------------------*/
    else if (tmp_byte)
    {
      /*---------------------------------------------------------------*/
      /* If no error recorded, set error to either correctable or code.*/
      /*---------------------------------------------------------------*/
      if (err0 == 0)
      {
        if (i == 9)
          err0 = CORRECTABLE;
        else
          err0 = CODE_ERROR;
      }

      /*---------------------------------------------------------------*/
      /* If bit 4 is set, odd, set error byte or bit number.           */
      /*---------------------------------------------------------------*/
      if (tmp_byte > 0x8)
      {
        if (i >= 3)
          byte0 |= (1 << (i - 3));
        else
          bit0 |= (1 << i);
      }
    }

    /*-----------------------------------------------------------------*/
    /* Else if correctable error recorded, switch to code_error.       */
    /*-----------------------------------------------------------------*/
    else if (err0 == CORRECTABLE)
      err0 = CODE_ERROR;

    /*-----------------------------------------------------------------*/
    /* Do second interleaving.                                         */
    /*-----------------------------------------------------------------*/
    tmp_byte = (ui8)(diff & MASK2);

    /*-----------------------------------------------------------------*/
    /* If both bits, 1 and 5, are 1, uncorrectable error.              */
    /*-----------------------------------------------------------------*/
    if (tmp_byte == MASK2)
      return -1;

    /*-----------------------------------------------------------------*/
    /* Else if one of the bits is 1, correctable or code error.        */
    /*-----------------------------------------------------------------*/
    else if (tmp_byte)
    {
      /*---------------------------------------------------------------*/
      /* If no error recorded, set error to either correctable or code.*/
      /*---------------------------------------------------------------*/
      if (err1 == 0)
      {
        if (i == 9)
          err1 = CORRECTABLE;
        else
          err1 = CODE_ERROR;
      }

      /*---------------------------------------------------------------*/
      /* If bit 5 is set, odd, set error byte or bit number.           */
      /*---------------------------------------------------------------*/
      if (tmp_byte > 0x8)
      {
        if (i >= 3)
          byte1 |= (1 << (i - 3));
        else
          bit1 |= (1 << i);
      }
    }

    /*-----------------------------------------------------------------*/
    /* Else if correctable error recorded, switch to code_error.       */
    /*-----------------------------------------------------------------*/
    else if (err1 == CORRECTABLE)
      err1 = CODE_ERROR;

    /*-----------------------------------------------------------------*/
    /* Do third interleaving.                                          */
    /*-----------------------------------------------------------------*/
    tmp_byte = (ui8)(diff & MASK3);

    /*-----------------------------------------------------------------*/
    /* If both bits, 2 and 6, are 1, uncorrectable error.              */
    /*-----------------------------------------------------------------*/
    if (tmp_byte == MASK3)
      return -1;

    /*-----------------------------------------------------------------*/
    /* Else if one of the bits is 1, correctable or code error.        */
    /*-----------------------------------------------------------------*/
    else if (tmp_byte)
    {
      /*---------------------------------------------------------------*/
      /* If no error recorded, set error to either correctable or code.*/
      /*---------------------------------------------------------------*/
      if (err2 == 0)
      {
        if (i == 9)
          err2 = CORRECTABLE;
        else
          err2 = CODE_ERROR;
      }

      /*---------------------------------------------------------------*/
      /* If bit 6 is set, odd, set error byte number.                  */
      /*---------------------------------------------------------------*/
      if (tmp_byte > 0x8)
      {
        if (i >= 3)
          byte2 |= (1 << (i - 3));
        else
          bit2 |= (1 << i);
      }
    }

    /*-----------------------------------------------------------------*/
    /* Else if correctable error recorded, switch to code_error.       */
    /*-----------------------------------------------------------------*/
    else if (err2 == CORRECTABLE)
      err2 = CODE_ERROR;

    /*-----------------------------------------------------------------*/
    /* Do fourth interleaving.                                         */
    /*-----------------------------------------------------------------*/
    tmp_byte = (ui8)(diff & MASK4);

    /*-----------------------------------------------------------------*/
    /* If both bits, 3 and 7, are 1, uncorrectable error.              */
    /*-----------------------------------------------------------------*/
    if (tmp_byte == MASK4)
      return -1;

    /*-----------------------------------------------------------------*/
    /* Else if one of the bits is 1, correctable or code error.        */
    /*-----------------------------------------------------------------*/
    else if (tmp_byte)
    {
      /*---------------------------------------------------------------*/
      /* If no error recorded, set error to either correctable or code.*/
      /*---------------------------------------------------------------*/
      if (err3 == 0)
      {
        if (i == 9)
          err3 = CORRECTABLE;
        else
          err3 = CODE_ERROR;
      }

      /*---------------------------------------------------------------*/
      /* If bit 7 is set, odd, set error byte or bit number.           */
      /*---------------------------------------------------------------*/
      if (tmp_byte > 0x8)
      {
        if (i >= 3)
          byte3 |= (1 << (i - 3));
        else
          bit3 |= (1 << i);
      }
    }

    /*-----------------------------------------------------------------*/
    /* Else if correctable error recorded, switch to code_error.       */
    /*-----------------------------------------------------------------*/
    else if (err3 == CORRECTABLE)
      err3 = CODE_ERROR;
  }

  /*-------------------------------------------------------------------*/
  /* Correct all correctable errors.                                   */
  /*-------------------------------------------------------------------*/
  if (err0 == CORRECTABLE)
    ((ui8 *)data)[4 * byte0 + bit0 / 2] ^= 1 << (4 * (bit0 % 2));
  if (err1 == CORRECTABLE)
    ((ui8 *)data)[4 * byte1 + bit1 / 2] ^= 1 << (4 * (bit1 % 2) + 1);
  if (err2 == CORRECTABLE)
    ((ui8 *)data)[4 * byte2 + bit2 / 2] ^= 1 << (4 * (bit2 % 2) + 2);
  if (err3 == CORRECTABLE)
    ((ui8 *)data)[4 * byte3 + bit3 / 2] ^= 1 << (4 * (bit3 % 2) + 3);
  return 0;
}
#endif /* INC_NAND_FS && NUM_FFS_VOLS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -