From 0f206fb2ecfc94e67866755a9b4ad70d6affc074 Mon Sep 17 00:00:00 2001 From: geozak Date: Tue, 18 Oct 2016 21:38:16 -0800 Subject: [PATCH] Add error correction code Added golay code and implemented for our project. --- Golay/golay.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++ Golay/golay.h | 71 +++++++++++++ Golay/reciever.c | 72 +++++++++++++ Golay/sender.c | 63 +++++++++++ README.md | 5 +- 5 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 Golay/golay.c create mode 100644 Golay/golay.h create mode 100644 Golay/reciever.c create mode 100644 Golay/sender.c diff --git a/Golay/golay.c b/Golay/golay.c new file mode 100644 index 0000000..e417d5b --- /dev/null +++ b/Golay/golay.c @@ -0,0 +1,271 @@ +/* File: golay.c + * Title: Encoder/decoder for a binary (23,12,7) Golay code + * Author: Max Luttrell (luttrell@icsl.ucla.edu), + * Date: October 1997 + * + * based on work done by: + * Author: Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) + * Date: August 1994 + * + * The binary (23,12,7) Golay code is an example of a perfect code, that is, + * the number of syndromes equals the number of correctable error patterns. + * The minimum distance is 7, so all error patterns of Hamming weight up to + * 3 can be corrected. The total number of these error patterns is: + * + * Number of errors Number of patterns + * ---------------- ------------------ + * 0 1 + * 1 23 + * 2 253 + * 3 1771 + * ---- + * Total number of error patterns = 2048 = 2^{11} = number of syndromes + * -- + * number of redundant bits -------^ + * + * Because of its relatively low length (23), dimension (12) and number of + * redundant bits (11), the binary (23,12,7) Golay code can be encoded and + * decoded simply by using look-up tables. The program below uses a 16K + * encoding table and an 8K decoding table. + * + * For more information, suggestions, or other ideas on implementing error + * correcting codes, please contact me at (I'm temporarily in Japan, but + * below is my U.S. address): + * + * Robert Morelos-Zaragoza + * 770 S. Post Oak Ln. #200 + * Houston, Texas 77056 + * + * email: robert@spectra.eng.hawaii.edu + * + * NOTE: This program is free. You may modify it at will. However, please + * include the original file with any redistribution. The author is + * not responsible for any damage caused by the use of this program. + * + * Homework: Add an overall parity-check bit to get the (24,12,8) + * extended Golay code. + * + * == Copyright (c) 1994 Robert Morelos-Zaragoza. All rights reserved. == + */ + +#include +#define X22 0x00400000 /* vector representation of X^{22} */ +#define X11 0x00000800 /* vector representation of X^{11} */ +#define MASK12 0xfffff800 /* auxiliary vector for testing */ +#define GENPOL 0x00000c75 /* generator polinomial, g(x) */ + +/* Global variables: + * + * pattern = error pattern, or information, or received vector + * encoding_table[] = encoding table + * decoding_table[] = decoding table + * data = information bits, i(x) + * codeword = code bits = x^{11}i(x) + (x^{11}i(x) mod g(x)) + * numerr = number of errors = Hamming weight of error polynomial e(x) + * position[] = error positions in the vector representation of e(x) + * recd = representation of corrupted received polynomial r(x) = c(x) + e(x) + * decerror = number of decoding errors + * a[] = auxiliary array to generate correctable error patterns + */ + +unsigned int pattern; +unsigned int encoding_table[4096], decoding_table[2048]; +unsigned int data, codeword, recd; +unsigned int position[23] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000 }; +unsigned int numerr, errpos[23], decerror = 0; +int a[4]; + +unsigned int arr2int(int* a,int r) +/* + * Convert a binary vector of Hamming weight r, and nonzero positions in + * array a[1]...a[r], to a unsigned int integer \sum_{i=1}^r 2^{a[i]-1}. + */ +{ + int i; + unsigned int mul, result = 0, temp; + + for (i=1; i<=r; i++) { + mul = 1; + temp = a[i]-1; + while (temp--) + mul = mul << 1; + result += mul; + } + return(result); +} + +void nextcomb(int n, int r, int *a) +/* + * Calculate next r-combination of an n-set. + */ +{ + int i, j; + + a[r]++; + if (a[r] <= n) + return; + j = r - 1; + while (a[j] == n - r + j) + j--; + for (i = r; i >= j; i--) + a[i] = a[j] + i - j + 1; + return; +} + +unsigned int get_syndrome(unsigned int pattern) +/* + * Compute the syndrome corresponding to the given pattern, i.e., the + * remainder after dividing the pattern (when considering it as the vector + * representation of a polynomial) by the generator polynomial, GENPOL. + * In the program this pattern has several meanings: (1) pattern = infomation + * bits, when constructing the encoding table; (2) pattern = error pattern, + * when constructing the decoding table; and (3) pattern = received vector, to + * obtain its syndrome in decoding. + */ +{ + unsigned int aux = X22; + + if (pattern >= X11) + while (pattern & MASK12) { + while (!(aux & pattern)) + aux = aux >> 1; + pattern ^= (aux/X11) * GENPOL; + } + return(pattern); +} + +void gen_enc_table(void) +{ + /* + * --------------------------------------------------------------------- + * Generate ENCODING TABLE + * + * An entry to the table is an information vector, a 32-bit integer, + * whose 12 least significant positions are the information bits. The + * resulting value is a codeword in the (23,12,7) Golay code: A 32-bit + * integer whose 23 least significant bits are coded bits: Of these, the + * 12 most significant bits are information bits and the 11 least + * significant bits are redundant bits (systematic encoding). + * --------------------------------------------------------------------- + */ + unsigned int temp; + for (pattern = 0; pattern < 4096; pattern++) { + temp = pattern << 11; /* multiply information by X^{11} */ + encoding_table[pattern] = temp + get_syndrome(temp);/* add redundancy */ + } +} + +void gen_dec_table(void) +{ + /* + * --------------------------------------------------------------------- + * Generate DECODING TABLE + * + * An entry to the decoding table is a syndrome and the resulting value + * is the most likely error pattern. First an error pattern is generated. + * Then its syndrome is calculated and used as a pointer to the table + * where the error pattern value is stored. + * --------------------------------------------------------------------- + * + * (1) Error patterns of WEIGHT 1 (SINGLE ERRORS) + */ + unsigned int temp; + int i; + + decoding_table[0] = 0; + decoding_table[1] = 1; + temp = 1; + for (i=2; i<= 23; i++) { + temp *= 2; + decoding_table[get_syndrome(temp)] = temp; + } + /* + * (2) Error patterns of WEIGHT 2 (DOUBLE ERRORS) + */ + a[1] = 1; a[2] = 2; + temp = arr2int(a,2); + decoding_table[get_syndrome(temp)] = temp; + for (i=1; i<253; i++) { + nextcomb(23,2,a); + temp = arr2int(a,2); + decoding_table[get_syndrome(temp)] = temp; + } + /* + * (3) Error patterns of WEIGHT 3 (TRIPLE ERRORS) + */ + a[1] = 1; a[2] = 2; a[3] = 3; + temp = arr2int(a,3); + decoding_table[get_syndrome(temp)] = temp; + for (i=1; i<1771; i++) { + nextcomb(23,3,a); + temp = arr2int(a,3); + decoding_table[get_syndrome(temp)] = temp; + } +} + + +unsigned int encode_golay(unsigned int data) +{ +/* + * encodes data and returns the codeword. + * data is assumed to contain 12 bits in the least significant bit positions + * codeword contains the 23 bits in the LSB positions + * + */ + static int initialized=0; + + if (!initialized) { + gen_enc_table(); + initialized=1; + } + codeword = encoding_table[data]; + return codeword; +} + +unsigned int decode_golay(unsigned int codeword) +{ +/* + * decodes codeword and returns the dataword contained within. + * + * note: no detection is done here! + * codeword is assumed to contain the 23 bits in the LSB positions + * the returned bits contain the bits in the LSB positions + * + * MSB will be ignored, since this is 23,12 code. + */ + static int initialized=0; + + if (!initialized) { + gen_dec_table(); + initialized=1; + } + + /* + * Calculate the syndrome, look up the corresponding error pattern and + * add it to the received vector. + */ + codeword ^= decoding_table[get_syndrome(codeword)]; + + return codeword >> 11; +} + +#if(0) +main() +{ + unsigned int data,encoded,decoded; + data = 0x0b; + printf("data: %x \n",data); + encoded = encode_golay(data); + printf("encoded: %x \n",encoded); + encoded ^= 0xE000; + printf("error encoded: %x \n",encoded); + decoded = decode_golay(encoded); + printf("decoded: %x \n",decoded); + +} +#endif diff --git a/Golay/golay.h b/Golay/golay.h new file mode 100644 index 0000000..14cc886 --- /dev/null +++ b/Golay/golay.h @@ -0,0 +1,71 @@ +/* + * golay.h + * + * functions for (23,12) golay encoding/decoding + */ + +unsigned int arr2int(int *, int); +/* + * Convert a binary vector of Hamming weight r, and nonzero positions in + * array a[1]...a[r], to a unsigned int integer \sum_{i=1}^r 2^{a[i]-1}. + */ + +void nextcomb(int,int,int*); +/* + * Calculate next r-combination of an n-set. + */ + +unsigned int get_syndrome(unsigned int); +/* + * Compute the syndrome corresponding to the given pattern, i.e., the + * remainder after dividing the pattern (when considering it as the vector + * representation of a polynomial) by the generator polynomial, GENPOL. + * In the program this pattern has several meanings: (1) pattern = infomation + * bits, when constructing the encoding table; (2) pattern = error pattern, + * when constructing the decoding table; and (3) pattern = received vector, to + * obtain its syndrome in decoding. + */ + +void gen_enc_table(void); + /* + * --------------------------------------------------------------------- + * Generate ENCODING TABLE + * + * An entry to the table is an information vector, a 32-bit integer, + * whose 12 least significant positions are the information bits. The + * resulting value is a codeword in the (23,12,7) Golay code: A 32-bit + * integer whose 23 least significant bits are coded bits: Of these, the + * 12 most significant bits are information bits and the 11 least + * significant bits are redundant bits (systematic encoding). + * --------------------------------------------------------------------- + */ + +void gen_dec_table(void); + /* + * --------------------------------------------------------------------- + * Generate DECODING TABLE + * + * An entry to the decoding table is a syndrome and the resulting value + * is the most likely error pattern. First an error pattern is generated. + * Then its syndrome is calculated and used as a pointer to the table + * where the error pattern value is stored. + * --------------------------------------------------------------------- + * + */ + +unsigned int encode_golay(unsigned int data); +/* + * encodes data and returns the codeword. + * data is assumed to contain 12 bits in the least significant bit positions + * codeword contains the 23 bits in the LSB positions + * + */ + +unsigned int decode_golay(unsigned int codeword); +/* + * decodes codeword and returns the dataword contained within. + * + * note: no detection is done here! + * codeword is assumed to contain the 23 bits in the LSB positions + * the returned bits contain the bits in the LSB positions + */ diff --git a/Golay/reciever.c b/Golay/reciever.c new file mode 100644 index 0000000..b51cfaa --- /dev/null +++ b/Golay/reciever.c @@ -0,0 +1,72 @@ +//reciever.c +//by geozak @ GitHub +#include "golay.h" +#include +#include +#include +#include + +#define LENGTH 0x5 +//length 0x1 - 0xF +#define START 0xB3800000 +//start 0x[0-F][0-F][0or8]00000 + +char *buffer; +size_t bufsize = 32; + +unsigned int recieve () { + static int initialized=0; + + if (!initialized) { + buffer = (char *)malloc(bufsize * sizeof(char)); + if( buffer == NULL) + { + perror("Unable to allocate buffer"); + exit(1); + } + } + + do { + printf("Enter packet: "); + getline(&buffer,&bufsize,stdin); + } while (strlen(buffer) == 0); + unsigned int value = strtol(buffer, NULL, 16); + if (value & START){ + } + else { + printf("Potential Error.\n"); + } + return value & 0x7FFFFF; + //return strtol(buffer, NULL, 16) & 0x7FFFFF; +} + +void prettyprintset(unsigned int set[LENGTH]) { + printf("[ '1' => 0x%X (%d)", set[1], set[1]); + int i; + for(i=1; i 0x%X (%d)", i, set[i], set[i]); + } + printf(" ]\n"); +} + +void main () { + unsigned int set[LENGTH]; + int i; + for (i=0; i> 8; + if (i < LENGTH) { + set[i] = data & 0xff; + printf("0x%X -> [0x%X] = 0x%X (%d)\n", data, i, set[i], set[i]); + //setmotor(i, set[i]); + } + else { + printf("Index out of bounds. 0x%X -> [0x%X] = 0x%X (%d)\n", data, i, data & 0xff, data & 0xff); + } + prettyprintset(set); + } +} \ No newline at end of file diff --git a/Golay/sender.c b/Golay/sender.c new file mode 100644 index 0000000..80801ab --- /dev/null +++ b/Golay/sender.c @@ -0,0 +1,63 @@ +//sender.c +////by geozak @ GitHub +#include "golay.h" +#include +#include +#include + +#define LENGTH 0x5 +//length 0x1 - 0x10 +#define START 0xB3800000 +//start 0x[0-F][0-F][0or8]00000 + +void transmitInt (unsigned int data) { + printf("Transmit: 0x%X\n", data); +} + +void sendPositions(int size, unsigned char values[]) { + for (int i=0; i0x%X\n", i, set[i], set[i], data); + send(encode_golay(data)); + } + + char ex = getchar(); + while (ex != 'q') { + //printf("--------------------------------\n"); + for (i=0; i0x%X\n", i, set[i], set[i], data); + send(encode_golay(data)); + } + ex = getchar(); + }; +} +#endif \ No newline at end of file diff --git a/README.md b/README.md index 2da10a4..6a60fc0 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -# ARI_2016_Codebase \ No newline at end of file +###### ARI_2016_Codebase + +###contributors +#Zakary Stone \ No newline at end of file