From 034855069a6cbf5952f4a78859d089668a38cfdf Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Sun, 1 Feb 2026 20:19:33 -0500 Subject: [PATCH] NXDN: Fix NXDN_LICH_OFFBITS and LICH_ERR_THRESHOLD to work as expected post NXDN Viterbi overhaul; Revert back to 1 bit error on lich "dividing"; NXDN: Skip Dibits prior to exit on bad sync in nxdn_frame; NXDN: Reimplement the CAC fail demodulator and dibit buffer soft reset; --- src/nxdn_deperm.c | 44 +++++++++++++++++++++++++++++++++++++++++++ src/nxdn_frame.c | 14 +++++++------- src/soft_viterbi_k5.c | 4 ++-- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/nxdn_deperm.c b/src/nxdn_deperm.c index 157fd1b..e6b4ffc 100644 --- a/src/nxdn_deperm.c +++ b/src/nxdn_deperm.c @@ -591,6 +591,7 @@ void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits) } +static int cac_fail = 0; void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits) { @@ -646,6 +647,10 @@ void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits) fprintf (stderr, "%s", KNRM); } + //check for accumulative cac failures and reset if multiple errors pile up + if (crc != 0) cac_fail++; + else cac_fail = 0; + if (crc == 0) NXDN_Elements_Content_decode(opts, state, 1, cac_message_buffer); if (opts->payload == 1) @@ -660,6 +665,45 @@ void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits) if (crc != 0) fprintf (stderr, " CRC ERR "); } + + //reset some parameters if CAC continues to fail + if (cac_fail > 5) + { + //simple reset + state->synctype = -1; //was 0, which is p25p1 + state->lastsynctype = -1; + state->carrier = 0; + state->last_cc_sync_time = time(NULL)+2; //probably not necesary + cac_fail = 0; //reset + + //more advanced modulator reset + state->center = 0; + state->jitter = -1; + state->synctype = -1; + state->min = -15000; + state->max = 15000; + state->lmid = 0; + state->umid = 0; + state->minref = -12000; + state->maxref = 12000; + state->lastsample = 0; + for (int i = 0; i < 128; i++) state->sbuf[i] = 0; + state->sidx = 0; + for (int i = 0; i < 1024; i++) state->maxbuf[i] = 15000; + for (int i = 0; i < 1024; i++) state->minbuf[i] = -15000; + state->midx = 0; + state->symbolcnt = 0; + + //reset the dibit buffer + state->dibit_buf_p = state->dibit_buf + 200; + memset (state->dibit_buf, 0, sizeof (int) * 200); + state->offset = 0; + + //debug notification + // fprintf (stderr, " RESET CARRIER; "); + + } + } void idas_scch(dsd_opts * opts, dsd_state * state, uint8_t * bits, uint8_t direction) diff --git a/src/nxdn_frame.c b/src/nxdn_frame.c index ec6ceac..566ee93 100644 --- a/src/nxdn_frame.c +++ b/src/nxdn_frame.c @@ -13,7 +13,7 @@ #include "dsd.h" #include "nxdn_const.h" -#define LICH_ERR_THRESHOLD 2 //Threshold for lich dibit "dividing" errors +#define LICH_ERR_THRESHOLD 7 //Threshold for lich dibit "dividing" errors (8 is perfect, 7 is 1 bit error) // #define NXDN_DEBUG_LICH //print LICH debug info on err on payload == 1 #define NXDN_LICH_OFFBITS //use the offbits to help determine sync status (disable if bad signal / bad sample) @@ -298,17 +298,17 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state) break; } // end of switch(lich) - // //collect remaining dibits at this point (before bad frame skip) - // for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174 - // dbuf[i+8] = getDibit(opts, state); + //collect remaining dibits at this point (before bad frame skip) + for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174 + dbuf[i+8] = getDibit(opts, state); //go to end if bad returns from earlier if (state->lastsynctype == -1) goto END; - //collect remaining dibits at this point (after bad frame skip) - for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174 - dbuf[i+8] = getDibit(opts, state); + // //collect remaining dibits at this point (after bad frame skip) + // for (int i = 0; i < 174; i++) //192total-10FSW-8lich = 174 + // dbuf[i+8] = getDibit(opts, state); //enable these after good lich parity and known lich value state->carrier = 1; diff --git a/src/soft_viterbi_k5.c b/src/soft_viterbi_k5.c index 3b2b369..40cddf1 100644 --- a/src/soft_viterbi_k5.c +++ b/src/soft_viterbi_k5.c @@ -19,7 +19,7 @@ static uint32_t prevMetrics[NUM_STATES]; static uint32_t currMetrics[NUM_STATES]; static uint32_t prevMetricsData[NUM_STATES]; static uint32_t currMetricsData[NUM_STATES]; -static uint16_t viterbi_history[600]; +static uint16_t viterbi_history[600*2]; /** * @brief Decode unpunctured convolutionally encoded data. @@ -66,7 +66,7 @@ uint32_t viterbi_decode(uint8_t* out, const uint16_t* in, const uint16_t len) uint32_t viterbi_decode_punctured(uint8_t* out, const uint16_t* in, const uint8_t* punct, const uint16_t in_len, const uint16_t p_len) { - uint16_t umsg[400*2]; //unpunctured message + uint16_t umsg[600*2]; //unpunctured message uint16_t p=0; //puncturer matrix entry uint16_t u=0; //bits count - unpunctured message uint16_t i=0; //bits read from the input message