📄 newecc2k.c
字号:
/****************** (c) 1999 STMicroelectronics *****************************
PROJECT : ST7265 USB Mass Storage - SMC
VERSION : SMC_ECC.c 1.0 Beta2
CREATION DATE : 20/03/2001
AUTHOR : CMG / ST Rousset
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
MODIFICATIONS :
******************************************************************************/
#include "Map_7265.h"
#include "MAL_Map.h"
#include "2K_Mass.h" // Parameter exchange area
#pragma DATA_SEG DEFAULT_RAM
extern const unsigned char Bit_Mask[8];
static unsigned char ECC1; // LP15,LP14,LP13,...
static unsigned char ECC2; // LP07,LP06,LP05,...
static unsigned char ECC3; // CP5,CP4,CP3,...,"1","1"
static unsigned char *ECC_Data;
#pragma CODE_SEG SMC_CODE
#define NEW_VER
//#define OLD_VER
/*-----------------------------------------------------------------------------
ROUTINE NAME : SMC_Correct_data
INPUT/OUTPUT :
DESCRIPTION : None
-----------------------------------------------------------------------------*/
#ifdef NEW_VER
unsigned char SMC_Correct_data(unsigned char flag) {
unsigned char Add, Bit;
unsigned char d1, d2, d3;
asm LD flag, A
d1 = ECC2 ^ ECC_Data[1];
d2 = ECC1 ^ ECC_Data[0]; // Compare LP's
d3 = ECC3 ^ ECC_Data[2]; // Compare CP's
if (d3 == 0 && d2 == 0 && d1 == 0)
return 0; // if no error, return
asm {
LD A, d1
SRL A
XOR A, d1
LD Bit, A
BTJF Bit,#0,not_correctable
BTJF Bit,#2,not_correctable
BTJF Bit,#4,not_correctable
BTJF Bit,#6,not_correctable
LD A, d2
SRL A
XOR A, d2
LD Bit, A
BTJF Bit,#0,not_correctable
BTJF Bit,#2,not_correctable
BTJF Bit,#4,not_correctable
BTJF Bit,#6,not_correctable
LD A, d3
SRL A
XOR A, d3
LD Bit, A
BTJF Bit,#2,not_correctable
BTJF Bit,#4,not_correctable
BTJF Bit,#6,not_correctable
}
correction_algorithm:
Add = 0;
if (d1 & 0x80)
Add |= 0x80;
if (d1 & 0x20)
Add |= 0x40;
if (d1 & 0x08)
Add |= 0x20;
if (d1 & 0x02)
Add |= 0x10;
if (d2 & 0x80)
Add |= 0x08;
if (d2 & 0x20)
Add |= 0x04;
if (d2 & 0x08)
Add |= 0x02;
if (d2 & 0x02)
Add |= 0x01;
Bit = 0;
if (d3 & 0x80)
Bit |= 0x04;
else if (d3 & 0x40)
Bit |= 0x00;
if (d3 & 0x20)
Bit |= 0x02;
if (d3 & 0x08)
Bit |= 0x01;
// data[Add] ^= Bit_Mask[Bit]; // Put corrected data
asm {
LD X, Bit
LD A, (Bit_Mask, X) // Bit_Mask[Bit]
LD X, Add
BTJT flag,#0,buffer1_correct
BTJT flag,#1,buffer01_correct
XOR A,(Buffer_0, X)
LD (Buffer_0, X), A
JRT data_corrected
buffer01_correct:
XOR A,(Buffer_0:256,X)
LD (Buffer_0:256,X), A
JRT data_corrected
buffer1_correct:
BTJT flag,#1,buffer11_correct
XOR A,(Buffer_1,X)
LD (Buffer_1,X), A
JRT data_corrected
buffer11_correct:
XOR A,(Buffer_1:256,X)
LD (Buffer_1:256,X), A
data_corrected:
}
/* if (flag & 1)
if (flag & 2)
Buffer_1[256 + Add] ^= Bit_Mask[Bit]; // Put corrected data
else
Buffer_1[Add] ^= Bit_Mask[Bit]; // Put corrected data
else
if (flag & 2)
Buffer_0[256 + Add] ^= Bit_Mask[Bit]; // Put corrected data
else
Buffer_0[Add] ^= Bit_Mask[Bit]; // Put corrected data
*/
return 1;
asm {
count_bits0:
SRL A
JRNC count_bits
INC X
TNZ A
count_bits:
JRNE count_bits0
RET
not_correctable:
CLR X
LD A, d1
CALLR count_bits
LD A, d2
CALLR count_bits
LD A, d3
CALLR count_bits
DEC X
JREQ ECC_Error
}
return 3;
asm {
ECC_Error:
}
// Put the right ECC code
ECC_Data[1]=ECC2;
ECC_Data[0]=ECC1;
ECC_Data[2]=ECC3;
return(2);
}
#endif // NEW_VER
#pragma DATA_SEG DEFAULT_RAM
/*-----------------------------------------------------------------------------
ROUTINE NAME : SMC_ECC_Correct
INPUT/OUTPUT : None
DESCRIPTION : None
-----------------------------------------------------------------------------*/
//#pragma NO_OVERLAP
unsigned char SMC_ECC_Correct(char ECC_Buff_Nb)
{
static unsigned char result1, result2;
ECC1 = Buffer_Param[SMC_ECC_Calc];
ECC2 = Buffer_Param[SMC_ECC_Calc + 1];
ECC3 = Buffer_Param[SMC_ECC_Calc + 2];
ECC_Data = Spare_Area.ECC_Field_1;
result1 = SMC_Correct_data(ECC_Buff_Nb & 0x01);
ECC1 = Buffer_Param[SMC_ECC_Calc + 3];
ECC2 = Buffer_Param[SMC_ECC_Calc + 4];
ECC3 = Buffer_Param[SMC_ECC_Calc + 5];
ECC_Data = Spare_Area.ECC_Field_2;
result2 = SMC_Correct_data((ECC_Buff_Nb & 0x01) | 0x02);
return ((result1 < 3) && (result2 < 3)); // BOOL
}
#ifdef OLD_VER
unsigned char SMC_Correct_data(volatile unsigned char *data, unsigned char *eccdata)
{
unsigned long l; /* Working to check d */
unsigned long d; /* Result of comparison */
unsigned short i; /* For counting */
unsigned char d1,d2,d3; /* Result of comparison */
unsigned char a; /* Working for add */
unsigned char add; /* Byte address of cor. DATA */
unsigned char b; /* Working for bit */
unsigned char bit; /* Bit address of cor. DATA */
d1=ECC2^eccdata[1]; d2=ECC1^eccdata[0]; /* Compare LP's */
d3=ECC3^eccdata[2]; /* Comapre CP's */
d=((unsigned long)d1<<16) /* Result of comparison */
+((unsigned long)d2<<8)
+(unsigned long)d3;
if (d==0) return(0); /* If No error, return */
if (((d^(d>>1))&CORRECTABLE)==CORRECTABLE) { /* If correctable */
l=BIT23;
add=0; /* Clear parameter */
a=BIT7;
for(i=0; i<8; ++i) { /* Checking 8 bit */
if ((d&l)!=0) add|=a; /* Make byte address from LP's */
l>>=2; a>>=1; /* Right Shift */
}
bit=0; /* Clear parameter */
b=BIT2;
for(i=0; i<3; ++i) { /* Checking 3 bit */
if ((d&l)!=0) bit|=b; /* Make bit address from CP's */
l>>=2; b>>=1; /* Right shift */
}
b=BIT0;
data[add]^=(b<<bit); /* Put corrected data */
return(1);
}
i=0; /* Clear count */
d&=0x00ffffffL; /* Masking */
while(d) { /* If d=0 finish counting */
if (d&BIT0) ++i; /* Count number of 1 bit */
d>>=1; /* Right shift */
}
if (i==1) { /* If ECC error */
eccdata[1]=ECC2; eccdata[0]=ECC1; /* Put right ECC code */
eccdata[2]=ECC3;
return(2);
}
return(3); /* Uncorrectable error */
}
#endif // OLD_VER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -