Sun Jun 27 2004 12:05, Maxim Polyanskiy wrote to Vladimir Vassilevsky:
MP> ðÏ BCH - ÔÙ ÉÍÅÌ × ×ÉÄÕ ÔÁÂÌÉÞÎÙÊ ÁÌÇÏÒÉÔÍ? äÁ ÏÎ × PIC ÎÅ ×ÌÅÚÅÔ, Á ÅÓÌÉ MP> É ×ÌÅÚÅÔ, ÔÏ ÎÅ ÆÁËÔ, ÞÔÏ ÒÁÄÉËÁÌØÎÏ ÂÙÓÔÒÅÅ ÔÁÍ ÂÕÄÅÔ ÒÁÂÏÔÁÔØ, ÐÒÏÝÅ MP> ×ÚÑÔØ ËÌÁÓÓÉÞÅÓËÕÀ ÍÅÔÏÄÉËÕ É ÏÐÔÉÍÉÚÉÒÏ×ÁÔØ ÅÅ ÄÏ ÐÏÒÏÓÑÞÅÇÏ ×ÉÚÇÁ. é ÎÅ MP> ÇÏ×ÏÒÉ ÞÔÏ ÐÉË ÏÔÓÔÏÊ, ÐÏÔÏÍÕ ÞÔÏ ÜÔÏ ÂÙÌÏ ÓÄÅÌÁÎÏ ÎÁ ÐÉËÅ ÅÝÅ ÄÏ ËÒÉÚÉÓÁ MP> 98 ÇÏÄÁ ;).
ñ ÎÅ ÇÏ×ÏÒÀ, ÞÔÏ PIC - ÏÔÓÔÏÊ (èÏÔÑ PIC, ËÏÎÅÞÎÏ ÖÅ, ÏÔÓÔÏÊ) ñ ÕÔ×ÅÒÖÄÁÀ, ÞÔÏ ÔÙ - ÐÉËÏÍÁÎ É ËÕÌØÈÁÃËÅÒ.
÷ÏÒÏÞÁÅÛØ ÂÉÔÉËÉ É ÂÁÊÔÉËÉ, ÒÁÚÂÉÒÁÅÛØÓÑ × ÐÏÄÓÔÒÏÅÞÎÙÈ ÓÅÒÄÅÞÎÉËÁÈ, Á ËÁÒÔÉÎÙ × ÃÅÌÏÍ - ÎÅ ×ÉÄÉÛØ.
óÐÅÃÉÁÌØÎÏ ÄÌÑ ÐÉËÏÍÁÎÏ× É ËÕÌØÈÁÃËÅÒÏ× ÐÒÉ×ÏÄÉÔÓÑ ÁÌÇÏÒÉÔÍ ËÏÒÒÅËÃÉÉ BCH ÎÁ ÏÓÎÏ×Å ÆÕÎËÃÉÊ úÅÈÁ, ËÏÔÏÒÙÊ ÐÏÑ×ÉÌÓÑ ÎÅ ÔÏ ÞÔÏ ÄÏ ËÒÉÚÉÓÁ, Á ÅÝÅ ÄÏ ÐÅÒÅÓÔÒÏÊËÉ. ðÒÅËÒÁÓÎÏ ×ÌÅÚÁÅÔ × 2051.
VLV
//**************** Invert bit at the position bitno ***************
void InvertBit(unsigned long int *bchword,unsigned char bitno) {
*bchword^=1lu<<bitno; }
//**************** Divide by polynom ******************************
unsigned char MakeSyndrome(unsigned long int x, unsigned char polynom) { unsigned char cntr; unsigned long int l_polynom;
x&=0xfffffffelu; // clear parity bit
l_polynom=((unsigned long int)polynom)<<27; // left align the polynom
// Calculate the syndrome
for(cntr=0;cntr<31;cntr++) { if(x&0x80000000lu) x=(x<<1)^l_polynom; else x<<=1; }
return (unsigned char)(x>>27); // right align the syndrome }
//******************* Correction itself *******************
unsigned char CorrectBCH(unsigned long int *bchword) { unsigned char sa,sb,parity,dist; unsigned long int ltmp;
// Syndrome A error position table
static unsigned char table_sa[32] = {
0x00,0x1b,0x1c,0x0e,0x1d,0x01,0x0f,0x07,
0x1e,0x19,0x02,0x17,0x10,0x04,0x08,0x13,
0x1f,0x06,0x1a,0x0d,0x03,0x12,0x18,0x16,
0x11,0x15,0x05,0x0c,0x09,0x0a,0x14,0x0b };
// Syndrome B error position table
static unsigned char table_sb[32] = {
0x00,0x1b,0x1c,0x10,0x1d,0x05,0x11,0x02,
0x1e,0x16,0x06,0x0c,0x12,0x14,0x03,0x19,
0x1f,0x0e,0x17,0x0a,0x07,0x08,0x0d,0x09,
0x13,0x18,0x15,0x0b,0x04,0x01,0x1a,0x0f };
// Distance between errors table
static unsigned char table_dist[32] = {
0xff,0xff,0xff,0x03,0xff,0xff,0x06,0x0b,
0xff,0xff,0xff,0xff,0x0c,0xff,0x09,0x08,
0xff,0x0e,0xff,0x0a,0xff,0xff,0xff,0x04,
0x07,0x05,0xff,0x02,0x0d,0x01,0x0f,0xff };
// Correction table [distance]
static unsigned char dist_correction_table[16] = {
0xff,0x13,0x06,0x1e,0x0b,0x03,0x1c,0x17,
0x15,0x11,0x05,0x14,0x18,0x0f,0x0e,0x19 };
ltmp=*bchword;
// Calculate syndromes A and B
sa=MakeSyndrome(ltmp,0x05); sb=MakeSyndrome(ltmp,0x1d);
// Calculate parity
ltmp^=ltmp>>16; ltmp^=ltmp>>8; ltmp^=ltmp>>4; ltmp^=ltmp>>2; ltmp^=ltmp>>1;
parity=(unsigned char)(ltmp&1);
// Check syndromes
if((sa==0)&&(sb!=0)) return 0xff; if((sb==0)&&(sa!=0)) return 0xff;
if((sa==0)&&(sb==0)) // If both syndromes are 0 (no code errors) { if(parity==0) return 0; // No errors
*bchword^=1; // Error in parity bit return 1; }
sa=table_sa[sa]; sb=table_sb[sb];
if(sa==sb) // If both syndromes are indicating one error { InvertBit(bchword,sa); if(parity) return 1; // One error
*bchword^=1; // Error in parity bit return 2; }
if(parity) return 0xff; // More then two errors - not correctable
dist=sa-sb;
if(dist&0x80) dist+=0x1f; // modulo 1f
dist=table_dist[dist]; // Find distance between errors
if(dist==0xff) return 0xff; // Not correctable
sa-=dist_correction_table[dist]; // Correct 1-st error location
if(sa&0x80) sa+=0x1f; // modulo 31
InvertBit(bchword,sa+1); // Correct 1-st error
sa+=dist; // Find 2-nd error location
if(sa>=31) sa-=31; // modulo 31
InvertBit(bchword,sa+1); // Correct 2-nd error
return 2; }
"There is no business other then show business " (c)