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.
lorabits.h
Go to the documentation of this file.
1 /*
2  Interleaving is "easiest" if the same number of bits is used per symbol as for FEC
3  Chosen mode "spreading 8, low rate" has 6 bits per symbol, so use 4:6 FEC
4 
5  More spreading needs higher frequency resolution and longer time on air, increasing drift errors.
6  Want higher bandwidth when using more spreading, which needs more CPU and a better FFT.
7 
8  Six bit Hamming can only correct long runs of drift errors when not using interleaving. Interleaving defeats the point of using Gray code and puts multiple bit errors into single FEC blocks. Hardware decoding uses RSSI to detect the symbols most likely to be damaged, so that individual bits can be repaired after de-interleaving.
9 
10  Using Implicit Mode: explicit starts with a 4:8 block and seems to have a different whitening sequence.
11 */
12 
13 // Six bits per symbol, six chars per block
14 void LoRaDemod::interleave6(char* inout, int size)
15 {
16  int i, j;
17  char in[6 * 2];
18  short s;
19 
20  for (j = 0; j < size; j+=6) {
21  for (i = 0; i < 6; i++)
22  in[i] = in[i + 6] = inout[i + j];
23  // top bits are swapped
24  for (i = 0; i < 6; i++) {
25  s = (32 & in[2 + i]) | (16 & in[1 + i]) | (8 & in[3 + i])
26  | (4 & in[4 + i]) | (2 & in[5 + i]) | (1 & in[6 + i]);
27  // bits are also rotated
28  s = (s << 3) | (s >> 3);
29  s &= 63;
30  s = (s >> i) | (s << (6 - i));
31  inout[i + j] = s & 63;
32  }
33  }
34 }
35 
36 short LoRaDemod::toGray(short num)
37 {
38  return (num >> 1) ^ num;
39 }
40 
41 // Ignore the FEC bits, just extract the data bits
42 void LoRaDemod::hamming6(char* c, int size)
43 {
44  int i;
45 
46  for (i = 0; i < size; i++) {
47  c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<0) | ((c[i] & 4)>>0) | ((c[i] & 8)>>3);
48  i++;
49  c[i] = ((c[i] & 1)<<2) | ((c[i] & 2)<<2) | ((c[i] & 4)>>1) | ((c[i] & 8)>>3);
50  i++;
51  c[i] = ((c[i] &32)>>2) | ((c[i] & 2)<<1) | ((c[i] & 4)>>1) | ((c[i] & 8)>>3);
52  i++;
53  c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<1) | ((c[i] & 4)>>1) | ((c[i] & 8)>>3);
54  i++;
55  c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<1) | ((c[i] & 4)>>1) | ((c[i] &16)>>4);
56  i++;
57  c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<1) | ((c[i] & 4)>>2) | ((c[i] & 8)>>2);
58  }
59  c[i] = 0;
60 }
61 
62 // data whitening (6 bit)
63 void LoRaDemod::prng6(char* inout, int size)
64 {
65  const char otp[] = {
66  //explicit mode
67  "cOGGg7CM2=b5a?<`i;T2of5jDAB=2DoQ9ko?h_RLQR4@Z\\`9jY\\PX89lHX8h_R]c_^@OB<0`W08ik?Mg>dQZf3kn5Je5R=R4h[<Ph90HHh9j;h:mS^?f:lQ:GG;nU:b?WFU20Lf4@A?`hYJMnW\\QZ\\AMIZ<h:jQk[PP<`6[Z"
68 #if 0
69  // implicit mode (offset 2 symbols)
70  "5^ZSm0=cOGMgUB=bNcb<@a^T;_f=6DEB]2ImPIKg:j]RlYT4YZ<`9hZ\\PPb;@8X8i]Zmc_6B52\\8oUPHIcBOc>dY?d9[n5Lg]b]R8hR<0`T008h9c9QJm[c?a:lQEGa;nU=b_WfUV2?V4@c=8h9B9njlQZDC@9Z<Q8\\iiX\\Rb6k:iY"
71 #endif
72  };
73  int i, maxchars;
74 
75  maxchars = sizeof( otp );
76  if (size < maxchars)
77  maxchars = size;
78  for (i = 0; i < maxchars; i++)
79  inout[i] ^= (otp[i] - 48);
80 }
81 
short toGray(short bin)
Definition: lorabits.h:36
void prng6(char *inout, int size)
Definition: lorabits.h:63
int32_t i
Definition: decimators.h:244
void interleave6(char *inout, int size)
Definition: lorabits.h:14
void hamming6(char *inout, int size)
Definition: lorabits.h:42