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