📄 ecc.c
字号:
/*============================================================================
____________________________________________________________________________
______________________________________________
SSSS M M CCCC Standard Microsystems Corporation
S MM MM SSSS C Austin Design Center
SSS M M M S C 11000 N. Mopac Expressway
S M M SSS C Stonelake Bldg. 6, Suite 500
SSSS M M S CCCC Austin, Texas 78759
SSSS ______________________________________________
____________________________________________________________________________
Copyright(C) 1999, Standard Microsystems Corporation
All Rights Reserved.
This program code listing is proprietary to SMSC and may not be copied,
distributed, or used without a license to do so. Such license may have
Limited or Restricted Rights. Please refer to the license for further
clarification.
____________________________________________________________________________
Notice: The program contained in this listing is a proprietary trade
secret of SMSC, Hauppauge, New York, and is copyrighted
under the United States Copyright Act of 1976 as an unpublished work,
pursuant to Section 104 and Section 408 of Title XVII of the United
States code. Unauthorized copying, adaption, distribution, use, or
display is prohibited by this law.
____________________________________________________________________________
Use, duplication, or disclosure by the Government is subject to
restrictions as set forth in subparagraph(c)(1)(ii) of the Rights
in Technical Data and Computer Software clause at DFARS 52.227-7013.
Contractor/Manufacturer is Standard Microsystems Corporation,
80 Arkay Drive, Hauppauge, New York, 1178-8847.
____________________________________________________________________________
____________________________________________________________________________
ecc.c - smart media mass storage class implementation file
____________________________________________________________________________
comments tbd
____________________________________________________________________________
Revision History
Date Who Comment
________ ___ _____________________________________________________________
11/##/01 cds initial version
============================================================================*/
#include "project.h"
static code uint8 ecctable[256] = {
0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00,
0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00
};
static void _ecc_trans_result(uint8,uint8,uint8 *,uint8 *) reentrant ;
static uint8 _ecc_correct_data(uint8*, uint8* )reentrant ;
#define kbm_bit7 0x80
#define kbm_bit6 0x40
#define kbm_bit5 0x20
#define kbm_bit4 0x10
#define kbm_bit3 0x08
#define kbm_bit2 0x04
#define kbm_bit1 0x02
#define kbm_bit0 0x01
#define kbm_bit10 0x03
#define kbm_bit23 0x00800000L
#define kbm_cps 0x3f
#define kbm_correctable 0x00555554L
//------------------------------------------------------------------------------
// Transpose (de-interleave) result
// LP14,12,10,... & LP15,13,11,... -> LP15,14,13,... & LP7,6,5,..
//------------------------------------------------------------------------------
static void _ecc_trans_result(
uint8 reg2, /* LP14,LP12,LP10,... */
uint8 reg3, /* LP15,LP13,LP11,... */
uint8 *ecc1, /* LP15,LP14,LP13,... */
uint8 *ecc2) reentrant /* LP07,LP06,LP05,... */
{
uint8 a; /* Working for reg2,reg3 */
uint8 b; /* Working for ecc1,ecc2 */
uint8 i; /* For counting */
a=kbm_bit7; b=kbm_bit7; /* 80h=10000000b */
*ecc1=*ecc2=0; /* Clear ecc1,ecc2 */
for (i=0; i<4; ++i)
{
if ((reg3&a)!=0) *ecc1|=b; /* LP15,13,11,9 -> ecc1 */
b=b>>1; /* Right shift */
if ((reg2&a)!=0) *ecc1|=b; /* LP14,12,10,8 -> ecc1 */
b=b>>1; /* Right shift */
a=a>>1; /* Right shift */
}
b=kbm_bit7; /* 80h=10000000b */
for (i=0; i<4; ++i)
{
if ((reg3&a)!=0) *ecc2|=b; /* LP7,5,3,1 -> ecc2 */
b=b>>1; /* Right shift */
if ((reg2&a)!=0) *ecc2|=b; /* LP6,4,2,0 -> ecc2 */
b=b>>1; /* Right shift */
a=a>>1; /* Right shift */
}
}
xdata uint8 x_eccbuf[6];
xdata uint8 buf_ecc_lp_hi ; /* lp 15-8 */
xdata uint8 buf_ecc_lp_lo ; /* lp 7-0 */
xdata uint8 buf_ecc_cp ; /* cp 5-0, 1, 1 */
xdata uint8 ecc_lp_hi ; /* LP 15-8 */
xdata uint8 ecc_lp_lo ; /* LP 7-0 */
xdata uint8 ecc_cp ; /* CP 5-0,"1","1" */
//+----------------------------------------------------------------------
// Calculating ECC
// data[0-255] -> ecc1,ecc2,ecc3 using CP0-CP5 code table[0-255]
//-----------------------------------------------------------------------
void ecc_sw_calculate(uint8 *buf) reentrant
{
unsigned int i; /* For counting */
uint8 a; /* Working for table */
uint8 reg1; /* D-all,CP5,CP4,CP3,... */
uint8 reg2; /* LP14,LP12,L10,... */
uint8 reg3; /* LP15,LP13,L11,... */
reg1=reg2=reg3=0; /* Clear parameter */
for (i=0; i<256; ++i)
{
a=ecctable[buf[i]]; // lookup column parity code (CP0-CP5) from table */
reg1^=(a&kbm_cps); // XOR with a */
if ((a&kbm_bit6)!=0)
{ /* If D_all(all bit XOR) = 1 */
reg3^=(uint8)i; /* XOR with counter */
reg2^=~((uint8)i); /* XOR with inv. of counter */
}
}
// transpose LP14,12,10,... & LP15,13,11,... -> LP15,14,13,... & LP7,6,5,..
_ecc_trans_result(reg2,reg3,&ecc_lp_hi,&ecc_lp_lo);
// invert & store ecc calculation in global ecc registers
ecc_lp_hi=~(ecc_lp_hi);
ecc_lp_lo=~(ecc_lp_lo); /* Inv. lp */
ecc_cp=((~reg1)<<2)|kbm_bit10; /* Make TEL format */
}
//+----------------------------------------------------------------------
// "ecccor.c" _ecc_correct_data() modified
// data[256-258] --> eccdata[0-2]
//-----------------------------------------------------------------------
static xdata unsigned long _ecc_l; /* Working to check d */
static xdata unsigned long _ecc_d; /* Result of comparison */
static uint8 ecc_correct_data( uint8 *buf ) reentrant
{
unsigned int i; /* For counting */
uint8 d1,d2,d3; /* Result of comparison */
uint8 a; /* Working for add */
uint8 add; /* Byte address of cor. DATA */
uint8 b; /* Working for bit */
uint8 bitaddr; /* Bit address of cor. DATA */
/* Compare line parity */
d1=ecc_lp_hi^buf_ecc_lp_hi ;
d2=ecc_lp_lo^buf_ecc_lp_lo ;
/* Compare column parity's */
d3=ecc_cp^buf_ecc_cp;
/* Result of comparison */
_ecc_d=((unsigned long)d1<<16)+((unsigned long)d2<<8) +(unsigned long)d3;
if (_ecc_d==0)
return k_success ; /* If No error, return */
/* If correctable */
if (((_ecc_d^(_ecc_d>>1))&kbm_correctable)==kbm_correctable)
{
_ecc_l=kbm_bit23;
add=0; /* Clear parameter */
a=kbm_bit7;
for (i=0; i<8; ++i)
{
/* Checking 8 bit */
if ((_ecc_d&_ecc_l)!=0)
add|=a; /* Make byte address from LP's */
_ecc_l>>=2;
a>>=1; /* Right Shift */
}
bitaddr=0; /* Clear parameter */
b=kbm_bit2;
for (i=0; i<3; ++i)
{ /* Checking 3 bit */
if ((_ecc_d&_ecc_l)!=0)
bitaddr|=b; /* Make bit address from CP's */
_ecc_l>>=2;
b>>=1; /* Right shift */
}
b=kbm_bit0;
// TRACE2(191, ecc, 0, "single error bit in buffer. address byte.bit:%d.%d", add, bitaddr) ;
buf[add]^=(b<<bitaddr); /* Put corrected data */
return k_ecc_corrected_buf_err;
}
i=0;
_ecc_d&=0x00ffffffL;
while (_ecc_d)
{ /* If d=0 finish counting */
if (_ecc_d&kbm_bit0) ++i; /* Count number of 1 bit */
_ecc_d>>=1; /* Right shift */
}
if (i==1)
{
/* Put in correct ecc data */
buf_ecc_lp_hi=ecc_lp_hi;
buf_ecc_lp_lo=ecc_lp_lo;
buf_ecc_cp=ecc_cp;
return k_ecc_corrected_ecc_code_err ;
}
// TRACE0(214, ecc, 0, "uncorrectable error detected.") ;
return k_ecc_uncorrectable_err ; /* Uncorrectable error */
}
//-----------------------------------------------------------------------
// ##### End of 'ecctable.c' and 'ecccor.c' ###################################
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// name:
// t_result ecc_sw_correct()
//
// purpose:
// correct a 256-byte buffer of data, given read ecc and calculated ecc.
//
// notes:
// this function assumes that ecc_lp_hi, ecc_lp_lo, and ecc_cp
// contain the 'post-read calculated ecc'
//
// source:
//-----------------------------------------------------------------------
// t_result ecc_sw_correct(uint8 *buf, uint8 *buf_ecc, uint8* calc_ecc ) reentrant
#define _set_buf_ecc(__buffer_ecc_data) \
{ buf_ecc_lp_hi = __buffer_ecc_data[1];buf_ecc_lp_lo=__buffer_ecc_data[0];buf_ecc_cp=__buffer_ecc_data[2]; }
#define _get_buf_ecc(__buffer_ecc_data) \
{ __buffer_ecc_data[1]=buf_ecc_lp_hi; __buffer_ecc_data[0]=buf_ecc_lp_lo ;__buffer_ecc_data[2]=buf_ecc_cp; }
#define _set_ecc(__ecc_data) \
{ ecc_lp_hi = __ecc_data[1]; ecc_lp_lo = __ecc_data[0]; ecc_cp = __ecc_data[2] ; }
#define _get_ecc(__ecc_data) \
{ __ecc_data[1] = ecc_lp_hi; __ecc_data[0] = buf_ecc_lp_lo ; __ecc_data[2] = buf_ecc_cp; }
//+----------------------------------------------------------------------
//-----------------------------------------------------------------------
t_result ecc_sw_correct(uint8 *buf, uint8 *buf_ecc, uint8* calc_ecc ) reentrant
{
unsigned int err;
_set_buf_ecc(buf_ecc) ;
_set_ecc(calc_ecc) ;
/*
buf_ecc_lp_hi = buf_ecc[1] ;
buf_ecc_lp_lo = buf_ecc[0] ;
buf_ecc_cp = buf_ecc[2] ;
*/
// err=_ecc_correct_data(buf,redundant_ecc,*(calculate_ecc+1),*(calculate_ecc),*(calculate_ecc+2));
err=ecc_correct_data(buf) ;
/*
*(calc_ecc+1) = ecc_lp_hi ;
*(calc_ecc) = ecc_lp_lo ;
*(calc_ecc+2) = ecc_cp ;
*/
_get_ecc(calc_ecc) ;
if (err==1)
{
_get_buf_ecc(buf_ecc) ;
}
if (err==0 || err==1 || err==2)
return k_success ;
return k_error ;
}
//+----------------------------------------------------------------------
//-----------------------------------------------------------------------
t_result ecc_sw_correct_ex(uint8 *buf ) reentrant
{
unsigned int err;
err=ecc_correct_data(buf) ;
if (err==k_ecc_corrected_buf_err)
{
buf_ecc_lp_hi = ecc_lp_hi ;
buf_ecc_lp_lo = ecc_lp_lo ;
buf_ecc_cp = ecc_cp ;
}
return ( k_ecc_uncorrectable_err == err) ? k_error : k_success ;
}
//+----------------------------------------------------------------------
//-----------------------------------------------------------------------
t_result ecc_check_rd_error() reentrant
{
// return ((buff_ecc_a == ecc_a)&&(buff_ecc_b == ecc_b));
if (! memcmp((char *)(x_sm_redt_data+0x0D),(char *) x_eccbuf,3))
if (! memcmp((char *)(x_sm_redt_data+0x08),(char *)(x_eccbuf+0x03),3))
return k_success;
return k_error ;
}
//+----------------------------------------------------------------------
//-----------------------------------------------------------------------
t_result ecc_check_and_correct(unsigned char *buf) reentrant
{
// check first 256 bytes against first 3 ecc parameters
if (memcmp((char *)(x_sm_redt_data+0x0D),(char *)x_eccbuf,3))
if (ecc_sw_correct(buf,x_sm_redt_data+0x0D,x_eccbuf))
return k_error ;
// check second 256 bytes agains second 3 ecc parameters
buf+=0x100;
if (memcmp((char *)(x_sm_redt_data+0x08),(char *)(x_eccbuf+0x03),3))
if (ecc_sw_correct(buf,x_sm_redt_data+0x08,x_eccbuf+0x03))
return k_error ;
return k_success;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -