www.pudn.com > wimax_ofdm_implementation_code.rar > detect_pre.c


/*****************************************************************************/
/*   FIle Name : detect_pre.c                                                */
/*   Description : WiMax detection of preamble                               */
/*   author : miffie                                                         */
/*   Date   : Nov/10/05                                                      */
/*   Copyright (c) 2005 miffie   All rights reserved.                        */
/*****************************************************************************/
///////////////////////////////////////////////////////////////////////////////
//clock lock function: Nov/15/05 Miffie
// I guess if SS's clock is not locked before the transaction,(assume 10ppm difference)
// it's almost impossible to make  SS's clock  locked to BS's using short/long preambles.// I assumed 10GHz carrier freq and 8 Mhz sampling freq and 10ppm torelance,
// clock offset amount before synchronization : 10GHz*10ppm=100KHz
// clock offset amount durng shortpreamble(64 cycles) : 360*64*(100kHz/8MHz)= 288degree
// Under this situation, preamble cannot be detected.
// So, SS's clock must be locked in another way(for example, use WiMax-SC preamble)

int detect_pre( struct complexset datain ) { // 
double  radius ;
double  maxr, minr ;
double  phase ;
double  bottom_radius ;
double  accum_radius ;
struct	complex tmp1 , tmp2 ;
struct	complexset cset ;
short   detect_cnt ;
int     RADIUS_THRESHOLD = 0.25 ;
int	ii , jj ;
int     detection ;
double  phase_sc, drift_amount ;

static char Pall[]={ 1,-1,  1,-1, -1,-1,  1, 1,  1,-1,  1,-1, -1, 1,  1,-1,  1,-1,  1,-1,
                     1, 1, -1,-1,  1, 1,  1, 1, -1,-1,  1, 1, -1,-1, -1,-1,  1,-1, -1, 1,
                     1,-1,  1,-1, -1,-1,  1, 1,  1,-1,  1,-1, -1, 1,  1,-1,  1,-1,  1,-1,
                     1, 1, -1,-1,  1, 1,  1, 1, -1,-1,  1, 1, -1,-1, -1,-1,  1,-1, -1, 1,
                     1,-1,  1,-1, -1,-1,  1, 1,  1,-1,  1,-1, -1, 1,  1,-1,  1,-1,  1,-1,
                     1, 1, -1,-1,  1, 1,  1, 1, -1,-1,  1, 1, -1,-1, -1,-1,  1,-1, -1, 1,
                     1, 1,  1, 1,  1,-1, -1, 1,  1, 1,  1, 1, -1,-1,  1, 1,  1, 1,  1, 1,
                    -1, 1,  1,-1, -1, 1, -1, 1,  1,-1, -1, 1,  1,-1,  1,-1,  1, 1, -1,-1,
                    -1,-1, -1,-1, -1, 1,  1,-1, -1,-1, -1,-1,  1, 1, -1,-1, -1,-1, -1,-1,
                     1,-1, -1, 1,  1,-1,  1,-1, -1, 1,  1,-1, -1, 1, -1, 1, -1,-1,  1, 1,
                     0,0,
                    -1,-1,  1, 1, -1, 1, -1, 1, -1,-1,  1, 1,  1, 1,  1, 1, -1,-1,  1, 1,
                     1,-1,  1,-1,  1,-1, -1, 1, -1, 1,  1, 1, -1, 1,  1,-1, -1,-1, -1,-1,
                    -1, 1,  1,-1,  1, 1,  1, 1, -1, 1,  1,-1,  1,-1,  1,-1, -1, 1,  1,-1,
                    -1,-1, -1,-1, -1,-1,  1, 1,  1, 1,  1, 1,  1, 1, -1,-1, -1, 1, -1, 1,
                     1, 1, -1,-1,  1,-1,  1,-1,  1, 1, -1,-1, -1,-1, -1,-1,  1, 1, -1,-1,
                    -1, 1, -1, 1, -1, 1,  1,-1,  1,-1,  1,-1,  1,-1, -1, 1,  1, 1,  1, 1,
                    -1,-1,  1, 1, -1, 1, -1, 1, -1,-1,  1, 1,  1, 1,  1, 1, -1,-1,  1, 1,
                     1,-1,  1,-1,  1,-1, -1, 1, -1, 1, -1, 1, -1, 1,  1,-1, -1,-1, -1,-1,
                     1,-1, -1, 1, -1,-1, -1,-1,  1,-1, -1, 1, -1, 1, -1, 1,  1,-1, -1, 1,
                     1, 1,  1, 1,  1, 1, -1,-1, -1,-1, -1,-1, -1,-1,  1, 1,  1,-1,  1,-1 };

 //Main 
  PRINTF("detect_pre size=%d \n", datain.size ) ;
  //detect short sequence
  ii=0 ;
  detection = datain.size +1 ;
  detect_cnt=0 ;
  while(ii< (datain.size-64) ) { //loop
    accum_radius=0 ;
    accum_radius=0 ;
    bottom_radius=2 ;
    cset = extract_complexset(datain , ii , 64 ) ; //Short sequence
    cset = dft64( cset ) ;
    print_complexset( cset ) ;
    phase = 0 ;
    for(jj=-25;jj<=25;jj++ ) { //each subcarrier
      tmp1.realp = Pall[jj*8+200+0] ;
      tmp1.image = Pall[jj*8+200+1] ;
      tmp1 = multiply_complex( cset.data[jj+32] , tmp1 ) ;
      tmp1 = cordic( tmp1 ) ;
      //radius
      accum_radius += tmp1.realp ;
      if (jj!=0) {
        bottom_radius  = ( bottom_radius>tmp1.realp) ? tmp1.realp : bottom_radius ;
      }
      //phase
      //normalize
      tmp1.image = (tmp1.image>pi) ? tmp1.image-2*pi :
                   (tmp1.image<-pi) ? tmp1.image+2*pi :  tmp1.image ;
      //printf("phase(%d) =%6.3f\n", jj, tmp1.image ) ;
      if(((jj>=-24)&(jj<=-1))|(jj>1)) {
        tmp2.image = phase_sc - tmp1.image  ;
        //normalize
        tmp2.image = (tmp2.image>pi) ? tmp2.image-2*pi :
                   (tmp2.image<-pi) ? tmp2.image+2*pi :  tmp2.image ;
        phase += tmp2.image ;
        printf("diff(%d) =%6.3f\n", jj, tmp2.image ) ;
      }
      phase_sc = tmp1.image ;
    } //each subcarrier
    phase = phase/48 ; //take mean
    phase = (phase*64.0)/(2.0*pi)  ; 
    accum_radius = accum_radius/50 ;
     
    PRINTF("detect_pre(%d) accum_radius=%6.3f bottom_radius=%6.3f phase=%6.3f detect_cnt=%d\n", ii, 
                           accum_radius, bottom_radius, phase, detect_cnt ) ;

    //detect_cnt as count # of octets(8 samples) in short seq
    if (((bottom_radius) > (accum_radius/4.0)) & //if bottom_radius is big enough
        (accum_radius>RADIUS_THRESHOLD)) {  //if accum_radius is big enough
        detect_cnt++ ;
    } //detected
    else { //not detected
        if(detect_cnt>1)  { //start of longseq
          detection = ii ;
          ii=datain.size ; //exit loop
        } //start of longseq
        detect_cnt=0 ;
    } //not detected
    
    ///And some number of consecutive samples  are qualified with phase test 
    //for AutoGainControl ???

    if (detect_cnt>0) {//short seq detected
      ii += 64+ floor(phase+0.5)  ;
    }//short seq detected
    else { //
     ii += 64 ; 
    } //
  } //loop
  PRINTF("detection =%d\n" , detection ) ;
  return( detection ) ;
} //detect_pre