📄 rxpll.c
字号:
/*****************************************************************************
Module : Phase Locked Loop
******************************************************************************
Function :
Procedures : none
Author : $Author: Jinfeng $
Revision : $Revision: 6 $
Modified : $Modtime: 05-05-24 14:10 $
File : $Workfile: rxpll.c $
******************************************************************************
KTH, Royal Institute of Technology, S3, Stockholm
*****************************************************************************/
/*--- Include files --------------------------------------------------------*/
/* import */
#include <csl_stdinc.h>
#include "../common/commondef.h"
/* export */
#include "rxpll.h"
/*=== End of include files =================================================*/
/*--- Global variables definition ------------------------------------------*/
typRX_PLLPARAM PLLparam;
/*=== End of global variables definition ===================================*/
/*--- Global constants definition ------------------------------------------*/
/*=== End of global constants definition ===================================*/
/*--- Local defines --------------------------------------------------------*/
#define LPFFILTERLEN 16
/*=== End of local defines =================================================*/
/*--- Local types declaration ----------------------------------------------*/
/*=== End of local types declaration =======================================*/
/*--- Local variables definition -------------------------------------------*/
extern float cos_table[COS_TAB_SIZE];
/*=== End of local variables definition ====================================*/
/*--- Local constants definition -------------------------------------------*/
const float lpf_coeff[LPFFILTERLEN] =
{-0.001920, -0.000316, 0.006319, 0.024859,
0.058182, 0.101516, 0.142955, 0.168405,
0.168405, 0.142955, 0.101516, 0.058182,
0.024859, 0.006319, -0.000316, -0.001920};
const float K0 = (2*PI*INTERFREQ/SAMPFREQ);
const Int16 AVG_LEN = 64; // the length of the domain carrying out average
/*=== End of local constants definition ====================================*/
/*--- Local functions definition -------------------------------------------*/
/*=== End of local functions definition ====================================*/
/*--- Global functions definition ------------------------------------------*/
/****************************************************************************
Function : lock_phase
****************************************************************************
Description : find the frequency offset
Inputs : sinusoid signal and parameters of estimation
Outputs : Frequency offset
By : 2005-05-05 Jinfeng Du
****************************************************************************/
void lock_phase(typRX_PLLPARAM *pPLLparam, float *pSampBuff, const unsigned int uiBuffLen)
{
unsigned int i, k;
Int16 pos_i;
Int16 pos = 0;
Int16 lookup_index,index_sin;
float a, interval;
float phase_diff, out_seq;
float I_filtered, Q_filtered;
// float delta_x;
float cos_n, sin_n;
float loop_filter_output;
float Ileft[LPFFILTERLEN]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float Qleft[LPFFILTERLEN]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float factor_1 = COS_TAB_SIZE*_rcpsp(2*PI);
// float factor_2 = 2*PI*_rcpsp((float)COS_TAB_SIZE);
loop_filter_output = pPLLparam->theta;
for(i = 0; i < uiBuffLen; i++)
{
a = pSampBuff[i];
interval = pPLLparam->theta*factor_1;
lookup_index = (Int16)interval;
index_sin = (lookup_index + 3*COS_TAB_SIZE/4) & (COS_TAB_SIZE - 1);
// index_sin = (index_sin>COS_TAB_SIZE) ? (index_sin-COS_TAB_SIZE):index_sin;
// delta_x = pPLLparam->theta - lookup_index*factor_2;
// cos_n = (1-0.5*delta_x*delta_x)*cos_table[lookup_index] - delta_x*cos_table[index_sin];
// sin_n = (1-0.5*delta_x*delta_x)*cos_table[index_sin] + delta_x*cos_table[lookup_index];
cos_n = cos_table[lookup_index];
sin_n = cos_table[index_sin];
Ileft[pos] = a*cos_n;
Qleft[pos] = a*sin_n;
I_filtered = 0;
Q_filtered = 0;
#pragma MUST_ITERATE (LPFFILTERLEN, LPFFILTERLEN)
for (k = 0; k<LPFFILTERLEN; k++)
{
pos_i = (pos - k +LPFFILTERLEN) & (LPFFILTERLEN - 1); // index in normal array
// to find the index in the cyclic array
// pos_i = (pos_i<0) ? (pos_i+LPFFILTERLEN):pos_i; //constrain index within LPFFILTERLEN
I_filtered += lpf_coeff[k]*Ileft[pos_i]; //-> working version
Q_filtered += lpf_coeff[k]*Qleft[pos_i]; //->
}
pos++;
pos = pos & (LPFFILTERLEN - 1);//save in cyclic array
if (I_filtered != 0)
phase_diff = -Q_filtered*_rcpsp(I_filtered);
// Loop filter
out_seq = loop_filter_output*pPLLparam->alpha + phase_diff*pPLLparam->beta ;
loop_filter_output = out_seq * pPLLparam->loop_gain;
if (i>= uiBuffLen-AVG_LEN && i< uiBuffLen) pPLLparam->delta_avg += loop_filter_output;
pPLLparam->theta += K0 + loop_filter_output;
while(pPLLparam->theta >= 2*PI)
{
pPLLparam->theta -= 2*PI;
}
while(pPLLparam->theta < 0)
{
pPLLparam->theta += 2*PI;
}
}
pPLLparam->delta = (pPLLparam->delta_avg)/AVG_LEN;
}
/*=== End of global functions definition ===================================*/
/*--- AUTOMATICALLY GENERATED VERSION HISTORY --------------------------------
$Log: /MIMO/Receiver/rxpll.c $
*
* 6 05-05-24 14:24 Jinfeng
* shorten filter length to 16. use #pragma MUST_ITERATE(16,16)
*
* 5 05-05-23 10:41 Jinfeng
* remove modification of cos lookup table, need to be optimized.
*
* 4 05-05-19 12:20 Jinfeng
* introduce cyclic array to release most of the memory used to be
* occupied.
*
* 3 05-05-18 23:45 Jinfeng
* correct for more than 70 steps debug, but cup error when run it
* through.
*
* 2 05-05-18 15:18 Jinfeng
* need to be verified with MATLAB
*
* 1 05-05-11 17:00 Adrian
* created and added to VSS
===== END OF AUTOMATICALLY GENERATED VERSION HISTORY =======================*/
/**** End of file ***********************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -