SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Public Member Functions | Public Attributes | List of all members
leansdr::rs_engine Struct Reference

#include <rs.h>

+ Collaboration diagram for leansdr::rs_engine:

Public Member Functions

 rs_engine ()
 
bool syndromes (const u8 *poly, u8 *synd)
 
u8 eval_poly_rev (const u8 *poly, int n, u8 x)
 
u8 eval_poly (const u8 *poly, int deg, u8 x)
 
void encode (u8 msg[204])
 
bool correct (u8 synd[16], u8 pout[188], u8 pin[204]=NULL, int *bits_corrected=NULL)
 

Public Attributes

gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
 
u8 G [17]
 

Detailed Description

Definition at line 97 of file rs.h.

Constructor & Destructor Documentation

◆ rs_engine()

leansdr::rs_engine::rs_engine ( )
inline

Definition at line 105 of file rs.h.

References leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::exp(), i, leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::mul(), and leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::sub().

106  {
107  // EN 300 421, section 4.4.2, Code Generator Polynomial
108  // G(X) = (X-alpha^0)*...*(X-alpha^15)
109  for (int i = 0; i <= 16; ++i)
110  G[i] = (i == 16) ? 1 : 0; // Init G=1
111  for (int d = 0; d < 16; ++d)
112  {
113  // Multiply by (X-alpha^d)
114  // G := X*G - alpha^d*G
115  for (int i = 0; i <= 16; ++i)
116  G[i] = gf.sub((i == 16) ? 0 : G[i + 1], gf.mul(gf.exp(d), G[i]));
117  }
118 #if DEBUG_RS
119  fprintf(stderr, "RS generator:");
120  for (int i = 0; i <= 16; ++i)
121  fprintf(stderr, " %02x", G[i]);
122  fprintf(stderr, "\n");
123 #endif
124  }
gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
Definition: rs.h:101
Te mul(Te x, Te y)
Definition: rs.h:69
u8 G[17]
Definition: rs.h:103
Te sub(Te x, Te y)
Definition: rs.h:68
int32_t i
Definition: decimators.h:244
Te exp(Te x)
Definition: rs.h:87
+ Here is the call graph for this function:

Member Function Documentation

◆ correct()

bool leansdr::rs_engine::correct ( u8  synd[16],
u8  pout[188],
u8  pin[204] = NULL,
int *  bits_corrected = NULL 
)
inline

Definition at line 201 of file rs.h.

References leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::div(), leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::exp(), leansdr::hamming_weight(), i, leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::inv(), and leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::mul().

Referenced by leansdr::rs_decoder< leansdr::u8, 0 >::run().

