Updated tables and code
This commit is contained in:
parent
8f004f11c4
commit
a29e1f0221
2 changed files with 94 additions and 33 deletions
|
@ -95,15 +95,15 @@ const uint8_t G[M][K_BYTES] = {
|
||||||
|
|
||||||
// Column order (permutation) in which the bits in codeword are stored
|
// Column order (permutation) in which the bits in codeword are stored
|
||||||
const uint8_t colorder[N] = {
|
const uint8_t colorder[N] = {
|
||||||
0, 1, 2, 3, 30, 4, 5, 6, 7, 8, 9, 10, 11, 32, 12, 40, 13, 14, 15, 16,
|
0, 1, 2, 3, 28, 4, 5, 6, 7, 8, 9, 10, 11, 34, 12, 32, 13, 14, 15, 16,
|
||||||
17, 18, 37, 45, 29, 19, 20, 21, 41, 22, 42, 31, 33, 34, 44, 35, 47, 51, 50, 43,
|
17, 18, 36, 29, 43, 19, 20, 42, 21, 40, 30, 37, 22, 47, 61, 45, 44, 23, 41, 39,
|
||||||
36, 52, 63, 46, 25, 55, 27, 24, 23, 53, 39, 49, 59, 38, 48, 61, 60, 57, 28, 62,
|
49, 24, 46, 50, 48, 26, 31, 33, 51, 38, 52, 59, 55, 66, 57, 27, 60, 35, 54, 58,
|
||||||
56, 58, 65, 66, 26, 70, 64, 69, 68, 67, 74, 71, 54, 76, 72, 75, 78, 77, 80, 79,
|
25, 56, 62, 64, 67, 69, 63, 68, 70, 72, 65, 73, 75, 74, 71, 77, 78, 76, 79, 80,
|
||||||
73, 83, 84, 81, 82, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
|
53, 81, 83, 82, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
|
||||||
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
|
100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
|
||||||
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,
|
120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,
|
||||||
140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173
|
160,161,162,163,164,165,166,167,168,169,170,171,172,173
|
||||||
};
|
};
|
||||||
|
|
||||||
// Costas 7x7 tone pattern
|
// Costas 7x7 tone pattern
|
||||||
|
@ -234,7 +234,7 @@ void genft8(const uint8_t *payload, uint8_t i3, uint8_t *itone) {
|
||||||
a91[9] |= (uint8_t)(checksum >> 11);
|
a91[9] |= (uint8_t)(checksum >> 11);
|
||||||
a91[10] = (uint8_t)(checksum >> 3);
|
a91[10] = (uint8_t)(checksum >> 3);
|
||||||
|
|
||||||
// a87 contains 72 bits of payload + 3 bits of i3 + 12 bits of CRC
|
// a87 contains 77 bits of payload + 14 bits of CRC
|
||||||
uint8_t codeword[22];
|
uint8_t codeword[22];
|
||||||
encode174(a91, codeword);
|
encode174(a91, codeword);
|
||||||
|
|
||||||
|
|
107
pack_77.cpp
107
pack_77.cpp
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
|
|
||||||
|
// TODO: This is wasteful, should figure out something more elegant
|
||||||
const char *A0 = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?";
|
const char *A0 = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-./?";
|
||||||
const char *A1 = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const char *A1 = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
const char *A2 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
const char *A2 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
@ -24,13 +25,10 @@ int32_t pack28(const char *callsign) {
|
||||||
constexpr int32_t NTOKENS = 2063592L;
|
constexpr int32_t NTOKENS = 2063592L;
|
||||||
constexpr int32_t MAX22 = 4194304L;
|
constexpr int32_t MAX22 = 4194304L;
|
||||||
|
|
||||||
int length = strlen(callsign); // We will need it later
|
|
||||||
if (length > 13) return -1;
|
|
||||||
|
|
||||||
// Check for special tokens first
|
// Check for special tokens first
|
||||||
if (equals(callsign, "DE")) return 0;
|
if (starts_with(callsign, "DE ")) return 0;
|
||||||
if (equals(callsign, "QRZ")) return 1;
|
if (starts_with(callsign, "QRZ ")) return 1;
|
||||||
if (equals(callsign, "CQ")) return 2;
|
if (starts_with(callsign, "CQ ")) return 2;
|
||||||
|
|
||||||
if (starts_with(callsign, "CQ_")) {
|
if (starts_with(callsign, "CQ_")) {
|
||||||
int nnum = 0, nlet = 0;
|
int nnum = 0, nlet = 0;
|
||||||
|
@ -46,6 +44,11 @@ int32_t pack28(const char *callsign) {
|
||||||
|
|
||||||
char c6[6] = {' ', ' ', ' ', ' ', ' ', ' '};
|
char c6[6] = {' ', ' ', ' ', ' ', ' ', ' '};
|
||||||
|
|
||||||
|
int length = 0; // strlen(callsign); // We will need it later
|
||||||
|
while (callsign[length] != ' ' && callsign[length] != 0) {
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
|
||||||
// Work-around for Swaziland prefix:
|
// Work-around for Swaziland prefix:
|
||||||
if (starts_with(callsign, "3DA0") && length <= 7) {
|
if (starts_with(callsign, "3DA0") && length <= 7) {
|
||||||
memcpy(c6, "3D0", 3);
|
memcpy(c6, "3D0", 3);
|
||||||
|
@ -83,6 +86,8 @@ int32_t pack28(const char *callsign) {
|
||||||
|
|
||||||
//char c13[13];
|
//char c13[13];
|
||||||
|
|
||||||
|
//if (length > 13) return -1;
|
||||||
|
|
||||||
// Treat this as a nonstandard callsign: compute its 22-bit hash
|
// Treat this as a nonstandard callsign: compute its 22-bit hash
|
||||||
// call save_hash_call(c13,n10,n12,n22) !Save callsign in hash table
|
// call save_hash_call(c13,n10,n12,n22) !Save callsign in hash table
|
||||||
// n28=NTOKENS + n22
|
// n28=NTOKENS + n22
|
||||||
|
@ -113,27 +118,82 @@ bool chkcall(const char *call, char *bc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t packgrid(const char *grid4) {
|
||||||
|
constexpr uint16_t MAXGRID4 = 32400;
|
||||||
|
|
||||||
|
if (grid4 == 0) {
|
||||||
|
// Two callsigns only, no report/grid
|
||||||
|
return MAXGRID4 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take care of special cases
|
||||||
|
if (equals(grid4, "RRR")) return MAXGRID4 + 2;
|
||||||
|
if (equals(grid4, "RR73")) return MAXGRID4 + 3;
|
||||||
|
if (equals(grid4, "73")) return MAXGRID4 + 4;
|
||||||
|
|
||||||
|
// Check for standard 4 letter grid
|
||||||
|
if (in_range(grid4[0], 'A', 'R') &&
|
||||||
|
in_range(grid4[1], 'A', 'R') &&
|
||||||
|
is_digit(grid4[2]) && is_digit(grid4[3]))
|
||||||
|
{
|
||||||
|
//if (w(3).eq.'R ') ir=1
|
||||||
|
uint16_t igrid4 = (grid4[3] - '0');
|
||||||
|
igrid4 = igrid4 * 10 + (grid4[2] - '0');
|
||||||
|
igrid4 = igrid4 * 10 + (grid4[1] - 'A');
|
||||||
|
igrid4 = igrid4 * 18 + (grid4[0] - 'A');
|
||||||
|
return igrid4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse report: +dd / -dd / R+dd / R-dd
|
||||||
|
// TODO: check the range of dd
|
||||||
|
if (grid4[0] == 'R') {
|
||||||
|
int dd = dd_to_int(grid4 + 1, 3);
|
||||||
|
uint16_t irpt = 35 + dd;
|
||||||
|
return (MAXGRID4 + irpt) | 0x8000; // ir = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int dd = dd_to_int(grid4, 3);
|
||||||
|
uint16_t irpt = 35 + dd;
|
||||||
|
return (MAXGRID4 + irpt); // ir = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return MAXGRID4 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Pack Type 1 (Standard 77-bit message) and Type 2 (ditto, with a "/P" call)
|
// Pack Type 1 (Standard 77-bit message) and Type 2 (ditto, with a "/P" call)
|
||||||
void pack77_1(const char *msg, uint8_t i3, uint8_t *b77) {
|
int pack77_1(const char *msg, uint8_t *b77) {
|
||||||
|
// Locate the first delimiter
|
||||||
|
const char *s1 = strchr(msg, ' ');
|
||||||
|
if (s1 == 0) return -1;
|
||||||
|
|
||||||
|
const char *call1 = msg; // 1st call
|
||||||
|
const char *call2 = s1 + 1; // 2nd call
|
||||||
|
|
||||||
|
int32_t n28a = pack28(call1);
|
||||||
|
int32_t n28b = pack28(call2);
|
||||||
|
|
||||||
|
uint16_t igrid4;
|
||||||
|
|
||||||
|
// Locate the second delimiter
|
||||||
|
const char *s2 = strchr(s1 + 1, ' ');
|
||||||
|
if (s2 != 0) {
|
||||||
|
igrid4 = packgrid(s2 + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Two callsigns, no grid/report
|
||||||
|
igrid4 = packgrid(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t i3 = 1;
|
||||||
|
// if(index(w(1),'/P').ge.4 .or. index(w(2),'/P').ge.4) i3=2 !Type 2, with "/P"
|
||||||
|
|
||||||
// if(index(w(1),'/P').ge.4 .or. index(w(1),'/R').ge.4) ipa=1
|
// if(index(w(1),'/P').ge.4 .or. index(w(1),'/R').ge.4) ipa=1
|
||||||
// if(index(w(2),'/P').ge.4 .or. index(w(2),'/R').ge.4) ipb=1
|
// if(index(w(2),'/P').ge.4 .or. index(w(2),'/R').ge.4) ipb=1
|
||||||
|
|
||||||
int32_t n28a, n28b;
|
// Shift in ipa and ipb bits into n28a and n28b
|
||||||
uint16_t igrid4;
|
|
||||||
|
|
||||||
const char *call1, *call2;
|
|
||||||
|
|
||||||
n28a = pack28(call1);
|
|
||||||
n28b = pack28(call2);
|
|
||||||
|
|
||||||
// Add ipa and ipb bits to the right
|
|
||||||
n28a <<= 1; // ipa = 0
|
n28a <<= 1; // ipa = 0
|
||||||
n28b <<= 1; // ipb = 0
|
n28b <<= 1; // ipb = 0
|
||||||
|
|
||||||
// Add igrid4 bit to the left
|
|
||||||
//igrid4 |= 0x8000; // ir = 1
|
|
||||||
|
|
||||||
// write(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3
|
// write(c77,1000) n28a,ipa,n28b,ipb,ir,igrid4,i3
|
||||||
// 1000 format(2(b28.28,b1),b1,b15.15,b3.3)
|
// 1000 format(2(b28.28,b1),b1,b15.15,b3.3)
|
||||||
// (28 + 1) + (28 + 1) + (1 + 15) + 3
|
// (28 + 1) + (28 + 1) + (1 + 15) + 3
|
||||||
|
@ -148,6 +208,8 @@ void pack77_1(const char *msg, uint8_t i3, uint8_t *b77) {
|
||||||
b77[7] = (uint8_t)(n28a << 6) | (uint8_t)(igrid4 >> 10);
|
b77[7] = (uint8_t)(n28a << 6) | (uint8_t)(igrid4 >> 10);
|
||||||
b77[8] = (igrid4 >> 2);
|
b77[8] = (igrid4 >> 2);
|
||||||
b77[9] = (uint8_t)(igrid4 << 6) | (uint8_t)(i3 << 3);
|
b77[9] = (uint8_t)(igrid4 << 6) | (uint8_t)(i3 << 3);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -182,10 +244,9 @@ void packtext77(const char *c13, uint8_t *b71) {
|
||||||
|
|
||||||
int pack77(const char *msg, uint8_t *c77) {
|
int pack77(const char *msg, uint8_t *c77) {
|
||||||
// Check Type 1 (Standard 77-bit message) or Type 2, with optional "/P"
|
// Check Type 1 (Standard 77-bit message) or Type 2, with optional "/P"
|
||||||
if (starts_with(msg, "CQ ")) {
|
//if (starts_with(msg, "CQ ")) {
|
||||||
pack77_1(nwords,w,i3,n3,c77);
|
return pack77_1(msg, c77);
|
||||||
return;
|
//}
|
||||||
}
|
|
||||||
// Check 0.5 (telemetry)
|
// Check 0.5 (telemetry)
|
||||||
// i3=0 n3=5 write(c77,1006) ntel,n3,i3 1006 format(b23.23,2b24.24,2b3.3)
|
// i3=0 n3=5 write(c77,1006) ntel,n3,i3 1006 format(b23.23,2b24.24,2b3.3)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue