tracking algorithm. If we lose sync we switch back to coarse mode
for fast re-acquisition of large frequency offsets.
+ The sync state is also useful for higher layers to determine when
+ there is valid FDMDV data for decoding. We want to reliably and
+ quickly get into sync, stay in sync even on fading channels, and
+ fall out of sync quickly if tx stops or it's a false sync.
+
+ In multipath fading channels the BPSK sync carrier may be pushed
+ down in the noise, despite other carriers being at full strength.
+ We want to avoid loss of sync in these cases.
+
\*---------------------------------------------------------------------------*/
int freq_state(int sync_bit, int *state)
{
int next_state, coarse_fine;
+ int bad_sync = 0;
/* acquire state, look for 6 symbol 010101 sequence from sync bit */
next_state = 0;
break;
case 5:
- if (sync_bit == 1)
+ if (sync_bit == 1) {
next_state = 6;
+ bad_sync = 0;
+ }
else
next_state = 0;
break;
/* states 6 and above are track mode, make sure we keep
- getting 0101 sync bit sequence */
+ 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)
- next_state = 7;
- else
- next_state = 0;
+ bad_sync = 0;
+ else {
+ bad_sync++;
+ if (bad_sync > 2)
+ next_state = 0;
+ }
break;
case 7:
+ next_state = 6;
if (sync_bit == 1)
- next_state = 6;
- else
- next_state = 0;
+ bad_sync = 0;
+ else {
+ bad_sync++;
+ if (bad_sync > 2)
+ next_state = 0;
+ }
break;
}
int f;
FILE *foct = NULL;
struct FDMDV_STATS stats;
- float *rx_fdm_log;
+ COMP *rx_fdm_log;
int rx_fdm_log_col_index;
COMP rx_symbols_log[FDMDV_NSYM][MAX_FRAMES];
int coarse_fine_log[MAX_FRAMES];
/* malloc some of the bigger variables to prevent out of stack problems */
- rx_fdm_log = (float*)malloc(sizeof(float)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES);
+ rx_fdm_log = (COMP*)malloc(sizeof(COMP)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES);
assert(rx_fdm_log != NULL);
rx_spec_log = (float*)malloc(sizeof(float)*FDMDV_NSPEC*MAX_FRAMES);
assert(rx_spec_log != NULL);
/* log modem states for later dumping to Octave log file */
- memcpy(&rx_fdm_log[rx_fdm_log_col_index], rx_fdm, sizeof(float)*nin_prev);
+ memcpy(&rx_fdm_log[rx_fdm_log_col_index], rx_fdm, sizeof(COMP)*nin_prev);
rx_fdm_log_col_index += nin_prev;
for(c=0; c<FDMDV_NSYM; c++)
argv[3], strerror(errno));
exit(1);
}
- octave_save_float(foct, "rx_fdm_log_c", rx_fdm_log, 1, rx_fdm_log_col_index, FDMDV_MAX_SAMPLES_PER_FRAME);
+ octave_save_complex(foct, "rx_fdm_log_c", rx_fdm_log, 1, rx_fdm_log_col_index, FDMDV_MAX_SAMPLES_PER_FRAME);
octave_save_complex(foct, "rx_symbols_log_c", (COMP*)rx_symbols_log, FDMDV_NSYM, 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);