Merged in f5soh/librepilot/LP-607_world_mag_model_2015v2 (pull request #526)
[librepilot.git] / flight / libraries / rscode / rs.c
blob62fd02386092037308b2d6b58d8cc3efede4940b
1 /*
2 * Reed Solomon Encoder/Decoder
4 * Copyright Henry Minsky (hqm@alum.mit.edu) 1991-2009
6 * This software library is licensed under terms of the GNU GENERAL
7 * PUBLIC LICENSE
9 * RSCODE is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * RSCODE is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with Rscode. If not, see <http://www.gnu.org/licenses/>.
22 * Commercial licensing is available under a separate license, please
23 * contact author for details.
25 * Source code is available at http://rscode.sourceforge.net
28 #include <stdio.h>
29 #include <ctype.h>
30 #include "ecc.h"
32 /* Encoder parity bytes */
33 int pBytes[MAXDEG];
35 /* Decoder syndrome bytes */
36 int synBytes[MAXDEG];
38 /* generator polynomial */
39 int genPoly[MAXDEG*2];
41 //int DEBUG = FALSE;
43 static void
44 compute_genpoly (int nbytes, int genpoly[]);
46 /* Initialize lookup tables, polynomials, etc. */
47 void
48 initialize_ecc ()
50 /* Initialize the galois field arithmetic tables */
51 init_galois_tables();
53 /* Compute the encoder generator polynomial */
54 compute_genpoly(RS_ECC_NPARITY, genPoly);
57 void
58 zero_fill_from (unsigned char buf[], int from, int to)
60 int i;
61 for (i = from; i < to; i++) buf[i] = 0;
64 /* debugging routines */
65 void
66 print_parity (void)
68 #ifdef NEVER
69 int i;
70 printf("Parity Bytes: ");
71 for (i = 0; i < RS_ECC_NPARITY; i++)
72 printf("[%d]:%x, ",i,pBytes[i]);
73 printf("\n");
74 #endif
78 void
79 print_syndrome (void)
81 #ifdef NEVER
82 int i;
83 printf("Syndrome Bytes: ");
84 for (i = 0; i < RS_ECC_NPARITY; i++)
85 printf("[%d]:%x, ",i,synBytes[i]);
86 printf("\n");
87 #endif
90 /* Append the parity bytes onto the end of the message */
91 void
92 build_codeword (unsigned char msg[], int nbytes, unsigned char dst[])
94 int i;
96 for (i = 0; i < nbytes; i++) dst[i] = msg[i];
98 for (i = 0; i < RS_ECC_NPARITY; i++) {
99 dst[i+nbytes] = pBytes[RS_ECC_NPARITY-1-i];
103 /**********************************************************
104 * Reed Solomon Decoder
106 * Computes the syndrome of a codeword. Puts the results
107 * into the synBytes[] array.
110 void
111 decode_data(unsigned char data[], int nbytes)
113 int i, j, sum;
114 for (j = 0; j < RS_ECC_NPARITY; j++) {
115 sum = 0;
116 for (i = 0; i < nbytes; i++) {
117 sum = data[i] ^ gmult(gexp[j+1], sum);
119 synBytes[j] = sum;
124 /* Check if the syndrome is zero */
126 check_syndrome (void)
128 int i, nz = 0;
129 for (i =0 ; i < RS_ECC_NPARITY; i++) {
130 if (synBytes[i] != 0) {
131 nz = 1;
132 break;
135 return nz;
139 void
140 debug_check_syndrome (void)
142 #ifdef NEVER
143 int i;
145 for (i = 0; i < 3; i++) {
146 printf(" inv log S[%d]/S[%d] = %d\n", i, i+1,
147 glog[gmult(synBytes[i], ginv(synBytes[i+1]))]);
149 #endif
153 /* Create a generator polynomial for an n byte RS code.
154 * The coefficients are returned in the genPoly arg.
155 * Make sure that the genPoly array which is passed in is
156 * at least n+1 bytes long.
159 static void
160 compute_genpoly (int nbytes, int genpoly[])
162 int i, tp[MAXDEG], tp1[MAXDEG];
164 /* multiply (x + a^n) for n = 1 to nbytes */
166 zero_poly(tp1);
167 tp1[0] = 1;
169 for (i = 1; i <= nbytes; i++) {
170 zero_poly(tp);
171 tp[0] = gexp[i]; /* set up x+a^n */
172 tp[1] = 1;
174 mult_polys(genpoly, tp, tp1);
175 copy_poly(tp1, genpoly);
179 /* Simulate a LFSR with generator polynomial for n byte RS code.
180 * Pass in a pointer to the data array, and amount of data.
182 * The parity bytes are deposited into pBytes[], and the whole message
183 * and parity are copied to dest to make a codeword.
187 void
188 encode_data (unsigned char msg[], int nbytes, unsigned char dst[])
190 int i, LFSR[RS_ECC_NPARITY+1],dbyte, j;
192 for(i=0; i < RS_ECC_NPARITY+1; i++) LFSR[i]=0;
194 for (i = 0; i < nbytes; i++) {
195 dbyte = msg[i] ^ LFSR[RS_ECC_NPARITY-1];
196 for (j = RS_ECC_NPARITY-1; j > 0; j--) {
197 LFSR[j] = LFSR[j-1] ^ gmult(genPoly[j], dbyte);
199 LFSR[0] = gmult(genPoly[0], dbyte);
202 for (i = 0; i < RS_ECC_NPARITY; i++)
203 pBytes[i] = LFSR[i];
205 build_codeword(msg, nbytes, dst);