new sync state machine for demod
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 18 Mar 2013 04:22:06 +0000 (04:22 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 18 Mar 2013 04:22:06 +0000 (04:22 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1208 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/codec2_fdmdv.h
codec2-dev/src/fdmdv.c
codec2-dev/src/fdmdv_demod.c
codec2-dev/src/fdmdv_internal.h

index f9f73fb0281164d69eefd4b7896e0dbb220a17b9..e0e8abb79b129198912ad37342c82be9800d166d 100644 (file)
@@ -84,7 +84,7 @@ struct FDMDV_STATS {
     int    Nc;
     float  snr_est;                    /* estimated SNR of rx signal in dB (3 kHz noise BW)  */
     COMP   rx_symbols[FDMDV_NC_MAX+1]; /* latest received symbols, for scatter plot          */ 
-    int    fest_coarse_fine;           /* freq est state, 0-coarse 1-fine                    */ 
+    int    sync;                       /* demod sync state                                   */ 
     float  foff;                       /* estimated freq offset in Hz                        */       
     float  rx_timing;                  /* estimated optimum timing offset in samples         */
     float  clock_offset;               /* Estimated tx/rx sample clock offset in ppm         */
index 509a02ae5b20c9d1d5bfb97a787a8e7aaa90290c..1d6f33a620ea6cdf572e67141a45f47b5075845d 100644 (file)
@@ -46,7 +46,9 @@
 #include "hanning.h"
 #include "os.h"
 
-/*---------------------------------------------------------------------------*\
+static int sync_uw[] = {1,-1,1,-1,1,-1};
+
+/*---------------------------------------------------------------------------* \
                                                                              
                                FUNCTIONS
 
@@ -229,8 +231,10 @@ struct FDMDV * CODEC2_WIN32SUPPORT fdmdv_create(int Nc)
     f->foff_phase_rect.imag = 0.0;
 
     f->fest_state = 0;
-    f->coarse_fine = COARSE;
-    f->bad_sync = 0;
+    f->sync = 0;
+    f->timer = 0;
+    for(i=0; i<NSYNC_MEM; i++)
+        f->sync_mem[i] = 0;
 
     for(c=0; c<Nc+1; c++) {
        f->sig_est[c] = 0.0;
@@ -1179,87 +1183,65 @@ void CODEC2_WIN32SUPPORT fdmdv_put_test_bits(struct FDMDV *f, int *sync, short e
 
 \*---------------------------------------------------------------------------*/
 
-int freq_state(int sync_bit, int *state, int *bad_sync)
+int freq_state(int sync_bit, int *state, int *timer, int *sync_mem)
 {
-    int next_state, coarse_fine;
+    int next_state, sync, unique_word, i, corr;
+
+    /* look for 6 symbols (120ms) 010101 of sync sequence */
 
-    /* acquire state, look for 6 symbol 010101 sequence from sync bit */
+    unique_word = 0;
+    for(i=0; i<NSYNC_MEM-1; i++)
+        sync_mem[i] = sync_mem[i+1];
+    sync_mem[i] = sync_bit;
+    corr = 0;
+    for(i=0; i<NSYNC_MEM; i++)
+        corr += sync_mem[i]*sync_uw[i];
+    if (corr == NSYNC_MEM)
+        unique_word = 1;
+
+    /* iterate state machine */
 
     next_state = *state;
     switch(*state) {
     case 0:
-       if (sync_bit == 0)
+       if (unique_word) {
            next_state = 1;
+            *timer = 0;
+        }
        break;
-    case 1:
-       if (sync_bit == 1)
-           next_state = 2;
-       else 
-           next_state = 0;
-       break;
-    case 2:
-       if (sync_bit == 0)
-           next_state = 3;
-       else 
-           next_state = 0;
-       break;
-    case 3:
-       if (sync_bit == 1)
-           next_state = 4;
-       else 
-           next_state = 0;
-       break;
-    case 4:
-       if (sync_bit == 0)
-           next_state = 5;
-       else 
-           next_state = 0;
-       break;
-    case 5:
-       if (sync_bit == 1) {
-           next_state = 6;
-            *bad_sync = 0;
+    case 1:                  /* tentative sync state         */
+       if (unique_word) {
+            (*timer)++;
+            if (*timer == 25) /* sync has been good for 500ms */
+                next_state = 2;
         }
        else 
-           next_state = 0;
+           next_state = 0;  /* quickly fall out of sync     */
        break;
-       
-       /* states 6 and above are track mode, make sure we keep
-          getting 0101 sync bit sequence. bad_sync allows us to track
-          through a few bad symbols when BPSK pilot is temporarilly
-          faded out, avoiding a costly re-sync when valid data still
-          exists on other carriers */
-
-    case 6:
-        next_state = 7;
-       if (sync_bit == 0)
-            *bad_sync = 0;
-       else {
-            (*bad_sync)++;
-            if (*bad_sync > 2)
-                next_state = 0;
+    case 2:                  /* good sync state */
+       if (unique_word == 0) {
+            *timer = 0;
+           next_state = 3;
         }
-
        break;
-    case 7:
-        next_state = 6;
-       if (sync_bit == 1)
-           *bad_sync = 0;
-        else {
-            (*bad_sync)++;
-            if (*bad_sync > 2)
+    case 3:                  /* tentative bad state, but could be a fade */
+       if (unique_word)
+           next_state = 2;
+       else  {
+            (*timer)++;
+            if (*timer == 50) /* wait for 1000ms in case sync comes back  */
                 next_state = 0;
         }
        break;
     }
 
     *state = next_state;
-    if (*state >= 6)
-       coarse_fine = FINE;
+    if (*state)
+       sync = 1;
     else
-       coarse_fine = COARSE;
+       sync = 0;
  
-    return coarse_fine;
+    return sync;
 }
 
 /*---------------------------------------------------------------------------*\
@@ -1296,7 +1278,7 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
    
     foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, *nin);
     
-    if (fdmdv->coarse_fine == COARSE)
+    if (fdmdv->sync == 0)
        fdmdv->foff = foff_coarse;
     fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_rect, &fdmdv->foff_phase_rect, *nin);
        
@@ -1323,7 +1305,7 @@ void CODEC2_WIN32SUPPORT fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
 
     /* freq offset estimation state machine */
 
-    fdmdv->coarse_fine = freq_state(*sync_bit, &fdmdv->fest_state, &fdmdv->bad_sync);
+    fdmdv->sync = freq_state(*sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem);
     fdmdv->foff  -= TRACK_COEFF*foff_fine;
 }
 
@@ -1388,7 +1370,7 @@ void CODEC2_WIN32SUPPORT fdmdv_get_demod_stats(struct FDMDV *fdmdv,
 
     fdmdv_stats->Nc = fdmdv->Nc;
     fdmdv_stats->snr_est = calc_snr(fdmdv->Nc, fdmdv->sig_est, fdmdv->noise_est);
-    fdmdv_stats->fest_coarse_fine = fdmdv->coarse_fine;
+    fdmdv_stats->sync = fdmdv->sync;
     fdmdv_stats->foff = fdmdv->foff;
     fdmdv_stats->rx_timing = fdmdv->rx_timing;
     fdmdv_stats->clock_offset = 0.0; /* TODO - implement clock offset estimation */
index 2559ee5bd4f94a525f3214554b1fe0f016b779ff..fd47050f4704a0a65785fadfc27ea5850e1219ed 100644 (file)
@@ -66,7 +66,7 @@ int main(int argc, char *argv[])
     COMP         *rx_fdm_log;
     int           rx_fdm_log_col_index;
     COMP         *rx_symbols_log;
-    int           coarse_fine_log[MAX_FRAMES];
+    int           sync_log[MAX_FRAMES];
     float         rx_timing_log[MAX_FRAMES];
     float         foff_log[MAX_FRAMES];
     int           sync_bit_log[MAX_FRAMES];
@@ -164,7 +164,7 @@ int main(int argc, char *argv[])
                rx_symbols_log[f*(Nc+1)+c] = stats.rx_symbols[c];
            foff_log[f] = stats.foff;
            rx_timing_log[f] = stats.rx_timing;
-           coarse_fine_log[f] = stats.fest_coarse_fine;
+           sync_log[f] = stats.sync;
            sync_bit_log[f] = sync_bit;
            memcpy(&rx_bits_log[bits_per_fdmdv_frame*f], rx_bits, sizeof(int)*bits_per_fdmdv_frame);
            snr_est_log[f] = stats.snr_est;
@@ -240,7 +240,7 @@ int main(int argc, char *argv[])
            octave_save_complex(foct, "rx_symbols_log_c", (COMP*)rx_symbols_log, Nc+1, f, MAX_FRAMES);  
            octave_save_float(foct, "foff_log_c", foff_log, 1, f, MAX_FRAMES);  
            octave_save_float(foct, "rx_timing_log_c", rx_timing_log, 1, f, MAX_FRAMES);  
-           octave_save_int(foct, "coarse_fine_log_c", coarse_fine_log, 1, f);  
+           octave_save_int(foct, "sync_log_c", sync_log, 1, f);  
            octave_save_int(foct, "rx_bits_log_c", rx_bits_log, 1, bits_per_fdmdv_frame*f);
            octave_save_int(foct, "sync_bit_log_c", sync_bit_log, 1, f);  
            octave_save_float(foct, "snr_est_log_c", snr_est_log, 1, f, MAX_FRAMES);  
index 87fb93c2ba7c48a2d52d2b16dcabc2534885dfaa..b4cf62ff19dc0962700fc0b35756e9899151d240 100644 (file)
 #define NPILOTLPF                  (4*M)    /* number of samples we DFT pilot over, pilot est window */
 #define MPILOTFFT                    256
 
-/* freq offset sestimation states */
-
-#define COARSE                   0
-#define FINE                     1
+#define NSYNC_MEM                6
 
 /* averaging filter coeffs */
 
@@ -129,11 +126,12 @@ struct FDMDV {
     COMP  phase_difference[NC+1];
     COMP  prev_rx_symbols[NC+1];
     
-    /* freq est state machine */
+    /* sync state machine */
 
+    int  sync_mem[NSYNC_MEM];
     int  fest_state;
-    int  coarse_fine;
-    int  bad_sync;
+    int  sync;
+    int  timer;
 
     /* SNR estimation states */
 
@@ -171,7 +169,7 @@ float rx_est_timing(COMP  rx_symbols[], int Nc,
                   int   nin);   
 float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
 void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
-int freq_state(int sync_bit, int *state, int *bad_sync);
+int freq_state(int sync_bit, int *state, int *timer, int *sync_mem);
 float calc_snr(int Nc, float sig_est[], float noise_est[]);
 
 #endif