From f92d942685fe5674ceb1a235ebce88f3b613143d Mon Sep 17 00:00:00 2001 From: baobrien Date: Thu, 21 Sep 2017 04:27:36 +0000 Subject: [PATCH] Tried TDMA double-demod for out of range RX; didn't work git-svn-id: https://svn.code.sf.net/p/freetel/code@3372 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/src/tdma.c | 100 ++++++++++++++++++++++++++++-------------- codec2-dev/src/tdma.h | 17 ++++--- 2 files changed, 77 insertions(+), 40 deletions(-) diff --git a/codec2-dev/src/tdma.c b/codec2-dev/src/tdma.c index 0caabee5..379d5c5a 100644 --- a/codec2-dev/src/tdma.c +++ b/codec2-dev/src/tdma.c @@ -33,6 +33,7 @@ #include #include #include +#include static const uint8_t TDMA_UW_V[] = {0,1,1,0,0,1,1,1, @@ -240,6 +241,15 @@ int tdma_demod_end_slot(tdma_t * tdma,u32 slot_idx, u8 * bit_buf){ return f_valid; } + +/* Pull TDMA frame out of bit stream and call RX CB if present */ +void tdma_deframe_cbcall(u8 bits[], u32 slot_i, tdma_t * tdma, slot_t * slot){ + /* Right now we're not actually deframing the bits */ + if(tdma->rx_callback != NULL){ + tdma->rx_callback(bits,slot_i,slot,tdma,tdma->rx_cb_data); + } +} + /* We got a new slot's worth of samples. Run the slot modem and try to get slot sync */ /* This will probably also work for the slot_sync state */ void tdma_rx_pilot_sync(tdma_t * tdma){ @@ -286,43 +296,62 @@ void tdma_rx_pilot_sync(tdma_t * tdma){ frame_samps[i].imag = 0; } - /* Pull out the frame and demod */ - memcpy(&frame_samps[0],&sample_buffer[tdma->sample_sync_offset],slot_samps*sizeof(COMP)); - - - /* Demodulate the frame */ - fsk_demod(fsk,bit_buf,frame_samps); - + /* Flag to indicate whether or not we should re-do the demodulation */ + bool repeat_demod = false; + bool repeat_demod_2 = false; + int rdemod_offset = 0; size_t delta,off; - off = fvhff_search_uw(bit_buf,nbits,TDMA_UW_V,16,&delta,bits_per_sym); - i32 f_start = off- (frame_bits-16)/2; - int f_valid = 0; /* Flag indicating wether or not we've found a UW */ + i32 f_start; + i32 frame_offset; + bool f_valid = false; + /* Demod section in do-while loop so we can repeat once if frame is just outside of bit buffer */ + do{ + /* Pull out the frame and demod */ + memcpy(&frame_samps[0],&sample_buffer[tdma->sample_sync_offset+rdemod_offset],slot_samps*sizeof(COMP)); + + /* Demodulate the frame */ + fsk_demod(fsk,bit_buf,frame_samps); + off = fvhff_search_uw(bit_buf,nbits,TDMA_UW_V,16,&delta,bits_per_sym); + f_start = off- (frame_bits-16)/2; + + /* Check frame tolerance and sync state*/ + if(slot->state == rx_sync){ + f_valid = delta <= tdma->settings.frame_sync_tol; + }else if(slot->state == rx_no_sync){ + f_valid = delta <= tdma->settings.first_sync_tol; + } - /* Check frame tolerance and sync state*/ - if(slot->state == rx_sync){ - f_valid = delta <= tdma->settings.frame_sync_tol; - }else if(slot->state == rx_no_sync){ - f_valid = delta <= tdma->settings.first_sync_tol; - } + /* Calculate offset (in samps) from start of frame */ + /* Note: FSK outputs one symbol from the last batch, so we have to account for that */ + i32 target_frame_offset = ((slot_size-frame_size)/2)*Ts; + frame_offset = ((f_start-bits_per_sym)*(Ts/bits_per_sym)) - target_frame_offset; - /* Calculate offset (in samps) from start of frame */ - /* Note: FSK outputs one symbol from the last batch, so we have to account for that */ - i32 target_frame_offset = ((slot_size-frame_size)/2)*Ts; - i32 frame_offset = ((f_start-bits_per_sym)*(Ts/bits_per_sym)) - target_frame_offset; + /* Flag a large frame offset as a bad UW sync */ + if( abs(frame_offset) > (slot_samps/4) ) + f_valid = false; + + if(f_valid) + slot->slot_local_frame_offset = frame_offset; - /* Flag a large frame offset as a bad UW sync */ - if( abs(frame_offset) > (slot_samps/8) ) - f_valid = 0; - - if(f_valid) - slot->slot_local_frame_offset = frame_offset; + if(f_valid){ + fprintf(stderr,"Good UW\n"); + }else{ + fprintf(stderr,"Bad UW\n"); + } - if(f_valid){ - fprintf(stderr,"Good UW\n"); - }else{ - fprintf(stderr,"Bad UW\n"); - } - + /* Check to see if the bits are outside of the demod buffer. If so, adjust and re-demod*/ + /* Disabled for now; will re-enable when worked out better in head */ + /*if(f_valid && !repeat_demod){ + if((f_start < bits_per_sym) || ((f_start+(bits_per_sym*frame_size)) > (bits_per_sym*(slot_size+1)))){ + fprintf(stderr,"f_start: %d, Re-demod-ing\n",f_start); + repeat_demod = true; + repeat_demod_2 = true; + } + }else repeat_demod = false;*/ + + rdemod_offset = frame_offset; + + }while(repeat_demod); i32 single_slot_offset = slot->slot_local_frame_offset; /* Flag indicating wether or not we should call the callback */ @@ -356,7 +385,7 @@ void tdma_rx_pilot_sync(tdma_t * tdma){ /* Unicode underline for pretty printing */ char underline[] = {0xCC,0xB2,0x00}; - fprintf(stderr,"slot: %d fstart:%d offset: %d delta: %d f1:%.3f EbN0:%f\n",tdma->slot_cur,frame_offset,off,delta,fsk->f_est[0],fsk->EbNodB); + fprintf(stderr,"slot: %d fstart:%d offset: %d delta: %d f1:%.3f EbN0:%f\n",tdma->slot_cur,f_start,off,delta,fsk->f_est[0],fsk->EbNodB); for(i=0; ioff && i<=off+16) || i==f_start || i==(f_start+frame_bits-1)){ @@ -478,9 +507,12 @@ void tdma_rx(tdma_t * tdma, COMP * samps,u64 timestamp){ } -void tdma_set_rx_cb(tdma_t * tdma,tdma_cb_rx_frame rx_callback){ +void tdma_set_rx_cb(tdma_t * tdma,tdma_cb_rx_frame rx_callback,void * cb_data){ tdma->rx_callback = rx_callback; + tdma->rx_cb_data = cb_data; } + + #pragma GCC diagnostic pop diff --git a/codec2-dev/src/tdma.h b/codec2-dev/src/tdma.h index f3f5fa29..8872c7f4 100644 --- a/codec2-dev/src/tdma.h +++ b/codec2-dev/src/tdma.h @@ -78,8 +78,8 @@ struct TDMA_SLOT { enum slot_state state; /* Current local slot state */ i32 slot_local_frame_offset; /* Where the RX frame starts, in samples, from the perspective of the modem */ u32 bad_uw_count; /* How many bad UWs have we gotten since synchronized */ + i32 master_count; /* How likely is this frame to be a synchronization master */ struct TDMA_SLOT * next_slot; /* Next slot in a linked list of slots */ - }; typedef struct TDMA_SLOT slot_t; @@ -98,12 +98,21 @@ struct TDMA_MODE_SETTINGS { u32 first_sync_tol; /* UW errors allowed for a valid first frame sync */ u32 frame_sync_tol; /* UW errors allowed to maintain a frame sync */ u32 frame_sync_baduw_tol; /* How many bad UWs before calling a frame unsynced */ + u32 mastersat_max; /* Maximum count for master detection counter */ + u32 mastersat_min; /* Minimum count before frame considered 'master' */ }; /* Declaration of basic 4800bps freedv tdma mode, defined in tdma.h */ //struct TDMA_MODE_SETTINGS FREEDV_4800T; -#define FREEDV_4800T {2400,4,48000,48,44,2,FREEDV_VHF_FRAME_AT,16,1,1,1,0} +#define FREEDV_4800T {2400,4,48000,48,44,2,FREEDV_VHF_FRAME_AT,16,4,2,2,2,4,2} + + + +typedef struct TDMA_MODEM tdma_t; +/* Callback typedef that just returns the bits of the frame */ +/* TODO: write this a bit better */ +typedef void (*tdma_cb_rx_frame)(u8* frame_bits,u32 slot_i, slot_t * slot, tdma_t * tdma, void * cb_data); /* TDMA modem */ struct TDMA_MODEM { @@ -119,7 +128,6 @@ struct TDMA_MODEM { void * rx_cb_data; }; -typedef struct TDMA_MODEM tdma_t; /* Allocate and setup a new TDMA modem */ tdma_t * tdma_create(struct TDMA_MODE_SETTINGS mode); @@ -143,9 +151,6 @@ void tdma_print_stuff(tdma_t * tdma); void tdma_set_rx_cb(tdma_t * tdma,tdma_cb_rx_frame rx_callback,void * cb_data); -/* Callback typedef that just returns the bits of the frame */ -/* TODO: write this a bit better */ -typedef void (*tdma_cb_rx_frame)(u8* frame_bits,u32 slot_i, slot_t * slot, tdma_t * tdma, void * cb_data); #endif -- 2.25.1