/*=================================================================
UMTS Cell Search:
Version 1.1:
Cell Search by correlating CPICH assosciated with all 512 scrambling codes (Alpha code)
- In fast-mode (Beta code) specified top few candidates (sample positions) are correlated
Algorithm:
1. Find the max corr for each scr. code. -> 512 max values
2. Sort these 512 max values, pick the top 200 scr codes (because the
maximums of the rest scr codes will be anyway discaraded later)
3. For each of these 200 scr-codes, sort their corr values for all
positions disregarding the values withing +/-2 chips of a local max, and
pick the top 10 or so positions -> In total, this will give us 200x10 =
20000 initial candidates
4. Sort the 2000 candidates to find the final 200 candidates.
Version 1.2:
- Resampling added
Version 1.3:
- Removed resampling from code
- Alpha and Beta codes are separated in two functions with parameters. The Beta code assumes that slot#0 is
always present in the snap shot, i.e., correlation begins at only slot#0 or frame boundary
Version 1.4:
- Beta: Correlation can start at any slot# {0,1,..,14} in the snap shot regardless of the frame boundary
- Beta: Tracking or corrrelation spread is considered by correlating at multiple positions around Alpha's slot boundary.
- Beta: New slot/frame boundary is updated considering correlation spread <=> Tracking
- Beta: Updated are 1) Frame boundary (in microframe) considering correlation spread <=> Tracking
2) scrCodeTbl[i].cpichCorrRmsVolt is calculated
Version 1.5:
- Integers changed to __int64 are: idxFrameStarts, d_samp, cellSearchCandidate::timeFrameStarts,
- scrCodeTbl[i].timeFrameStarts is changed to absolute time in micro frames as
[timeSnapShotStarts + (frBndry+corrMaxIdx-cs) * (1.0e8/sampRate)]
- Scrambling code index (0,..,511) is changed to 3GPP scr code num (0, 16, ... ,8176) in Alpha(), and vice versa in Beta()
- The r.m.s. of received signal, scrCodeTbl[i].sigRMS, is calculated and updated in candidate table
Version 1.6
- CUDA FFT-based cross correlation code added (1:1 subst)
- Addressed some IPPS errors (linear/circular correlation issue)
- Using pinned memory (non pageable) allocated by cudaMallocHost in FFTBenchmark
- TODO: optimize cudaCrossCorr
*/
// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "lib_UMTS_cell_search_v1_5.h"
#include "ScramblingTable.h"
#include "correlation_CUDA.h"
#define SCR_TBL_NUM_CODES 512
#define SCR_TBL_NUM_CHIPS 5120
void PauseForUser()
{
printf("press <Enter> to end");
scanf("%*c");
}
void terminate(const char *pMsg)
{
printf("Error: %s\n", pMsg);
fcloseall();
PauseForUser();
exit(-1);
}
int main(int argc, char **argv)
{
int i, j;
FILE * pFile;
/*
printf("*** CUDA benchmark ***\n");
for (i=0; i < 10; i++)
cudaFFTBenchmark(1024*(16 << i));
printf("*** IPPs benchmark ***\n");
for (i=0; i < 10; i++)
ippsFFTBenchmark(1024*(16 << i));
*/
/*
printf("press <Enter> to end");
scanf("%*c");
return 0;
*/
UMTSScramblingCodeTable ScrTbl(SCR_TBL_NUM_CODES, SCR_TBL_NUM_CHIPS,
(double)OSR, "cpich_Beta_osr325_128.dat");
if ( !ScrTbl.TableValid() )
{
terminate("Table not opened or too short");
}
Ipp32fc *TblStart = ScrTbl.ReadTable();
cellSearchCandidate *scrCodeInfoTbl = new cellSearchCandidate [N_CAND_POS_CPICH_CORR];
Ipp32fc *BBsig = ippsMalloc_32fc(N_BASEBAND_SAMP); // Complex-baseband-oversampled signal
Ipp32fc *CPICHsig = ippsMalloc_32fc(512*N_SAMP_CPICH_CORR); // All 512 Primary-Scrambling codes
//----- Get CPICH signal for all Primary Scrambling Codes that are in the table -----
int tblIndex;
int scIndex = 0;
for(i=0; i<SCR_TBL_NUM_CODES; i++) {
tblIndex = int( (i*SCR_TBL_NUM_CHIPS)*OSR );
for (j=0; j<N_SAMP_CPICH_CORR; j++)
{
CPICHsig[scIndex].re = TblStart[tblIndex].re;
CPICHsig[scIndex++].im = TblStart[tblIndex++].im;
}
}
//------- Get rx samples: HW Sampling rate=9.75 MHz/s -------
pFile = fopen("rx_sig_sampRate9.75MHz.dat","r+");
if ( pFile == NULL )
{
terminate("file rx_sig_sampRate9.75MHz.dat not opened.");
}
rewind(pFile);
for(i=0; i<N_BASEBAND_SAMP; i++){
fscanf(pFile, "%f %f", &BBsig[i].re, &BBsig[i].im);
// printf("rx[%d] = %f + %f j \n", i, BBsig[i].re, BBsig[i].im);
}
fclose (pFile);
printf("\n --- Nohcoherent correaltion: %d x %d chips = %d chips ---\n\n", N_PARTS_CPICH_CORR, (int)(N_SAMP_PER_PART_CPICH_CORR/OSR), (int)(N_SAMP_CPICH_CORR/OSR));
//======= Alpha: Search all 512 P-scr codes =======
Alpha_cell_search(BBsig, N_BASEBAND_SAMP, 0, SAMPLING_RATE, CPICHsig, N_SAMP_PER_PART_CPICH_CORR, N_PARTS_CPICH_CORR,
scrCodeInfoTbl, N_CAND_POS_CPICH_CORR); // Set Alpha time_SnapShotStarts instead of 0
//======= Beta: Estimate Ec/Io for scr-code and positions provided by Alpha =======
//ippsZero_32fc(CPICHsig,512*N_SAMP_CPICH_CORR);
////------- Get CPICH signal of full frame for N_POS_CPICH_CORR_LONG-Primary Scrambling Codes (Beta only) -------
//scIndex = (int) (FRAME_PERIOD_SEC * SAMPLING_RATE);
//for ( i=0; i < N_POS_CPICH_CORR_LONG; i++ )
//{
// // SrcCodeGroup = codeNum / 16 ??
// tblIndex = (scrCodeInfoTbl[i].scrCodeNum * scIndex) >> 4;
// ippsCopy_32fc(&TblStart[tblIndex], &CPICHsig[scIndex*i], scIndex);
//}
//Beta(BBsig, N_BASEBAND_SAMP, 0, SAMPLING_RATE, CPICHsig, N_SAMP_PER_PART_CPICH_CORR_LONG, N_PARTS_CPICH_CORR_LONG,
// scrCodeInfoTbl, N_POS_CPICH_CORR_LONG); // if time_SnapShotStarts==0, Alpha and Beta works on the same shap shot.
// // Set Beta time_SnapShotStarts instead of 0
delete [] scrCodeInfoTbl;
ippsFree(BBsig);
ippsFree(CPICHsig);
fcloseall();
printf("press <Enter> to end");
scanf("%*c");
return 0;
}