1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-09-12 16:16:35 -04:00
sdrangel/plugins/channel/lora/lorabits.h

75 lines
2.1 KiB
C
Raw Normal View History

2015-01-17 10:59:44 -05:00
/*
Interleaving is "easiest" if the same number of bits is used per symbol as for FEC
Chosen mode "spreading 8, low rate" has 6 bits per symbol, so use 4:6 FEC
2015-02-12 04:37:08 -05:00
More spreading needs higher frequency resolution and longer time on air, increasing drift errors.
Want higher bandwidth when using more spreading, which needs more CPU.
Six bit Hamming can only correct drift errors. Want 7 or 8 bit FEC for QRM
2015-01-17 10:59:44 -05:00
*/
// Needs adjusting for different sizes
2015-02-12 04:37:08 -05:00
void LoRaDemod::interleave6(char* inout, int size)
2015-01-17 10:59:44 -05:00
{
2015-02-09 18:54:51 -05:00
int i, j;
char in[6 * 2];
short s;
for (j = 0; j < size; j+=6) {
for (i = 0; i < 6; i++)
in[i] = in[i + 6] = inout[i + j];
// top bits are swapped
for (i = 0; i < 6; i++) {
s = (32 & in[2 + i]) | (16 & in[1 + i]) | (8 & in[3 + i])
2015-02-06 13:59:35 -05:00
| (4 & in[4 + i]) | (2 & in[5 + i]) | (1 & in[6 + i]);
2015-02-09 18:54:51 -05:00
// bits are also rotated
s = (s << 3) | (s >> 3);
s &= 63;
s = (s >> i) | (s << (6 - i));
inout[i + j] = s & 63;
}
2015-01-17 10:59:44 -05:00
}
}
2015-01-22 17:30:55 -05:00
short LoRaDemod::toGray(short num)
2015-01-17 10:59:44 -05:00
{
2015-01-22 17:30:55 -05:00
return (num >> 1) ^ num;
2015-01-17 10:59:44 -05:00
}
2015-02-09 18:54:51 -05:00
// ignore FEC, try to extract raw bits
2015-02-12 04:37:08 -05:00
void LoRaDemod::hamming6(char* c, int size)
2015-02-05 14:38:46 -05:00
{
int i;
2015-02-09 18:54:51 -05:00
2015-02-05 14:38:46 -05:00
for (i = 0; i < size; i++) {
2015-02-09 18:54:51 -05:00
c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<0) | ((c[i] & 4)>>0) | ((c[i] & 8)>>3);
i++;
c[i] = ((c[i] & 1)<<2) | ((c[i] & 2)<<2) | ((c[i] & 4)>>1) | ((c[i] & 8)>>3);
i++;
2015-02-11 17:06:09 -05:00
c[i] = ((c[i] & 32)>>2) | ((c[i] & 2)<<1) | ((c[i] & 4)>>1) | ((c[i] & 8)>>3);
2015-02-09 18:54:51 -05:00
i++;
c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<1) | ((c[i] & 4)>>1) | ((c[i] & 8)>>3);
i++;
2015-02-11 17:06:09 -05:00
c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<1) | ((c[i] & 4)>>1) | ((c[i] & 16)>>4);
2015-02-09 18:54:51 -05:00
i++;
c[i] = ((c[i] & 1)<<3) | ((c[i] & 2)<<1) | ((c[i] & 4)>>2) | ((c[i] & 8)>>2);
2015-02-05 14:38:46 -05:00
}
2015-02-09 18:54:51 -05:00
c[i] = 0;
2015-02-05 14:38:46 -05:00
}
2015-02-11 17:06:09 -05:00
// data whitening (6 bit)
2015-02-12 04:37:08 -05:00
void LoRaDemod::prng6(char* inout, int size)
2015-02-05 14:38:46 -05:00
{
const char otp[] = {
2015-02-11 17:06:09 -05:00
"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_UbTW3=W5Aa<9i;F;ondS[LBA;[4S9]kkh]Vc2j>kX"
2015-02-05 14:38:46 -05:00
};
int i, maxchars;
maxchars = sizeof( otp );
if (size < maxchars)
maxchars = size;
for (i = 0; i < maxchars; i++)
2015-02-11 17:06:09 -05:00
inout[i] ^= (otp[i] - 48);
2015-02-05 14:38:46 -05:00
}