digital_pll.cpp
上传用户:jtjnyq9001
上传日期:2014-11-21
资源大小:3974k
文件大小:10k
源码类别:

3G开发

开发平台:

Visual C++

  1. //
  2. //  File = digital_pll.cpp
  3. //
  4. #include "parmfile.h"
  5. #include "misdefs.h"
  6. #include "model_error.h"
  7. #include "digital_pll.h"
  8. #include "butt_filt_iir.h"
  9. #include "model_graph.h"
  10. extern ParmFile *ParmInput;
  11. extern PracSimModel *ActiveModel;
  12. //======================================================
  13. DigitalPLL::DigitalPLL( 
  14.                     char* instance_name,
  15.                     PracSimModel* outer_model,
  16.                     Signal<float>* fsig_input,
  17.                     Signal<float>* fsig_filtered_error,
  18.                     Signal<float>* fsig_vco_output,
  19.                     Signal<float>* vco_freq_sig,
  20.                     Signal<float>* ref_phase_sig,
  21.                     Signal<float>* out_sig )
  22.               :PracSimModel( instance_name,
  23.                              outer_model)
  24. {
  25.    MODEL_NAME(DigitalPLL);
  26.    //---------------------------------------
  27.    //  Read model config parms
  28.    OPEN_PARM_BLOCK;
  29.    GET_DOUBLE_PARM(K_Sub_D);
  30.    GET_DOUBLE_PARM(K_Sub_0);
  31.    GET_DOUBLE_PARM(Center_Freq_Hz);
  32.    GET_BOOL_PARM(m_UsingDco);
  33.    GET_DOUBLE_PARM(Tau_1);
  34.    GET_DOUBLE_PARM(Tau_2);
  35.    GET_DOUBLE_PARM(Supply_Volts);
  36.    //--------------------------------------
  37.    //  Connect input and output signals
  38.    fsig_Input = fsig_input;
  39.    fsig_Filtered_Error = fsig_filtered_error;
  40.    fsig_Osc_Output = fsig_vco_output;
  41.    fsig_Osc_Freq = vco_freq_sig;
  42.    fsig_Osc_Phase = ref_phase_sig;
  43.    fsig_Output = out_sig;
  44.    MAKE_OUTPUT( fsig_Output );
  45.    MAKE_OUTPUT( fsig_Filtered_Error );
  46.    MAKE_OUTPUT( fsig_Osc_Output );
  47.    MAKE_OUTPUT( fsig_Osc_Freq );
  48.    MAKE_OUTPUT( fsig_Osc_Phase );
  49.    MAKE_INPUT( fsig_Input );
  50.    //----------------------------------
  51.    //  Compute derived parameters
  52.    Omega_Sub_0 = TWO_PI * Center_Freq_Hz;
  53.    //--------------------------------
  54.    // create loop filter object
  55.    char sub_name[50];
  56.    strcpy(sub_name, GetInstanceName());
  57.    strcat(sub_name, ":Filter");
  58.    Filter_Core = new 
  59.       ButterworthFilterByIir<float>( sub_name, this);
  60. }
  61. //======================================================
  62. DigitalPLL::~DigitalPLL( void ){ };
  63. //======================================================
  64. void DigitalPLL::Initialize(void)
  65. {
  66.    //------------------
  67.    int block_size = fsig_Output->GetBlockSize();
  68.    Samp_Intvl = fsig_Input->GetSampIntvl();
  69.    Filter_Core->Initialize(block_size, Samp_Intvl);
  70.    Osc_Output_Prev_Val = 0.0;
  71.    OscOutput = 0;
  72.    Phi_Sub_2 = 0;
  73.    Prev_Input_Positive = true;
  74.    Prev_Input_Val = 0;
  75.    Prev_Filt_Val = 0;
  76.    Prev_Time_Zc = 0;
  77.    Prev_State = 0;
  78.    Prev_Cap_Val = 0;
  79.    Time_Of_Samp = 0.0;
  80.    Prev_Osc_Phase = 0.0;
  81. }
  82. //======================================================
  83. int DigitalPLL::Execute()
  84. {
  85.    // pointers for signal data
  86.    float *fsOutput_ptr;
  87.    float *fs_filtered_error_ptr;
  88.    float *fsOscOutput_ptr;
  89.    float *fsOscFreq_ptr;
  90.    float *fsOscPhase_ptr;
  91.    float *fsInput_ptr;
  92.    float input_val;
  93.    float prev_input_val;
  94.    float osc_output_val;
  95.    float filt_val;
  96.    float inst_freq;
  97.    double samp_intvl;
  98.    double err_sum=0;
  99.    double err_avg;
  100.    int is;
  101.    int block_size;
  102.    double time_of_samp;
  103.    double time_zc;
  104.    double delta_T;
  105.    double osc_phase;
  106.    double cap_val;
  107.    double prev_cap_val;
  108.    double prev_osc_phase;
  109.    double prev_filt_val;
  110.    double prev_time_zc;
  111.    double output_phase;
  112.    double tau_n;
  113.    int prev_state;
  114.    int new_state;
  115.    double time_dwell_plus;
  116.    double time_dwell_minus;
  117.    //---------------------------------------------------
  118.    // set up pointers to data buffers for input and 
  119.    // output signals
  120.    fsOutput_ptr = GET_OUTPUT_PTR( fsig_Output );
  121.    fs_filtered_error_ptr = 
  122.                GET_OUTPUT_PTR( fsig_Filtered_Error );
  123.    fsOscOutput_ptr = GET_OUTPUT_PTR( fsig_Osc_Output );
  124.    fsOscFreq_ptr = GET_OUTPUT_PTR( fsig_Osc_Freq );
  125.    fsOscPhase_ptr = GET_OUTPUT_PTR( fsig_Osc_Phase );
  126.    fsInput_ptr = GET_INPUT_PTR( fsig_Input );
  127.    samp_intvl = Samp_Intvl;
  128.    osc_output_val = Osc_Output_Prev_Val;
  129.    prev_input_val = Prev_Input_Val;
  130.    prev_filt_val = Prev_Filt_Val;
  131.    prev_time_zc = Prev_Time_Zc;
  132.    prev_state = Prev_State;
  133.    prev_cap_val = Prev_Cap_Val;
  134.    prev_osc_phase = Prev_Osc_Phase;
  135.    block_size = fsig_Input->GetValidBlockSize();
  136.    fsig_Output->SetValidBlockSize(block_size);
  137.    fsig_Filtered_Error->SetValidBlockSize(block_size);
  138.    fsig_Osc_Output->SetValidBlockSize(block_size);
  139.    fsig_Osc_Freq->SetValidBlockSize(block_size);
  140.    fsig_Osc_Phase->SetValidBlockSize(block_size);
  141.    for (is=0; is<block_size; is++){
  142.       time_of_samp = Time_Of_Samp + (is+1)*samp_intvl;
  143.       //----------------------------------
  144.       //  Look for zero crossing 
  145.       *fsOscOutput_ptr++ = osc_output_val;
  146.       input_val = *fsInput_ptr;
  147.       if( (input_val >= 0) != Prev_Input_Positive){
  148.          // zero crossing has occurred
  149.          time_zc = time_of_samp - samp_intvl * 
  150.                input_val /(input_val - prev_input_val);
  151.          // compute elapsed interval
  152.          delta_T = time_zc - prev_time_zc;
  153.          // update oscillator phase
  154.          inst_freq = 
  155.                Omega_Sub_0 + K_Sub_0 * prev_filt_val;
  156.          osc_phase = 
  157.                prev_osc_phase + inst_freq * delta_T;
  158.          // based on osc_phase and prev_osc_phase, 
  159.          // determine if the oscillator waveform has
  160.          // had a positive-going zero crossing between
  161.          // times prev_time_zc and time_zc.
  162.          //
  163.          // Normalize osc_phase and prev-osc_phase
  164.          if(osc_phase > TWO_PI){
  165.             osc_phase -= TWO_PI;
  166.             prev_osc_phase -= TWO_PI;
  167.          }
  168.          if(osc_phase >= 0.0 && prev_osc_phase < 0.0){
  169.             // a positive-going zero crossing has 
  170.             // occurred, so compute the crossing time
  171.             tau_n = -delta_T * prev_osc_phase/ 
  172.                         ( osc_phase - prev_osc_phase);
  173.          }
  174.          else{
  175.             tau_n = 0.0;
  176.          }
  177.          //------------------------------------------
  178.          // do state machine for phase detector
  179.          switch (prev_state){
  180.          case 1:
  181.             if(tau_n !=0.0){
  182.                new_state = 0;
  183.                time_dwell_plus = tau_n;
  184.                time_dwell_minus = 0.0;
  185.             }
  186.             else{
  187.                new_state = 0;
  188.                time_dwell_plus = delta_T;
  189.                time_dwell_minus = 0.0;
  190.             }
  191.             break;
  192.          case -1:
  193.             if(!Prev_Input_Positive){
  194.                //step 3 Algorithm 12.3
  195.                new_state = -1;
  196.                time_dwell_plus = 0.0;
  197.                time_dwell_minus = delta_T;
  198.             }
  199.             else{
  200.                if(tau_n != 0.0){
  201.                   //step 4a Algorithm 12.3
  202.                   new_state = -1;
  203.                   time_dwell_plus = 0.0;
  204.                   time_dwell_minus = delta_T - tau_n;
  205.                }
  206.                else{
  207.                    //step 4b Algorithm 12.3
  208.                   new_state = 0;
  209.                   time_dwell_plus = 0.0;
  210.                   time_dwell_minus = 0.0;
  211.               }
  212.             }
  213.             break;
  214.          case 0:
  215.             if(Prev_Input_Positive){
  216.                if(tau_n != 0.0 ){
  217.                   // step 5a Algorithm 12.3
  218.                   new_state = 0;
  219.                   time_dwell_plus = tau_n;
  220.                   time_dwell_minus = 0.0;
  221.                }
  222.                else{
  223.                   // step 5b Algorithm 12.3
  224.                   new_state = 1;
  225.                   time_dwell_plus = delta_T;
  226.                   time_dwell_minus = 0.0;
  227.                }
  228.             }
  229.             else{
  230.                if(tau_n != 0.0 ){
  231.                   // step 6a Algorithm 12.3
  232.                   new_state = -1;
  233.                   time_dwell_plus = 0.0;
  234.                   time_dwell_minus = delta_T - tau_n;
  235.                }
  236.                else{
  237.                   // step 6b Algorithm 12.3
  238.                   new_state = 0;
  239.                   time_dwell_plus = 0.0;
  240.                   time_dwell_minus = 0.0;
  241.                }
  242.             }
  243.          }
  244.          // end of state machine
  245.          //------------------------------------------
  246.          // Perform Filtering
  247.          //
  248.          if(time_dwell_plus == 0 && 
  249.                               time_dwell_minus == 0){
  250.             // step 6 Algorithm 12.5
  251.             cap_val = prev_cap_val;
  252.             filt_val = cap_val;
  253.          }
  254.          else{
  255.             if(time_dwell_minus > 0){
  256.                // step 7 Algorithm 12.5
  257.                cap_val = prev_cap_val*(1.0 - 
  258.                      time_dwell_minus/(Tau_1 + Tau_2));
  259.                filt_val = cap_val * (1.0 - (Tau_2/
  260.                      (Tau_1+Tau_2))*
  261.                      (time_dwell_minus/delta_T));
  262.             }
  263.             else{
  264.                // step 8 Algorithm 12.5
  265.                cap_val = prev_cap_val + 
  266.                      (time_dwell_plus/(Tau_1 + Tau_2))*
  267.                      (Supply_Volts - prev_cap_val);
  268.                filt_val = cap_val + 
  269.                      (time_dwell_plus/delta_T)* 
  270.                      (Tau_2/(Tau_1+Tau_2))* 
  271.                      (Supply_Volts - cap_val);
  272.             }
  273.          }
  274.          //---------------------------------------------
  275.          // update delayed variables
  276.          prev_state = new_state;
  277.          prev_time_zc = time_zc;
  278.          prev_osc_phase = osc_phase;
  279.          prev_cap_val = cap_val;
  280.          prev_filt_val = filt_val;
  281.          Prev_Input_Positive = (input_val >= 0);
  282.       }
  283.       delta_T = time_of_samp - prev_time_zc;
  284.       inst_freq = Omega_Sub_0 + K_Sub_0 * prev_filt_val;
  285.       output_phase = 
  286.                   prev_osc_phase + inst_freq * delta_T;
  287.       *fsOutput_ptr++ = sin(output_phase);
  288.       *fs_filtered_error_ptr++ = prev_filt_val;
  289.       *fsOscPhase_ptr++ = output_phase;
  290.       *fsOscFreq_ptr++ = inst_freq/TWO_PI;
  291.       fsInput_ptr++;
  292.    }
  293.    Prev_Input_Val = prev_input_val;
  294.    Prev_Filt_Val = prev_filt_val;
  295.    Prev_Time_Zc = prev_time_zc;
  296.    Prev_State = prev_state;
  297.    Prev_Cap_Val = prev_cap_val;
  298.    Time_Of_Samp = time_of_samp;
  299.    Prev_Osc_Phase = prev_osc_phase;
  300.    err_avg = err_sum / block_size;
  301.    BasicResults << "avg PLL error = " << err_avg 
  302.                 << endl;
  303.    Osc_Output_Prev_Val = osc_output_val;
  304.   return(_MES_AOK);
  305. }