Changeset 5465

Show
Ignore:
Timestamp:
10/21/07 14:40:20 (6 years ago)
Author:
jgaeddert
Message:

adding frequency estimation to beginning of frame header; works over-the-air

Location:
experimental/components/SymbolSyncPoly/branches/SymbolSyncPoly-metadata/src
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • experimental/components/SymbolSyncPoly/branches/SymbolSyncPoly-metadata/src/FrameSynchronizer.cpp

    r5463 r5465  
    294294 
    295295#if 0 
     296        N_out = buf_len; 
    296297        // Main signal processing algorithm 
    297298        DEBUG(7, FrameSynchronizer, "Attempting to synchronize and decimate...") 
     
    299300            I_in, Q_in, N_in, 
    300301            I_out, Q_out, N_out); 
    301 #endif 
     302        num_written = N_out; 
     303#endif 
     304#if 1 
    302305        DEBUG(7, FrameSynchronizer, "trying to find header..."); 
    303306        FindFrameHeader( 
    304307            I_in, Q_in, N_in, num_read, 
    305308            I_out, Q_out, buf_len, num_written); 
    306         //printf("fs cv = %f\n", cv/(2*PI)); 
     309        printf("fs cv = %f\n", cv/(2*PI)); 
     310        //printf("fs q_hat_c = %f\n", q_hat_c); 
     311#endif 
    307312 
    308313        DEBUG(7, FrameSynchronizer, "Emptying port buffer...") 
  • experimental/components/SymbolSyncPoly/branches/SymbolSyncPoly-metadata/src/FrameSynchronizerDSP.cpp

    r5463 r5465  
    5353    UpdateCostasLoopFilterCoefficients(0.02f); 
    5454 
     55    e_i = 0; 
     56    e_q = Ac; 
     57    lock_zeta = 0.02; 
     58    header_phase_locked = false; 
     59    header_phase_lock_delay = 64; 
     60    header_phase_lock_delay_counter = 0; 
     61 
    5562#ifdef FS_LOGGING 
    5663    input_log.open("framesync_input_log.dat"); 
     
    6875} 
    6976 
    70 // Find frame header 
     77// Find frame header using Costas loop 
     78bool FrameSynchronizerDSP::FindFrameHeaderCostasLoop( 
     79    short * I_in, 
     80    short * Q_in, 
     81    unsigned int input_length, 
     82    unsigned int &num_read, 
     83    short * I_out, 
     84    short * Q_out, 
     85    unsigned int output_length, 
     86    unsigned int &num_written) 
     87{ 
     88    alpha_s = 0.027f; 
     89    beta_s = 1.02f; 
     90 
     91    int i(0); 
     92    short I, Q; 
     93    num_read = 0; 
     94    num_written = 0; 
     95    //printf("nco CV = %f\n", cv/(2*PI)); 
     96 
     97    while ( i < (signed int) input_length ) { 
     98        v++; 
     99 
     100        // apply nco to input sample 
     101        ApplyNCO(I_in[i], Q_in[i], I, Q); 
     102        //I = I_in[i]; 
     103        //Q = Q_in[i]; 
     104        i++; 
     105 
     106        // push samples into buffer 
     107        PushInput(I, Q); 
     108 
     109        // compute filtered outputs (stored in mf_i, mf_q) 
     110        ComputeFilterBankOutputs(); 
     111         
     112        // compute costas loop phase error on matched-filter outputs 
     113        ///\todo matched filter output won't work because of delay 
     114        pd2_cl = GenerateCostasLoopPhaseError(I, Q); 
     115        //pd2_cl = GenerateCostasLoopPhaseError(mf_i, mf_q); 
     116        pd2_cl /= Ac; 
     117         
     118        // advance costas loop filter 
     119        AdvanceCostasLoopFilter(); 
     120 
     121        // update nco 
     122        UpdateNCO(); 
     123            //I_out[num_written] = mf_i; 
     124            //Q_out[num_written] = mf_q; 
     125            //num_written++; 
     126 
     127        // decimate 
     128        if ( v >= (signed int) k ) { 
     129            // enable output 
     130            v -= k; 
     131            I_out[num_written] = mf_i; 
     132            Q_out[num_written] = mf_q; 
     133            num_written++; 
     134            //printf("I = %d, Q = %d\n", mf_i, mf_q); 
     135 
     136            // generate timing error 
     137            GenerateTimingError(); 
     138 
     139            // advance timing loop filter 
     140            AdvanceTimingLoopFilter(); 
     141 
     142            // compute filter bank index 
     143            ComputeFilterBankIndex(); 
     144 
     145            // update v 
     146            switch (lc) { 
     147            case SHIFT: 
     148                // normal operation; do nothing 
     149                break; 
     150            case SKIP: 
     151                v--; 
     152                //printf("skip\n"); 
     153                lc = SHIFT; 
     154                break; 
     155            case STUFF: 
     156                v++; 
     157                //printf("stuff\n"); 
     158                lc = SHIFT; 
     159                break; 
     160            default:; 
     161            } 
     162 
     163            // push sample into buffer 
     164            inputBuffer.Push(mf_i); 
     165            r = CorrelateSequence( pnFrameSyncCode, 255 ); 
     166 
     167            if ( abs(r) > int( Ac/2 ) ) { 
     168                r_frame_sync = abs(r); 
     169                std::cout << "PN FRAME SYNC CODE FOUND!!!" << std::endl; 
     170                std::cout << "  r = " << r_frame_sync << std::endl; 
     171 
     172                // check for phase inversion; if so inject pi radians into NCO 
     173                // [not sure how well this will work with band-limited pulse shapes] 
     174                if ( r<0 ) { 
     175                    std::cout << "  [Frame sync found negative PN code]" << std::endl; 
     176                    nco_control += PI; 
     177                } 
     178 
     179                operationalMode = EXTRACT_CONTROL_CODES; 
     180                inputBuffer.Release(); 
     181                numControlCodesReceived = 0; 
     182 
     183                //num_read = i+1; 
     184                //return true; 
     185 
     186                // reduce bandwidth of loop filters for steady tracking mode 
     187                //UpdatePhaseLoopFilterCoefficients(0.0025f); 
     188                //UpdateTimingLoopFilterCoefficients(ALPHA_T_LO, BETA_T_LO); 
     189 
     190            } 
     191 
     192        } 
     193    } 
     194     
     195    num_read = input_length; 
     196    return false; 
     197} 
     198 
     199// Extract frame header 
     200bool FrameSynchronizerDSP::ExtractFrameHeader( 
     201    short * I_in, 
     202    short * Q_in, 
     203    unsigned int input_length, 
     204    unsigned int &num_read, 
     205    short * I_out, 
     206    short * Q_out, 
     207    unsigned int output_length, 
     208    unsigned int &num_written) 
     209{ 
     210    //unsigned int i; 
     211    //short I, Q; 
     212    //num_read = 0; 
     213    //num_written = 0; 
     214    return false; 
     215} 
     216 
     217 
     218// Find frame header using conventional method 
    71219bool FrameSynchronizerDSP::FindFrameHeader( 
    72220    short * I_in, 
     
    79227    unsigned int &num_written) 
    80228{ 
    81     alpha_s = 0.027f; 
    82     beta_s = 1.02f; 
    83  
    84     int i(0); 
    85     short I, Q; 
     229    unsigned int i(0); 
    86230    num_read = 0; 
    87231    num_written = 0; 
    88     //printf("nco CV = %f\n", cv/(2*PI)); 
    89  
    90     while ( i < (signed int) input_length ) { 
     232    alpha_c = 0.04f; 
     233    beta_c = 0.0028284f; 
     234 
     235    while ( i<input_length ) { 
     236        // Increment sample counter for output enable 
    91237        v++; 
    92238 
    93         // apply nco to input sample 
    94         ApplyNCO(I_in[i], Q_in[i], I, Q); 
    95         //I = I_in[i]; 
    96         //Q = Q_in[i]; 
    97         i++; 
    98  
    99         // push samples into buffer 
    100         PushInput(I, Q); 
    101  
    102         // compute filtered outputs (stored in mf_i, mf_q) 
    103         ComputeFilterBankOutputs(); 
    104          
    105         // compute costas loop phase error on matched-filter outputs 
    106         ///\todo matched filter output won't work because of delay 
    107         //pd2_cl = GenerateCostasLoopPhaseError(I, Q); 
    108         pd2_cl = GenerateCostasLoopPhaseError(mf_i, mf_q); 
    109         pd2_cl /= Ac; 
    110          
    111         // advance costas loop filter 
    112         AdvanceCostasLoopFilter(); 
    113  
    114         // update nco 
    115         UpdateNCO(); 
    116             //I_out[num_written] = mf_i; 
    117             //Q_out[num_written] = mf_q; 
    118             //num_written++; 
    119  
    120         // decimate 
     239        PushInputs( I_in, Q_in, i, input_length ); 
     240 
    121241        if ( v >= (signed int) k ) { 
    122             // enable output 
     242            // Enable output 
    123243            v -= k; 
     244 
     245            // Decimate values; compute filter outputs mf_i, mf_q, dmf_i, dmf_q 
     246            ComputeFilterBankOutputs(); 
     247 
    124248            I_out[num_written] = mf_i; 
    125249            Q_out[num_written] = mf_q; 
    126250            num_written++; 
    127             //printf("I = %d, Q = %d\n", mf_i, mf_q); 
    128  
    129             // generate timing error 
    130             GenerateTimingError(); 
    131  
    132             // advance timing loop filter 
    133             AdvanceTimingLoopFilter(); 
    134  
    135             // compute filter bank index 
    136             ComputeFilterBankIndex(); 
    137  
    138             // update v 
    139             switch (lc) { 
    140             case SHIFT: 
    141                 // normal operation; do nothing 
    142                 break; 
    143             case SKIP: 
    144                 v--; 
    145                 //printf("skip\n"); 
    146                 lc = SHIFT; 
    147                 break; 
    148             case STUFF: 
    149                 v++; 
    150                 //printf("stuff\n"); 
    151                 lc = SHIFT; 
    152                 break; 
    153             default:; 
    154             } 
    155  
    156             // push sample into buffer 
     251 
     252            // push sample into buffer and correlate with frame sync code 
    157253            inputBuffer.Push(mf_i); 
    158254            r = CorrelateSequence( pnFrameSyncCode, 255 ); 
     
    183279            } 
    184280 
     281            // generate timing error 
     282            GenerateTimingError(); 
     283 
     284            // advance timing loop filter 
     285            AdvanceTimingLoopFilter(); 
     286 
     287            // compute filter bank index 
     288            ComputeFilterBankIndex(); 
     289 
     290 
     291            // Update lock detection 
     292            e_i = lock_zeta*(float)(abs(mf_i)) + (1-lock_zeta)*e_i; 
     293            e_q = lock_zeta*(float)(abs(mf_q)) + (1-lock_zeta)*e_q; 
     294            header_phase_lock_delay_counter++; 
     295            lock_detect = e_i/e_q; 
     296            if ( header_phase_lock_delay_counter == header_phase_lock_delay && 
     297                 lock_detect < 1.25f ) { 
     298                header_phase_lock_delay_counter = 0; 
     299                lock_detect = e_i/e_q; 
     300                printf("  lock_detect = %f\n", lock_detect); 
     301                //if ( lock_detect < 1.25 ) { 
     302                    unsigned int N_est = (input_length < 256) ? input_length : 256; 
     303                    wcTs = 2*PI*EstimateCarrierOffset(I_in, Q_in, N_est, false); 
     304                    printf("  estimate: %f\n", wcTs/(2*PI)); 
     305                    cv = 0; 
     306                    nco_control = 0; 
     307                    q_c = 0; 
     308                    q_hat_c = 0; 
     309                    buff2_c = 0; 
     310                    q_prime_c = 0; 
     311                //} 
     312            } else { 
     313                // Calculate phase error 
     314 
     315                q_c = GeneratePhaseError( mf_i, mf_q ); 
     316                q_c /= Ac; 
     317            } 
     318 
     319            AdvancePhaseLoopFilter(); 
     320 
    185321        } 
     322        UpdateNCO(); 
     323 
    186324    } 
    187      
     325 
    188326    num_read = input_length; 
    189327    return false; 
    190328} 
    191329 
    192 // Find frame header 
    193 bool FrameSynchronizerDSP::ExtractFrameHeader( 
    194     short * I_in, 
    195     short * Q_in, 
    196     unsigned int input_length, 
    197     unsigned int &num_read, 
    198     short * I_out, 
    199     short * Q_out, 
    200     unsigned int output_length, 
    201     unsigned int &num_written) 
    202 { 
    203     unsigned int i; 
    204     short I, Q; 
    205     num_read = 0; 
    206     num_written = 0; 
    207     return false; 
    208 } 
     330 
    209331 
    210332// Main signal processing loop 
     
    392514            AdvancePhaseLoopFilter(); 
    393515 
    394             UpdateNCO(); 
    395  
    396516        } 
    397517 
     518        UpdateNCO(); 
     519 
    398520    } // while 
     521 
    399522} 
    400523 
  • experimental/components/SymbolSyncPoly/branches/SymbolSyncPoly-metadata/src/FrameSynchronizerDSP.h

    r5463 r5465  
    5454 
    5555    /// \brief Uses a CostasLoop to lock to the carrier, correlates with P/N sequence 
     56    bool FindFrameHeaderCostasLoop( 
     57        short * I_in, 
     58        short * Q_in, 
     59        unsigned int input_length, 
     60        unsigned int &num_read, 
     61        short * I_out, 
     62        short * Q_out, 
     63        unsigned int output_length, 
     64        unsigned int &num_written); 
     65 
    5666    bool FindFrameHeader( 
    5767        short * I_in, 
     
    133143    unsigned int r_frame_sync; 
    134144 
     145    // Phase lock detect variables 
     146    float e_i; 
     147    float e_q; 
     148    float lock_zeta; 
     149    float lock_detect; 
     150    bool header_phase_locked; 
     151    unsigned int header_phase_lock_delay; 
     152    unsigned int header_phase_lock_delay_counter; 
     153 
    135154    // Costas loop methods 
    136155 
     
    147166 
    148167        ///\todo this is necessary because of the delay introduced by the filter 
    149         beta_cl /= 30.0f; 
     168        //beta_cl /= 30.0f; 
    150169    }; 
    151170 
  • experimental/components/SymbolSyncPoly/branches/SymbolSyncPoly-metadata/src/MultirateSynchronizerDSP.cpp

    r5464 r5465  
    243243 
    244244void MultirateSynchronizerDSP::UpdateNCO() { 
    245     cv = wcTs + q_hat_c; 
     245    cv = wcTs + q_hat_c/k; 
    246246 
    247247    cv = ( cv >  PI/50 ) ?  PI/50 : cv;