#include <stdio.h>
#include <stdint.h>
void decode_bch_bin(uint16_t enc, uint16_t* dec);
void decodebch_bi1(int *bits, int *decbits);
uint32_t getbitu(uint8_t* buff, uint32_t pos, uint32_t len);
void bits2byte(int *bits, int nbits, int nbin, int right, uint8_t *bin);
union bch_reg{
uint8_t val;
struct {
uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
} bits;
};
int main(void) {
int32_t bits[15] = {1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1};
int32_t bits_res[15];
uint16_t dec = 0, bin = 0x5555;
decodebch_bi1(bits, bits_res);
decode_bch_bin(bin , &dec);
{
int i = 0;
for(i = 0; i < 15; i++) {
}
}
return 0;
}
void decode_bch_bin(uint16_t enc, uint16_t* dec)
{
union bch_reg reg;
uint8_t i, bit;
uint16_t err[15] = {0, 1, 2, 16, 4, 256, 32, 1024, 8, 16384, 512, 128,
64, 8192, 2048, 4096};
/* see Table 5.2 */
uint8_t ind = 0;
/* BCH decoding (Fig 5-4) */
for (i = 0; i < 15; i++) {
bit = reg.bits.b3;
reg.bits.b3 = reg.bits.b2;
reg.bits.b2 = reg.bits.b1;
reg.bits.b1 = reg.bits.b0;
reg.bits.b0 = (enc & (1 << i))^bit;
reg.bits.b1 ^= bit;
}
printf("reg val = %u\n", reg.
val); /*error correction*/
enc ^= err[reg.val];
*dec = enc;
}
void decodebch_bi1(int *bits, int *decbits)
{
int i,bit,err,reg[4]={1,1,1,1};
int errind[15]={14,13,10,12,6,9,4,11,0,5,7,8,1,3,2}; /* see Table 5.2 */
uint8_t bin;
/* copy input to output */
for (i=0;i<15;i++) decbits[i]=bits[i];
/* BCH decoding (Fig 5-4) */
for (i=0;i<15;i++) {
bit=reg[3];
reg[3]=reg[2]; reg[2]=reg[1]; reg[1]=reg[0];
reg[0]=bits[i]*bit;
reg[1]*=bit;
}
/* get error index */
bits2byte(reg,4,1,0,&bin);
printf("bin = %u\n", getbitu
(&bin
,0,4)); err=errind[getbitu(&bin,0,4)]; /* error index */
/* error correction */
if (err>0) decbits[err-1]*=-1;
}
void bits2byte(int *bits, int nbits, int nbin, int right, uint8_t *bin)
{
int i,j,rem,bitscpy[8192]={0};
unsigned char b;
rem=8*nbin-nbits;
memcpy(&bitscpy
[right
?rem
:0],bits
,sizeof(int)*nbits
);
for (i=0;i<nbin;i++) {
b=0;
for (j=0;j<8;j++) {
b<<=1;
if (bitscpy[i*8+j]<0) b|=0x01; /* -1=>1, 1=>0 */
}
bin[i]=b;
}
}
uint32_t getbitu(uint8_t* buff, uint32_t pos, uint32_t len)
{
uint32_t i, bits=0;
for (i = pos; i < pos + len; i++) {
bits = (bits << 1) + ((buff[i/8] >> (7 - i%8)) & 1u);
}
return bits;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRpbnQuaD4KCnZvaWQgZGVjb2RlX2JjaF9iaW4odWludDE2X3QgZW5jLCB1aW50MTZfdCogZGVjKTsKdm9pZCBkZWNvZGViY2hfYmkxKGludCAqYml0cywgaW50ICpkZWNiaXRzKTsKdWludDMyX3QgZ2V0Yml0dSh1aW50OF90KiBidWZmLCB1aW50MzJfdCBwb3MsIHVpbnQzMl90IGxlbik7CnZvaWQgYml0czJieXRlKGludCAqYml0cywgaW50IG5iaXRzLCBpbnQgbmJpbiwgaW50IHJpZ2h0LCB1aW50OF90ICpiaW4pOwoKdW5pb24gYmNoX3JlZ3sKICAgIHVpbnQ4X3QgdmFsOwogICAgc3RydWN0IHsKICAgICAgICB1aW50OF90IGIwOjE7CiAgICAgICAgdWludDhfdCBiMToxOwogICAgICAgIHVpbnQ4X3QgYjI6MTsKICAgICAgICB1aW50OF90IGIzOjE7CiAgICB9IGJpdHM7Cn07CgppbnQgbWFpbih2b2lkKSB7CglpbnQzMl90IGJpdHNbMTVdID0gezEsLTEsMSwtMSwxLC0xLDEsLTEsMSwtMSwxLC0xLDEsLTEsMX07CglpbnQzMl90IGJpdHNfcmVzWzE1XTsKCXVpbnQxNl90IGRlYyA9IDAsIGJpbiA9IDB4NTU1NTsKCWRlY29kZWJjaF9iaTEoYml0cywgYml0c19yZXMpOwoJZGVjb2RlX2JjaF9iaW4oYmluICwgJmRlYyk7Cgl7CgkJaW50IGkgPSAwOwoJCWZvcihpID0gMDsgaSA8IDE1OyBpKyspIHsKCQkJcHJpbnRmKCIgJWQiLGJpdHNfcmVzW2ldKTsKCQl9Cgl9CglwcmludGYoIlxuJXgiLGRlYyk7CglyZXR1cm4gMDsKfQoKdm9pZCBkZWNvZGVfYmNoX2Jpbih1aW50MTZfdCBlbmMsIHVpbnQxNl90KiBkZWMpCnsKICAgIHVuaW9uIGJjaF9yZWcgcmVnOwogICAgdWludDhfdCBpLCBiaXQ7CiAgICB1aW50MTZfdCBlcnJbMTVdID0gezAsIDEsIDIsIDE2LCA0LCAyNTYsIDMyLCAxMDI0LCA4LCAxNjM4NCwgNTEyLCAxMjgsIAogICAgICAgICAgICAgICAgICAgICAgICA2NCwgODE5MiwgMjA0OCwgNDA5Nn07IAogICAgLyogc2VlIFRhYmxlIDUuMiAqLwogICAgdWludDhfdCBpbmQgPSAwOwoKICAgIC8qIEJDSCBkZWNvZGluZyAoRmlnIDUtNCkgKi8KICAgIGZvciAoaSA9IDA7IGkgPCAxNTsgaSsrKSB7CiAgICAgICAgYml0ID0gcmVnLmJpdHMuYjM7CiAgICAgICAgcmVnLmJpdHMuYjMgPSByZWcuYml0cy5iMjsKICAgICAgICByZWcuYml0cy5iMiA9IHJlZy5iaXRzLmIxOwogICAgICAgIHJlZy5iaXRzLmIxID0gcmVnLmJpdHMuYjA7CiAgICAgICAgcmVnLmJpdHMuYjAgPSAoZW5jICYgKDEgPDwgaSkpXmJpdDsKICAgICAgICByZWcuYml0cy5iMSBePSBiaXQ7CiAgICB9CiAgICBwcmludGYoInJlZyB2YWwgPSAldVxuIiwgcmVnLnZhbCk7CiAgICAvKmVycm9yIGNvcnJlY3Rpb24qLwogICAgZW5jIF49IGVycltyZWcudmFsXTsKCiAgICAqZGVjID0gZW5jOwp9CgoKdm9pZCBkZWNvZGViY2hfYmkxKGludCAqYml0cywgaW50ICpkZWNiaXRzKQp7CiAgICBpbnQgaSxiaXQsZXJyLHJlZ1s0XT17MSwxLDEsMX07CiAgICBpbnQgZXJyaW5kWzE1XT17MTQsMTMsMTAsMTIsNiw5LDQsMTEsMCw1LDcsOCwxLDMsMn07IC8qIHNlZSBUYWJsZSA1LjIgKi8KICAgIHVpbnQ4X3QgYmluOwoKICAgIC8qIGNvcHkgaW5wdXQgdG8gb3V0cHV0ICovCiAgICBmb3IgKGk9MDtpPDE1O2krKykgZGVjYml0c1tpXT1iaXRzW2ldOwoKICAgIC8qIEJDSCBkZWNvZGluZyAoRmlnIDUtNCkgKi8KICAgIGZvciAoaT0wO2k8MTU7aSsrKSB7CiAgICAgICAgYml0PXJlZ1szXTsKICAgICAgICByZWdbM109cmVnWzJdOyByZWdbMl09cmVnWzFdOyByZWdbMV09cmVnWzBdOwogICAgICAgIHJlZ1swXT1iaXRzW2ldKmJpdDsKICAgICAgICByZWdbMV0qPWJpdDsKICAgIH0KICAgIC8qIGdldCBlcnJvciBpbmRleCAqLwogICAgYml0czJieXRlKHJlZyw0LDEsMCwmYmluKTsKICAgIHByaW50ZigiYmluID0gJXVcbiIsIGdldGJpdHUoJmJpbiwwLDQpKTsKICAgIGVycj1lcnJpbmRbZ2V0Yml0dSgmYmluLDAsNCldOyAvKiBlcnJvciBpbmRleCAqLwogICAgCiAgICAvKiBlcnJvciBjb3JyZWN0aW9uICovCiAgICBpZiAoZXJyPjApIGRlY2JpdHNbZXJyLTFdKj0tMTsKfQoKdm9pZCBiaXRzMmJ5dGUoaW50ICpiaXRzLCBpbnQgbmJpdHMsIGludCBuYmluLCBpbnQgcmlnaHQsIHVpbnQ4X3QgKmJpbikKewogICAgaW50IGksaixyZW0sYml0c2NweVs4MTkyXT17MH07CiAgICB1bnNpZ25lZCBjaGFyIGI7CiAgICByZW09OCpuYmluLW5iaXRzOwoKICAgIG1lbWNweSgmYml0c2NweVtyaWdodD9yZW06MF0sYml0cyxzaXplb2YoaW50KSpuYml0cyk7CgogICAgZm9yIChpPTA7aTxuYmluO2krKykgewogICAgICAgIGI9MDsKICAgICAgICBmb3IgKGo9MDtqPDg7aisrKSB7CiAgICAgICAgICAgIGI8PD0xOwogICAgICAgICAgICBpZiAoYml0c2NweVtpKjgral08MCkgYnw9MHgwMTsgLyogLTE9PjEsIDE9PjAgKi8KICAgICAgICB9CiAgICAgICAgYmluW2ldPWI7CiAgICB9Cn0KCnVpbnQzMl90IGdldGJpdHUodWludDhfdCogYnVmZiwgdWludDMyX3QgcG9zLCB1aW50MzJfdCBsZW4pCnsKICAgIHVpbnQzMl90IGksIGJpdHM9MDsKICAgIGZvciAoaSA9IHBvczsgaSA8IHBvcyArIGxlbjsgaSsrKSB7CiAgICAgICAgYml0cyA9IChiaXRzIDw8IDEpICsgKChidWZmW2kvOF0gPj4gKDcgLSBpJTgpKSAmIDF1KTsKICAgIH0KICAgIHJldHVybiBiaXRzOwp9