EDACS: implement voting algorithm for FR BCH checks

This commit is contained in:
ilyacodes
2024-04-10 09:33:52 -04:00
parent deb9dbed61
commit 95aaa8fc2e

View File

@@ -69,6 +69,27 @@ char* get_lcn_status_string(int lcn)
return "";
}
//Bitwise vote-compare the three copies of a message received. Note that FR_2 is transmitted inverted.
unsigned long long int edacs_vote_fr(unsigned long long int fr_1, unsigned long long int fr_2, unsigned long long int fr_3)
{
fr_2 = (~fr_2) & 0xFFFFFFFFFF;
unsigned long long int msg_result = 0;
for (int i = 0; i < 40; i++)
{
int bit_1 = (fr_1 >> i) & 1;
int bit_2 = (fr_2 >> i) & 1;
int bit_3 = (fr_3 >> i) & 1;
//Vote: the value of the bit that we see the most is what we assume is correct
if (bit_1 + bit_2 + bit_3 > 1) {
msg_result |= (1ll << i);
}
}
return msg_result & 0xFFFFFFFFFF;
}
void openWavOutFile48k (dsd_opts * opts, dsd_state * state)
{
UNUSED(state);
@@ -509,6 +530,9 @@ void edacs(dsd_opts * opts, dsd_state * state)
}
//Old logic - take copy 1 of the first and second messages, then verify BCH on them.
//
//TODO 2024-04-10: Keep this logic around for a bit to compare against new voting implementation.
fr_1 = fr_1 & 0xFFFFFFFFFF;
fr_4 = fr_4 & 0xFFFFFFFFFF;
@@ -522,10 +546,34 @@ void edacs(dsd_opts * opts, dsd_state * state)
fr_1t = fr_1t & 0xFFFFFFFFFF;
fr_4t = fr_4t & 0xFFFFFFFFFF;
if (fr_1 != fr_1t || fr_4 != fr_4t)
int old_bch_pass = (fr_1 == fr_1t) && (fr_4 == fr_4t);
//New logic - take our 3 copies of the first and second message and vote them to extract the "error-corrected" first
//and second message, then verify BCH on that.
unsigned long long int msg_1_ec = edacs_vote_fr(fr_1, fr_2, fr_3);
unsigned long long int msg_2_ec = edacs_vote_fr(fr_4, fr_5, fr_6);
unsigned long long int msg_1_ec_m = msg_1_ec >> 12;
unsigned long long int msg_2_ec_m = msg_2_ec >> 12;
//take our message and create a new crc for it, if it matches the old crc, then we have a good frame
unsigned long long int msg_1_ec_t = edacs_bch(msg_1_ec_m) & 0xFFFFFFFFFF;
unsigned long long int msg_2_ec_t = edacs_bch(msg_2_ec_m) & 0xFFFFFFFFFF;
int bch_pass = (msg_1_ec == msg_1_ec_t) && (msg_2_ec == msg_2_ec_t);
if (!bch_pass && !old_bch_pass)
{
fprintf (stderr, " BCH FAIL ");
}
else if (bch_pass && !old_bch_pass)
{
fprintf (stderr, " BCH FAIL (old logic only) ");
}
else if (!bch_pass && old_bch_pass)
{
fprintf (stderr, " BCH FAIL (new logic only)");
}
else //BCH Pass, continue from here.
{