📄 rxdetector.c
字号:
pr1_data_Q = pDetectorStat->pfCplxSymbBuff_1->pQBuffer;
pr2_data_I = pDetectorStat->pfCplxSymbBuff_2->pIBuffer;
pr2_data_Q = pDetectorStat->pfCplxSymbBuff_2->pQBuffer;
for (pp = 0; pp < data_len; pp++)
{
idx = (pDetectorStat->uiNextSymb + pp) % pDetectorStat->uiBufLen;
//Start with one S
pS[0][0] = -3;
pS[0][1] = -3;
pS[1][0] = -3;
pS[1][1] = -3;
//OBS! Rad 0 & kolumn 1 i pH_hat_r i matlab representeras av rad 1 & kolumn 0 i CCS
pZ[0][0] = pr1_data_I[idx] - (pH_hat_r[0][0]*pS[0][0] - pH_hat_i[0][0]*pS[0][1] + pH_hat_r[1][0]*pS[1][0] - pH_hat_i[1][0]*pS[1][1]);
pZ[0][1] = pr1_data_Q[idx] - (pH_hat_r[0][0]*pS[0][1] + pH_hat_i[0][0]*pS[0][0] + pH_hat_r[1][0]*pS[1][1] + pH_hat_i[1][0]*pS[1][0]);
pZ[1][0] = pr2_data_I[idx] - (pH_hat_r[0][1]*pS[0][0] - pH_hat_i[0][1]*pS[0][1] + pH_hat_r[1][1]*pS[1][0] - pH_hat_i[1][1]*pS[1][1]);
pZ[1][1] = pr2_data_Q[idx] - (pH_hat_r[0][1]*pS[0][1] + pH_hat_i[0][1]*pS[0][0] + pH_hat_r[1][1]*pS[1][1] + pH_hat_i[1][1]*pS[1][0]);
normmin = norm_ML(pZ[0][0], pZ[0][1], pZ[1][0], pZ[1][1]);
pS_out[0] = pS[0][0];
pS_out[1] = pS[0][1];
pS_out[2] = pS[1][0];
pS_out[3] = pS[1][1];
for(s1_I = -3; s1_I <= 3; s1_I += 2)
{
for(s1_Q = -3; s1_Q <= 3; s1_Q += 2)
{
for(s2_I = -3; s2_I <= 3; s2_I += 2)
{
for(s2_Q = -3; s2_Q <= 3; s2_Q += 2)
{
pS[0][0] = s1_I;
pS[0][1] = s1_Q;
pS[1][0] = s2_I;
pS[1][1] = s2_Q;
// H鋜 鋜 jag! 膎dra pH_hat_r & pH_hat_i enligt ovan
pZ[0][0] = pr1_data_I[idx] - (pH_hat_r[0][0]*pS[0][0] - pH_hat_i[0][0]*pS[0][1] + pH_hat_r[1][0]*pS[1][0] - pH_hat_i[1][0]*pS[1][1]);
pZ[0][1] = pr1_data_Q[idx] - (pH_hat_r[0][0]*pS[0][1] + pH_hat_i[0][0]*pS[0][0] + pH_hat_r[1][0]*pS[1][1] + pH_hat_i[1][0]*pS[1][0]);
pZ[1][0] = pr2_data_I[idx] - (pH_hat_r[0][1]*pS[0][0] - pH_hat_i[0][1]*pS[0][1] + pH_hat_r[1][1]*pS[1][0] - pH_hat_i[1][1]*pS[1][1]);
pZ[1][1] = pr2_data_Q[idx] - (pH_hat_r[0][1]*pS[0][1] + pH_hat_i[0][1]*pS[0][0] + pH_hat_r[1][1]*pS[1][1] + pH_hat_i[1][1]*pS[1][0]);
newnorm = norm_ML(pZ[0][0], pZ[0][1], pZ[1][0], pZ[1][1]);
if(newnorm < normmin)
{
normmin = newnorm;
pS_out[0] = pS[0][0];
pS_out[1] = pS[0][1];
pS_out[2] = pS[1][0];
pS_out[3] = pS[1][1];
}
}
}
}
}
pDetectorStat->pfCplxSymbBuff_1->pIBuffer[idx] = pS_out[0];
pDetectorStat->pfCplxSymbBuff_1->pQBuffer[idx] = pS_out[1];
pDetectorStat->pfCplxSymbBuff_2->pIBuffer[idx] = pS_out[2];
pDetectorStat->pfCplxSymbBuff_2->pQBuffer[idx] = pS_out[3];
}
//Convertion from symbols to bytes
Detect(pDetectorStat);
}
/****************************************************************************
Function : ZFDetector
****************************************************************************
Description : Estimate the transmitted symbols with Zero-Forcing
Inputs : Received symbols in antenna 1 and antenna 2
Outputs : Detected symbols in bytes
By : 2005-05-09 Created by Anders Lindgren
2005-05-13 modified by Anders Lindgren
****************************************************************************/
static void ZFDetector(typRX_DETECTORSTATE *pDetectorStat)
{
//Define the constants and the variables
float a1;
float a2;
float a3;
float a4;
float b1;
float b2;
float b3;
float b4;
float x, y, xy;
// float pG_r[2][2];
// float pG_i[2][2];
float pG_ZF_r[2][2];
float pG_ZF_i[2][2];
int data_len;
int p, idx;
float *pr1_data_I;
float *pr1_data_Q;
float *pr2_data_I;
float *pr2_data_Q;
float fTemp_1;
float fTemp_2;
float fTemp_3;
float fTemp_4;
//Calculate the values of the constants that will be used to simplify the calculations
/*a1 = powf(pH_hat_r[0][0],2) + powf(pH_hat_i[0][0],2) + powf(pH_hat_r[1][0],2) + powf(pH_hat_i[1][0],2);
b1 = 0;
a2 = pH_hat_r[0][0]*pH_hat_r[0][1] + pH_hat_i[0][0]*pH_hat_i[0][1] + pH_hat_r[1][0]*pH_hat_r[1][1] + pH_hat_i[1][0]*pH_hat_i[1][1];
b2 = pH_hat_r[0][0]*pH_hat_i[0][1] - pH_hat_i[0][0]*pH_hat_r[0][1] + pH_hat_r[1][0]*pH_hat_i[1][1] - pH_hat_i[1][0]*pH_hat_r[1][1];
a3 = a2;
b3 = -b2;
a4 = powf(pH_hat_r[0][1],2) + powf(pH_hat_i[0][1],2) + powf(pH_hat_r[1][1],2) + powf(pH_hat_i[1][1],2);
b4 = 0;*/
a1 = pH_hat_r[0][0];
b1 = pH_hat_i[0][0];
a2 = pH_hat_r[0][1];
b2 = pH_hat_i[0][1];
a3 = pH_hat_r[1][0];
b3 = pH_hat_i[1][0];
a4 = pH_hat_r[1][1];
b4 = pH_hat_i[1][1];
x = a1*a4 - b1*b4 - a2*a3 + b2*b3;
y = a1*b4 + a4*b1 - a3*b2 - a2*b3;
xy = x*x + y*y;
//xy = _rcpsp(xy);
//Calculating the inverse of H_hat'*H_hat, where e.g. pG_r=Re{inv(H_hat_2)}
pG_ZF_r[0][0] = (a4*x + b4*y)/xy;
pG_ZF_i[0][0] = (b4*x - a4*y)/xy;
pG_ZF_r[0][1] = (-a2*x - b2*y)/xy;
pG_ZF_i[0][1] = (a2*y - b2*x)/xy;
pG_ZF_r[1][0] = (-a3*x - b3*y)/xy;
pG_ZF_i[1][0] = (a3*y - b3*x)/xy;
pG_ZF_r[1][1] = (a1*x + b1*y)/xy;
pG_ZF_i[1][1] = (b1*x - a1*y)/xy;
/*
//Calculating G_ZF from the matlab code
pG_ZF_r[0][0] = pG_r[0][0]*pH_hat_r[0][0] + pG_i[0][0]*pH_hat_i[0][0] + pG_r[0][1]*pH_hat_r[0][1] + pG_i[0][1]*pH_hat_i[0][1];
pG_ZF_i[0][0] = -pG_r[0][0]*pH_hat_i[0][0] + pG_i[0][0]*pH_hat_r[0][0] - pG_r[0][1]*pH_hat_i[0][1] + pG_i[0][1]*pH_hat_r[0][1];
pG_ZF_r[0][1] = pG_r[0][0]*pH_hat_r[1][0] + pG_i[0][0]*pH_hat_i[1][0] + pG_r[0][1]*pH_hat_r[1][1] + pG_i[0][1]*pH_hat_i[1][1];
pG_ZF_i[0][1] = -pG_r[0][0]*pH_hat_i[1][0] + pG_i[0][0]*pH_hat_r[1][0] - pG_r[0][1]*pH_hat_i[1][1] + pG_i[0][1]*pH_hat_r[1][1];
pG_ZF_r[1][0] = pG_r[1][0]*pH_hat_r[0][0] + pG_i[1][0]*pH_hat_i[0][0] + pG_r[1][1]*pH_hat_r[0][1] + pG_i[1][1]*pH_hat_i[0][1];
pG_ZF_i[1][0] = -pG_r[1][0]*pH_hat_i[0][0] + pG_i[1][0]*pH_hat_r[0][0] - pG_r[1][1]*pH_hat_i[0][1] + pG_i[1][1]*pH_hat_r[0][1];
pG_ZF_r[1][1] = pG_r[1][0]*pH_hat_r[1][0] + pG_i[1][0]*pH_hat_i[1][0] + pG_r[1][1]*pH_hat_r[1][1] + pG_i[1][1]*pH_hat_i[1][1];
pG_ZF_i[1][1] = -pG_r[1][0]*pH_hat_i[1][0] + pG_i[1][0]*pH_hat_r[1][0] - pG_r[1][1]*pH_hat_i[1][1] + pG_i[1][1]*pH_hat_r[1][1];
*/
//Calculating of the estimated symbols
data_len = pDetectorStat->uiNoOfSymb;
pr1_data_I = pDetectorStat->pfCplxSymbBuff_1->pIBuffer;
pr1_data_Q = pDetectorStat->pfCplxSymbBuff_1->pQBuffer;
pr2_data_I = pDetectorStat->pfCplxSymbBuff_2->pIBuffer;
pr2_data_Q = pDetectorStat->pfCplxSymbBuff_2->pQBuffer;
for (p = 0; p < data_len; p++)
{
idx = (pDetectorStat->uiNextSymb + p) % pDetectorStat->uiBufLen;
/*
fTemp_1 = pG_ZF_r[0][0]*pr1_data_I[p] - pG_ZF_i[0][0]*pr1_data_Q[p] + pG_ZF_r[0][1]*pr2_data_I[p] - pG_ZF_i[0][1]*pr2_data_Q[p];
pDetectorStat->pfCplxSymbBuff_1->pIBuffer[p] = fTemp_1;
fTemp_2 = pG_ZF_r[0][0]*pr1_data_Q[p] + pG_ZF_i[0][0]*pr1_data_I[p] + pG_ZF_r[0][1]*pr2_data_Q[p] + pG_ZF_i[0][1]*pr2_data_I[p];
pDetectorStat->pfCplxSymbBuff_1->pQBuffer[p] = fTemp_2;
fTemp_3 = pG_ZF_r[1][0]*pr1_data_I[p] - pG_ZF_i[1][0]*pr1_data_Q[p] + pG_ZF_r[1][1]*pr2_data_I[p] - pG_ZF_i[1][1]*pr2_data_Q[p];
pDetectorStat->pfCplxSymbBuff_2->pIBuffer[p] = fTemp_3;
fTemp_4 = pG_ZF_r[1][0]*pr1_data_Q[p] + pG_ZF_i[1][0]*pr1_data_I[p] + pG_ZF_r[1][1]*pr2_data_Q[p] + pG_ZF_i[1][1]*pr2_data_I[p];
pDetectorStat->pfCplxSymbBuff_2->pQBuffer[p] = fTemp_4;
*/
fTemp_1 = pG_ZF_r[0][0]*pr1_data_I[idx] - pG_ZF_i[0][0]*pr1_data_Q[idx] + pG_ZF_r[0][1]*pr2_data_I[idx] - pG_ZF_i[0][1]*pr2_data_Q[idx];
fTemp_3 = pG_ZF_r[1][0]*pr1_data_I[idx] - pG_ZF_i[1][0]*pr1_data_Q[idx] + pG_ZF_r[1][1]*pr2_data_I[idx] - pG_ZF_i[1][1]*pr2_data_Q[idx];
fTemp_2 = pG_ZF_r[0][0]*pr1_data_Q[idx] + pG_ZF_i[0][0]*pr1_data_I[idx] + pG_ZF_r[0][1]*pr2_data_Q[idx] + pG_ZF_i[0][1]*pr2_data_I[idx];
fTemp_4 = pG_ZF_r[1][0]*pr1_data_Q[idx] + pG_ZF_i[1][0]*pr1_data_I[idx] + pG_ZF_r[1][1]*pr2_data_Q[idx] + pG_ZF_i[1][1]*pr2_data_I[idx];
pDetectorStat->pfCplxSymbBuff_1->pIBuffer[idx] = fTemp_1;
pDetectorStat->pfCplxSymbBuff_1->pQBuffer[idx] = fTemp_2;
pDetectorStat->pfCplxSymbBuff_2->pIBuffer[idx] = fTemp_3;
pDetectorStat->pfCplxSymbBuff_2->pQBuffer[idx] = fTemp_4;
}
//Convertion from symbols to bits
Detect(pDetectorStat);
}
/*=== End of local functions definition ====================================*/
/*--- Global functions definition ------------------------------------------*/
/****************************************************************************
Function : detection
****************************************************************************
Description : Detection of the transmitted symbols with either ML or ZF
Inputs : Received symbols in antenna 1 and antenna 2
Outputs : -
By : 2005-05-07 Created by Anders Lindgren
2005-05-11 modified by Anders Lindgren
****************************************************************************/
void detection(typRX_DETECTORSTATE *pDetectorStat)
{
//int detect_type;
//detect_type = ZF; //The Detection method we will use is set here
if (pDetectorStat->detect_type == eRX_ML)
{
MLDetector(pDetectorStat);
}
else if (pDetectorStat->detect_type == eRX_ZF)
{
ZFDetector(pDetectorStat);
}
}
/*=== End of global functions definition ===================================*/
/*--- AUTOMATICALLY GENERATED VERSION HISTORY --------------------------------
$Log: /MIMO/Receiver/rxdetector.c $
*
* 13 05-05-29 17:43 Adrian
* no changes that matter (in ZF tried to precompute 1/xy but now
* commented)
*
* 12 05-05-28 17:15 Maxime
* Debugged the if nibble = 0 or 1 using switch cases
*
* 11 05-05-28 13:46 Adrian
* Replaced the powf(.,2) library call with multiplication. Replaced the
* computation of (x*x+y*y) in ZFDetector with a variable which is
* precomputed.
*
* 10 05-05-28 12:40 Adrian
* added and modifyed some lines to use the circular symbol buffer and
* change in static void Detect(): should be pDetectStat->
* instead of DetectStat. (line 194)
*
* 9 05-05-27 20:40 Adrian
* removed some unused constants
*
* 8 05-05-25 10:57 Adrian
* removed initialization of pDetectorStat->nibble = 0; and
* pDetectorStat->uiNextWriteByte = 0;
*
* 7 05-05-24 19:04 Adrian
* Commented the array declarations pG_r and pG_i in order to avoid the
* warning because they are not used.
*
* 6 05-05-24 17:25 Anders
* Finished and tested with matlab
*
* 5 05-05-20 19:37 Anders
* Finished but not tested
*
* 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 + -