diff --git a/ecc/bch_ecc.c b/ecc/bch_ecc.c index 2a96788..e16798c 100644 --- a/ecc/bch_ecc.c +++ b/ecc/bch_ecc.c @@ -104,6 +104,9 @@ static RS_t RS256 = { 255, 12, 24, 231, 0, 1, 1, {0}}; static RS_t RS256ccsds = { 255, 16, 32, 223, 112, 11, 116, {0}}; static RS_t BCH64 = { 63, 2, 12, 51, 1, 1, 1, {0}}; +static RS_t RS16_0 = { 15, 3, 6, 9, 0, 1, 1, {0}}; +//static RS_t RS16_1 = { 15, 3, 6, 9, 1, 1, 1, {0}}; + static GF_t GF; static RS_t RS; @@ -810,13 +813,38 @@ int rs_init_BCH64() { return check_gen; } +int rs_init_RS15() { + int i, check_gen; + ui8_t Xalp[MAX_DEG+1]; + + GF = GF16RS; + check_gen = GF_genTab( GF, exp_a, log_a); + + RS = RS16_0; // N=15, t=3, b=0, p=1 + //RS = RS16_1; // N=15, t=3, b=1, p=1 + for (i = 0; i <= MAX_DEG; i++) RS.g[i] = 0; + for (i = 0; i <= MAX_DEG; i++) Xalp[i] = 0; + + // g(X)=(X-alpha^b)...(X-alpha^(b+2t-1)) + RS.g[0] = 0x01; + Xalp[1] = 0x01; // X + for (i = 0; i < 2*RS.t; i++) { + Xalp[0] = exp_a[(RS.b+i) % (GF.ord-1)]; // Xalp[0..1]: X - alpha^(b+i) + poly_mul(RS.g, Xalp, RS.g); + } + + return check_gen; +} + int rs_encode(ui8_t cw[]) { int j; - ui8_t parity[MAX_DEG+1], + ui8_t __cw[MAX_DEG+1], + parity[MAX_DEG+1], d[MAX_DEG+1]; - for (j = 0; j < RS.R; j++) cw[j] = 0; for (j = 0; j <= MAX_DEG; j++) parity[j] = 0; - poly_divmod(cw, RS.g, d, parity); + for (j = 0; j <= MAX_DEG; j++) __cw[j] = 0; + for (j = RS.R; j < RS.N; j++) __cw[j] = cw[j]; + poly_divmod(__cw, RS.g, d, parity); //if (poly_deg(parity) >= RS.R) return -1; for (j = 0; j <= poly_deg(parity); j++) cw[j] = parity[j]; return 0; diff --git a/ecc/ecc-rs_gf16.c b/ecc/ecc-rs_gf16.c new file mode 100644 index 0000000..b61bf5d --- /dev/null +++ b/ecc/ecc-rs_gf16.c @@ -0,0 +1,262 @@ + +/* + GF(2^4) - RS(15,9) + (no bit-packing, i.e. 1 nibble <-> 1 byte) + +a) + ka9q-fec: + gcc -c init_rs_char.c + gcc -c encode_rs_char.c + gcc -c decode_rs_char.c + + gcc -DKA9Q ecc-rs_gf16.c init_rs_char.o encode_rs_char.o decode_rs_char.o -o ecc-rs15 + +b) + gcc ecc-rs_gf16.c -o ecc-rs15 + +*/ + + +#include +#include + +#ifdef KA9Q + #include "fec.h" +#endif + + +typedef unsigned char ui8_t; +typedef unsigned int ui32_t; + +#include "bch_ecc.c" + + +#define BFSIZE 512 +#define rs_N 15 +#define rs_R 6 +#define rs_K (rs_N-rs_R) + +ui8_t data[BFSIZE]; + +ui8_t cw[rs_N+1]; // cw[MAX_DEG+1]; // fixed in encode() ... +ui8_t par[rs_N], msg[rs_N]; +int errs; +ui8_t err_pos[rs_R], err_val[rs_R]; + +#ifdef KA9Q + void *rs; + ui8_t codeword[rs_N]; + int errors, errpos[rs_R]; +#endif + + +int main(int argc, char *argv[]) { + int i, l; + + int len1, len2; + char *str1 = NULL, + *str2 = NULL; + + + rs_init_RS15(); // 0x13: X^4 + X + 1 + +#ifdef KA9Q + rs = init_rs_char( 4, 0x13, 0, 1, 6, 0); // RS16_0 + //rs = init_rs_char( 4, 0x13, 1, 1, 6, 0); // RS16_1 +#endif + + if (argv[0] == NULL) return -1; + + for (i = 0; i < BFSIZE; i++) data[i] = 0; + for (i = 0; i < rs_N; i++) cw[i] = 0; +#ifdef KA9Q + for (i = 0; i < rs_N; i++) codeword[i] = 0; +#endif + + + str1 = argv[1]; + + len1 = strlen(str1); + if (len1 > BFSIZE) return -1; + + for (i = 0; i < len1; i++) { + l = sscanf(str1+i, "%1hhx", data+i); if (l < 1) {/*len1 = i;*/} + } + // 1byte/nibble + + + for (i = 0; i < rs_K; i++) cw[rs_R+i] = data[i]; // codeword[rs_N-1-i] = cw[i]; + + for (i = 0; i < rs_N; i++) msg[i] = 0; + for (i = 0; i < rs_N; i++) par[i] = 0; + for (i = 0; i < rs_K; i++) msg[i] = data[rs_K-1-i]; + + +// +// GF(16) %02X -> %1X (1 nibble / 1 byte) +// printf("%1X", cw[i]); // dbg: printf("%02X", cw[i]); +// printf("%1X", cw[i]&0xF); // dbg: printf("%02X", cw[i]); +// + + + printf("\n"); + + if (argv[2]) { + + str2 = argv[2]; + len2 = strlen(str2); + if (len2 > rs_R) len2 = rs_R; + + for (i = 0; i < len2; i++) { + l = sscanf(str2+i, "%1hhx", par+i); if (l < 1) {/*len2 = i;*/} + } + while (i < rs_R) par[i++] = 0; + + for (i = 0; i < rs_N; i++) cw[i] = 0; + for (i = 0; i < rs_R; i++) cw[i] = par[i]; + for (i = 0; i < len1; i++) cw[rs_R+i] = msg[rs_K-1-i]; + + +#ifdef KA9Q + for (i = 0; i < rs_N; i++) codeword[rs_N-1-i] = cw[i]; +#endif + + printf("msg: "); + for (i = rs_R; i < rs_N; i++) printf("%1X", cw[i]); // dbg: printf("%02X", cw[i]); + printf("\n"); + printf("par: "); + for (i = 0; i < rs_R; i++) printf("%1X", cw[i]); printf("\n"); + printf("\n"); + + + printf("cw\n"); + errs = rs_decode(cw, err_pos, err_val); + printf("errs: %d\n", errs); + if (errs > 0) { + printf("pos: "); + for (i = 0; i < errs; i++) printf(" %d", err_pos[i]); + printf("\n"); + } + for (i = 0; i < rs_N; i++) printf("%1X", cw[i]); printf("\n"); + + +#ifdef KA9Q + printf("\n"); + + printf("codeword\n"); + errors = decode_rs_char(rs, codeword, errpos, 0); + printf("errors: %d\n", errors); + if (errors > 0) { + printf("pos: "); + for (i = 0; i < errors; i++) printf(" %d", errpos[i]); + printf("\n"); + } + for (i = 0; i < rs_N; i++) printf("%1X", codeword[i]); printf("\n"); +#endif + + } else { + + printf("msg: "); + for (i = rs_R; i < rs_N; i++) printf("%1X", cw[i]); // dbg: printf("%02X", cw[i]); + printf("\n"); + printf("\n"); + + + printf("cw\n"); + rs_encode(cw); + printf("par: "); + for (i = 0; i < rs_R; i++) printf("%1X", cw[i]); printf("\n"); + printf("cw-enc:\n"); + for (i = 0; i < rs_N; i++) { + //if (i == rs_R) printf(" "); + printf("%1X", cw[i]); + } + printf("\n"); + + // check + errs = rs_decode(cw, err_pos, err_val); + if (errs) { + printf("errs: %d\n", errs); + printf("cw-dec:\n"); + for (i = 0; i < rs_N; i++) { + //if (i == rs_R) printf(" "); + printf("%1X", cw[i]); + } + printf("\n"); + } + + +#ifdef KA9Q + printf("\n"); + + printf("codeword\n"); + printf("message: "); + for (i = 0; i < rs_K; i++) printf("%1x", msg[i]); printf("\n"); + encode_rs_char(rs, msg, par); + printf("parity : "); + for (i = 0; i < rs_R; i++) printf("%1x", par[i]); printf("\n"); + + for (i = 0; i < rs_K; i++) codeword[i] = msg[i]; + for (i = 0; i < rs_R; i++) codeword[rs_K+i] = par[i]; + printf("codeword:\n"); + for (i = 0; i < rs_N; i++) printf("%1x", codeword[i]); printf("\n"); +#endif + + } + + + printf("\n"); + + return 0; +} + + +/* + +RS(15,9): + codeword length 15 + message length 9 + parity length 6 + +./ecc-rs15 str1 [str2] + str1: 9 nibbles (msg) + str2: 6 nibbles (par) + +ecc-rs15 input/output: nibbles +cw[]: 1 byte / 1 nibble + + +examples: + +$./ecc-rs15 000000001 + +msg: 000000001 + +cw +par: 342FA1 +cw-enc: +342FA1000000001 + +codeword +message: 100000000 +parity : 1af243 +codeword: +1000000001af243 + + +$./ecc-rs15 000000001 342FA1 + +msg: 000000001 +par: 342FA1 + +cw +errs: 0 +342FA1000000001 + +codeword +errors: 0 +1000000001AF243 + +*/ + +