203  {
204  // Berlekamp - Massey
205  // http://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm#Code_sample
206  u8 C[16] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Max degree is L
207  u8 B[16] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
208  int L = 0;
209  int m = 1;
210  u8 b = 1;
211  for (int n = 0; n < 16; ++n)
212  {
213  u8 d = synd[n];
214  for (int i = 1; i <= L; ++i)
215  d ^= gf.mul(C[i], synd[n - i]);
216  if (!d)
217  {
218  ++m;
219  }
220  else if (2 * L <= n)
221  {
222  u8 T[16];
223  memcpy(T, C, sizeof(T));
224  for (int i = 0; i < 16 - m; ++i)
225  C[m + i] ^= gf.mul(d, gf.mul(gf.inv(b), B[i]));
226  L = n + 1 - L;
227  memcpy(B, T, sizeof(B));
228  b = d;
229  m = 1;
230  }
231  else
232  {
233  for (int i = 0; i < 16 - m; ++i)
234  C[m + i] ^= gf.mul(d, gf.mul(gf.inv(b), B[i]));
235  ++m;
236  }
237  }
238  // L is the number of errors
239  // C of degree L is now the error locator polynomial (Lambda)
240 #if DEBUG_RS
241  fprintf(stderr, "[L=%d C=", L);
242  for (int i = 0; i < 16; ++i)
243  fprintf(stderr, " %d", C[i]);
244  fprintf(stderr, "]\n");
245  fprintf(stderr, "[S=");
246  for (int i = 0; i < 16; ++i)
247  fprintf(stderr, " %d", synd[i]);
248  fprintf(stderr, "]\n");
249 #endif
250 
251  // Forney
252  // http://en.wikipedia.org/wiki/Forney_algorithm (2t=16)
253 
254  // Compute Omega
255  u8 omega[16];
256  memset(omega, 0, sizeof(omega));
257  // TODO loops
258  for (int i = 0; i < 16; ++i)
259  for (int j = 0; j < 16; ++j)
260  if (i + j < 16)
261  omega[i + j] ^= gf.mul(synd[i], C[j]);
262 #if DEBUG_RS
263  fprintf(stderr, "omega=");
264  for (int i = 0; i < 16; ++i)
265  fprintf(stderr, " %d", omega[i]);
266  fprintf(stderr, "\n");
267 #endif
268 
269  // Compute Lambda'
270  u8 Cprime[15];
271  for (int i = 0; i < 15; ++i)
272  Cprime[i] = (i & 1) ? 0 : C[i + 1];
273 #if DEBUG_RS
274  fprintf(stderr, "Cprime=");
275  for (int i = 0; i < 15; ++i)
276  fprintf(stderr, " %d", Cprime[i]);
277  fprintf(stderr, "\n");
278 #endif
279 
280  // Find zeroes of C by exhaustive search?
281  // TODO Chien method
282  int roots_found = 0;
283  for (int i = 0; i < 255; ++i)
284  {
285  u8 r = gf.exp(i); // Candidate root alpha^0..alpha^254
286  u8 v = eval_poly(C, L, r);
287  if (!v)
288  {
289  // r is a root X_k^-1 of the error locator polynomial.
290  u8 xk = gf.inv(r);
291  int loc = (255 - i) % 255; // == log(xk)
292 #if DEBUG_RS
293  fprintf(stderr, "found root=%d, inv=%d, loc=%d\n", r, xk, loc);
294 #endif
295  if (loc < 204)
296  {
297  // Evaluate e_k
298  u8 num = gf.mul(xk, eval_poly(omega, L, r));
299  u8 den = eval_poly(Cprime, 14, r);
300  u8 e = gf.div(num, den);
301  // Subtract e from coefficient of degree loc.
302  // Note: Coeffients listed by decreasing degree in pin[] and pout[].
303  if (bits_corrected)
304  *bits_corrected += hamming_weight(e);
305  if (loc >= 16)
306  pout[203 - loc] ^= e;
307  if (pin)
308  pin[203 - loc] ^= e;
309  }
310  if (++roots_found == L)
311  break;
312  }
313  }
314  if (pin)
315  return syndromes(pin, synd);
316  else
317  return false;
318  }
gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
Definition: rs.h:101
Te mul(Te x, Te y)
Definition: rs.h:69
unsigned char u8
Definition: framework.h:453
int hamming_weight(uint8_t x)
Definition: math.cpp:6
Te inv(Te x)
Definition: rs.h:82
u8 eval_poly(const u8 *poly, int deg, u8 x)
Definition: rs.h:153
int32_t i
Definition: decimators.h:244
Te div(Te x, Te y)
Definition: rs.h:75
Te exp(Te x)
Definition: rs.h:87
bool syndromes(const u8 *poly, u8 *synd)
Definition: rs.h:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ encode()

void leansdr::rs_engine::encode ( u8  msg[204])
inline

Definition at line 164 of file rs.h.

References leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::div(), i, leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::mul(), and leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::sub().

