📄 ecc256.c
字号:
//----------------------------------------------------
//Copyright (C), 2004-2009, 网络.
//版权所有 (C), 2004-2009, 网络.
//所属模块:flash文件系统
//作者:网络
//版本:V1.0.0
//文件描述:flash文件系统中ECC校验部分
//其他说明:
//修订历史:
// 2. ...
// 1. 日期:
// 作者:
// 新版本号:
// 修改说明:
//------------------------------------------------------
#include "inc_os.h"
#include "ecc256.h"
const uint8_t ecc_table[] = {
0x00,0x55,0x59,0x0c,0x65,0x30,0x3c,0x69,0x69,0x3c,0x30,0x65,0x0c,0x59,0x55,0x00,
0x95,0xc0,0xcc,0x99,0xf0,0xa5,0xa9,0xfc,0xfc,0xa9,0xa5,0xf0,0x99,0xcc,0xc0,0x95,
0x99,0xcc,0xc0,0x95,0xfc,0xa9,0xa5,0xf0,0xf0,0xa5,0xa9,0xfc,0x95,0xc0,0xcc,0x99,
0x0c,0x59,0x55,0x00,0x69,0x3c,0x30,0x65,0x65,0x30,0x3c,0x69,0x00,0x55,0x59,0x0c,
0xa5,0xf0,0xfc,0xa9,0xc0,0x95,0x99,0xcc,0xcc,0x99,0x95,0xc0,0xa9,0xfc,0xf0,0xa5,
0x30,0x65,0x69,0x3c,0x55,0x00,0x0c,0x59,0x59,0x0c,0x00,0x55,0x3c,0x69,0x65,0x30,
0x3c,0x69,0x65,0x30,0x59,0x0c,0x00,0x55,0x55,0x00,0x0c,0x59,0x30,0x65,0x69,0x3c,
0xa9,0xfc,0xf0,0xa5,0xcc,0x99,0x95,0xc0,0xc0,0x95,0x99,0xcc,0xa5,0xf0,0xfc,0xa9,
0xa9,0xfc,0xf0,0xa5,0xcc,0x99,0x95,0xc0,0xc0,0x95,0x99,0xcc,0xa5,0xf0,0xfc,0xa9,
0x3c,0x69,0x65,0x30,0x59,0x0c,0x00,0x55,0x55,0x00,0x0c,0x59,0x30,0x65,0x69,0x3c,
0x30,0x65,0x69,0x3c,0x55,0x00,0x0c,0x59,0x59,0x0c,0x00,0x55,0x3c,0x69,0x65,0x30,
0xa5,0xf0,0xfc,0xa9,0xc0,0x95,0x99,0xcc,0xcc,0x99,0x95,0xc0,0xa9,0xfc,0xf0,0xa5,
0x0c,0x59,0x55,0x00,0x69,0x3c,0x30,0x65,0x65,0x30,0x3c,0x69,0x00,0x55,0x59,0x0c,
0x99,0xcc,0xc0,0x95,0xfc,0xa9,0xa5,0xf0,0xf0,0xa5,0xa9,0xfc,0x95,0xc0,0xcc,0x99,
0x95,0xc0,0xcc,0x99,0xf0,0xa5,0xa9,0xfc,0xfc,0xa9,0xa5,0xf0,0x99,0xcc,0xc0,0x95,
0x00,0x55,0x59,0x0c,0x65,0x30,0x3c,0x69,0x69,0x3c,0x30,0x65,0x0c,0x59,0x55,0x00,
};
uint32_t ecc_count_bits(uint8_t x)
{
uint32_t r = 0;
while(x)
{
if(x & 1) r++;
x >>= 1;
}
return r;
}
//----计算ecc值----------------------------------------------------------------
//功能: 产生ecc效验码
//参数: data : 要效验的数据首地址
// ecc : 存放ecc效验的首地址
//返回: 无
//----------------------------------------------------------------------------
void ecc_make_256(const uint8_t *data,uint8_t *ecc)
{
uint32_t i;
uint8_t col_parity = 0;
uint8_t line_parity = 0;
uint8_t line_parity_prime = 0;
uint8_t t;
uint8_t b;
for(i = 0; i < 256; i++)
{
b = ecc_table[*data++];
col_parity ^= b;
if(b & 0x01)
{
line_parity ^= i;
line_parity_prime ^= ~i;
}
}
ecc[2] = (~col_parity) | 0x03;
t = 0;
if(line_parity & 0x80) t |= 0x80;
if(line_parity_prime & 0x80) t |= 0x40;
if(line_parity & 0x40) t |= 0x20;
if(line_parity_prime & 0x40) t |= 0x10;
if(line_parity & 0x20) t |= 0x08;
if(line_parity_prime & 0x20) t |= 0x04;
if(line_parity & 0x10) t |= 0x02;
if(line_parity_prime & 0x10) t |= 0x01;
ecc[1] = ~t;
t = 0;
if(line_parity & 0x08) t |= 0x80;
if(line_parity_prime & 0x08) t |= 0x40;
if(line_parity & 0x04) t |= 0x20;
if(line_parity_prime & 0x04) t |= 0x10;
if(line_parity & 0x02) t |= 0x08;
if(line_parity_prime & 0x02) t |= 0x04;
if(line_parity & 0x01) t |= 0x02;
if(line_parity_prime & 0x01) t |= 0x01;
ecc[0] = ~t;
t = ecc[0];
ecc[0] = ecc[1];
ecc[1] = t;
}
//----ecc检测并修正数据-------------------------------------------------------
//功能: ecc检测并修正数据
//参数: data : 检测的数据
// old_ecc : 之前效验的ecc
//返回: 0 : 正确
// 1 : 数据被修正
// 2 : 之前效验的ecc是错误的
// -1: 数据无法恢复
//----------------------------------------------------------------------------
uint32_t ecc_corect_256(uint8_t *data, const uint8_t *old_ecc)
{
uint8_t d0, d1, d2;
uint8_t new_ecc[3];
ecc_make_256(data,new_ecc);
d0 = old_ecc[0] ^ new_ecc[0];
d1 = old_ecc[1] ^ new_ecc[1];
d2 = old_ecc[2] ^ new_ecc[2];
if((d0 | d1 | d2) == 0)
{
return 0;
}
if( ((d0 ^ (d0 >> 1)) & 0x55) == 0x55 )
if( ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 )
if( ((d2 ^ (d2 >> 1)) & 0x54) == 0x54 )
{
unsigned byte;
unsigned bit;
uint8_t t;
t = d0;
d0 = d1;
d1 = t;
bit = byte = 0;
if(d1 & 0x80) byte |= 0x80;
if(d1 & 0x20) byte |= 0x40;
if(d1 & 0x08) byte |= 0x20;
if(d1 & 0x02) byte |= 0x10;
if(d0 & 0x80) byte |= 0x08;
if(d0 & 0x20) byte |= 0x04;
if(d0 & 0x08) byte |= 0x02;
if(d0 & 0x02) byte |= 0x01;
if(d2 & 0x80) bit |= 0x04;
if(d2 & 0x20) bit |= 0x02;
if(d2 & 0x08) bit |= 0x01;
data[byte] ^= (1 << bit);
return 1;
}
if((ecc_count_bits(d0)+ecc_count_bits(d1)+ecc_count_bits(d2)) == 1)
{
return 2;
}
else
{
return -1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -