📄 hamming.c
字号:
** 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 + -