www.pudn.com > wimax_ofdm_implementation_code.rar > equalizer.c
/*****************************************************************************/
/* FIle Name : Equalizer.c */
/* Description : WiMax OFDM Subcarrier modulation DATA Equalizer */
/* author : miffie */
/* Date : Nov/04/05 */
/* Copyright (c) 2005 miffie All rights reserved. */
/*****************************************************************************/
struct complexset equalizer (struct complexset datain, char index,
struct complexset *sram , short *pilot_shifter,
double *drift_phase, char *drift_cnt, char *sram_cnt ) {
int ii , jj ;
char shifter ;
double realp, image ;
char pilot_polarity ;
struct complexset cset ;
struct complex *top ;
struct complex tmp1, tmp2 ;
double radius[8] ;
double angle , roffset, slope ;
double drift , difference;
double MAX_PILOTLENGTH = 1.125 ;
double MIN_PILOTLENGTH = 0.75 ;
double DRIFT_THRESHOLD = 0.10 ;
double SRAM_THRESHOLD = 0.0015 ;
char num_pilot = 8 ;
char sc_pilot[] = { -88, -63, -38, -13, 13, 38, 63, 88 } ;
char sc ;
char mask[256] ;
//Main
if ((top = (struct complex *)malloc(256*sizeof(struct complex)) ) == NULL) {
PRINTF( " malloc failed in equalizer.c\n") ;
} //fail
else { //allocated
//mask
mask_sc(&mask[0], index ) ;
//OFDM randomizer
pilot_polarity = *pilot_shifter & 0x1 ;
*pilot_shifter = pilot_randomizer( *pilot_shifter ) ;
PRINTF("equalizer size=%d pilot_polarity=%d\n", datain.size, pilot_polarity ) ;
jj=0;
for(ii=-100;ii<=100;ii++) { //each subcarrier
if ((mask[ii+128])&!(pilot_bool(ii))) { //enabled
top[ jj++ ] = multiply_complex(datain.data[ii+128],
sram->data[ii+100] ) ;
} //enabled
} //each subcarrier
cset.size = jj ;
cset.data = top ;
////////////////////
//PILOT TRAINING
////////////////////
angle=0;
drift=0;
for(ii=0;iidata[sc+100] ) ;
//printf("pilot(%d) ( %6.3f %6.3f )\n", sc, tmp2.realp, tmp2.image ) ;
//pilot sub
if ((sc==-63)|(sc==-13)|(sc==13)|(sc==38)) { //DL
//if ((sc==-63)|(sc==-13)) { //UL
tmp1.realp = (pilot_polarity) ? 1 : -1 ;
tmp1.image = 0 ;
} else { //
tmp1.realp = (pilot_polarity) ? -1 : 1 ;
tmp1.image = 0 ;
} //
tmp1 = multiply_complex(tmp1, tmp2 ) ;
printf("pilot(%d) ( %6.3f %6.3f )\n", sc, tmp1.realp, tmp1.image ) ;
radius[ii] = tmp1.realp ;
angle += polarizer ( tmp1 )/((double)sc) ;
drift += polarizer ( tmp1 ) ;
} //each pilot subcarrier
//Take means of 4 pilot sub carriers
angle = angle/num_pilot ;
drift = drift/num_pilot ;
PRINTF("angle =%6.3f\n" , angle ) ;
PRINTF("drift =%8.5f\n" , drift ) ;
//calculate radius & slope
//radius21 = 2/radius21 ;
//radius7 = 2/radius7 ;
//assume radius will be linear against freq
//slope = (radius21-radius7)/14 ;
//radius = radius7-slope*7 ; //radius(0)
//correct drift_phase
if ((fabs(drift)>DRIFT_THRESHOLD) & (*drift_cnt>=3)) {//correction
*drift_phase -= drift ;
PRINTF(" drift=%8.5f drift_phase=%8.5f\n", drift, *drift_phase ) ;
} //correction
else if (fabs(drift)>DRIFT_THRESHOLD) {
*drift_cnt = *drift_cnt +1 ;
}
//sram
//Nov/15/05 M.Inoue
//sram's change might not hapen in Wi-Max OFDM because, the clock
// is already locked and it's tolerance is less than 0.1ppm.
// Under the situation, the sample timing should not be drifted.
roffset =1.0 ;
slope =0 ;
if ((fabs(angle) > SRAM_THRESHOLD ) & (*sram_cnt>=3)) { //SRAM
PRINTF("...changing SRAM\n" ) ;
for(ii=-100;ii<=100;ii++) { //each subcarrier
tmp1.realp = cos(angle*1.5*ii) * (roffset+slope*abs(ii)) ;
tmp1.image = -sin(angle*1.5*ii) * (roffset+slope*abs(ii)) ;
PRINTF("sram(%d) %6.3f+j*%6.3f =>" , ii,
sram->data[ii+100].realp, sram->data[ii+100].image ) ;
sram->data[ii+100] = multiply_complex(sram->data[ii+100], tmp1 ) ;
PRINTF(" %6.3f+j*%6.3f \n" , sram->data[ii+100].realp, sram->data[ii+100].image ) ;
} //each subcarrier
*sram_cnt=0 ;
} //SRAM
else if (fabs(angle) > SRAM_THRESHOLD ) {
*sram_cnt= *sram_cnt + 1 ;
}
else *sram_cnt= 0 ;
}//allocated
free ( datain.data ) ;
return ( cset ) ;
} //equalizer