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