165  {
166  // TBD Avoid copying
167  u8 p[204];
168  memcpy(p, msg, 188);
169  memset(p + 188, 0, 16);
170  // p = msg*X^16
171 #if DEBUG_RS
172  fprintf(stderr, "uncoded:");
173  for (int i = 0; i < 204; ++i)
174  fprintf(stderr, " %d", p[i]);
175  fprintf(stderr, "\n");
176 #endif
177  // Compute remainder modulo G
178  for (int d = 0; d < 188; ++d)
179  {
180  // Clear monomial of degree d
181  if (!p[d])
182  continue;
183  u8 k = gf.div(p[d], G[0]);
184  // p(X) := p(X) - k*G(X)*X^(188-d)
185  for (int i = 0; i <= 16; ++i)
186  p[d + i] = gf.sub(p[d + i], gf.mul(k, G[i]));
187  }
188 #if DEBUG_RS
189  fprintf(stderr, "coded:");
190  for (int i = 0; i < 204; ++i)
191  fprintf(stderr, " %d", p[i]);
192  fprintf(stderr, "\n");
193 #endif
194  memcpy(msg + 188, p + 188, 16);
195  }
gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
Definition: rs.h:101
Te mul(Te x, Te y)
Definition: rs.h:69
unsigned char u8
Definition: framework.h:453
u8 G[17]
Definition: rs.h:103
Te sub(Te x, Te y)
Definition: rs.h:68
int32_t i
Definition: decimators.h:244
Te div(Te x, Te y)
Definition: rs.h:75
+ Here is the call graph for this function:

◆ eval_poly()

u8 leansdr::rs_engine::eval_poly ( const u8 poly,
int  deg,
u8  x 
)
inline

Definition at line 153 of file rs.h.

References leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::add(), and leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::mul().

154  {
155  // poly[0]*x^0 + .. + poly[deg]*x^deg with Hörner method.
156  u8 acc = 0;
157  for (; deg >= 0; --deg)
158  acc = gf.add(gf.mul(acc, x), poly[deg]);
159  return acc;
160  }
gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
Definition: rs.h:101
Te mul(Te x, Te y)
Definition: rs.h:69
Te add(Te x, Te y)
Definition: rs.h:67
unsigned char u8
Definition: framework.h:453
+ Here is the call graph for this function:

◆ eval_poly_rev()

u8 leansdr::rs_engine::eval_poly_rev ( const u8 poly,
int  n,
u8  x 
)
inline

Definition at line 143 of file rs.h.

References leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::add(), i, and leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::mul().

144  {
145  // poly[0]*x^(n-1) + .. + poly[n-1]*x^0 with Hörner method.
146  u8 acc = 0;
147  for (int i = 0; i < n; ++i)
148  acc = gf.add(gf.mul(acc, x), poly[i]);
149  return acc;
150  }
gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
Definition: rs.h:101
Te mul(Te x, Te y)
Definition: rs.h:69
Te add(Te x, Te y)
Definition: rs.h:67
unsigned char u8
Definition: framework.h:453
int32_t i
Definition: decimators.h:244
+ Here is the call graph for this function:

◆ syndromes()

bool leansdr::rs_engine::syndromes ( const u8 poly,
u8 synd 
)
inline

Definition at line 132 of file rs.h.

References leansdr::gf2x_p< Te, Tp, P, N, ALPHA >::exp(), and i.

Referenced by leansdr::rs_decoder< leansdr::u8, 0 >::run().

133  {
134  bool corrupted = false;
135  for (int i = 0; i < 16; ++i)
136  {
137  synd[i] = eval_poly_rev(poly, 204, gf.exp(i));
138  if (synd[i])
139  corrupted = true;
140  }
141  return corrupted;
142  }
gf2x_p< unsigned char, unsigned short, 0x11d, 8, 2 > gf
Definition: rs.h:101
u8 eval_poly_rev(const u8 *poly, int n, u8 x)
Definition: rs.h:143
int32_t i
Definition: decimators.h:244
Te exp(Te x)
Definition: rs.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ G

u8 leansdr::rs_engine::G[17]

Definition at line 103 of file rs.h.

◆ gf

gf2x_p<unsigned char, unsigned short, 0x11d, 8, 2> leansdr::rs_engine::gf

Definition at line 101 of file rs.h.


The documentation for this struct was generated from the following file: