Cell search program working

master
ismagom 11 years ago
parent aaadc40ff4
commit afa8cd8424

@ -176,7 +176,7 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (sync_init(&synch)) { if (sync_init(&synch, 960)) {
fprintf(stderr, "Error initiating PSS/SSS\n"); fprintf(stderr, "Error initiating PSS/SSS\n");
exit(-1); exit(-1);
} }

@ -85,6 +85,7 @@ int main(int argc, char **argv) {
cf_t *input = NULL; cf_t *input = NULL;
cf_t *outfft = NULL; cf_t *outfft = NULL;
cf_t *ce = NULL; cf_t *ce = NULL;
int i;
if (argc < 3) { if (argc < 3) {
usage(argv[0]); usage(argv[0]);
@ -135,6 +136,7 @@ int main(int argc, char **argv) {
bzero(input, sizeof(cf_t) * in_slot_length()); bzero(input, sizeof(cf_t) * in_slot_length());
bzero(outfft, sizeof(cf_t) * slot_length()); bzero(outfft, sizeof(cf_t) * slot_length());
fprintf(f, "ce=zeros(%d, %d);\n", nof_slots * CP_NSYMB(cp), nof_prb * RE_X_RB);
/* read all file or nof_slots */ /* read all file or nof_slots */
slot_cnt = 0; slot_cnt = 0;
while (in_slot_length() == filesource_read(&fsrc, input, in_slot_length()) while (in_slot_length() == filesource_read(&fsrc, input, in_slot_length())
@ -144,11 +146,12 @@ int main(int argc, char **argv) {
chest_ce_slot_port(&eq, outfft, ce, slot_cnt%20, 0); chest_ce_slot_port(&eq, outfft, ce, slot_cnt%20, 0);
chest_fprint(&eq, f, slot_cnt%20, 0); //chest_fprint(&eq, f, slot_cnt%20, 0);
fprintf(f, "ce=["); for (i=0;i<CP_NSYMB(cp);i++) {
vec_fprint_c(f, ce, nof_prb * RE_X_RB * CP_NSYMB(cp)); fprintf(f, "ce(%d,:)=", slot_cnt * CP_NSYMB(cp) + i + 1);
fprintf(f, "];\n"); vec_fprint_c(f, &ce[i * nof_prb * RE_X_RB], nof_prb * RE_X_RB);
}
slot_cnt++; slot_cnt++;
} }
@ -170,6 +173,6 @@ do_exit:
} }
filesource_close(&fsrc); filesource_close(&fsrc);
printf("Done\n"); printf("Done processed %d slots\n", slot_cnt);
exit(0); exit(0);
} }

@ -12,20 +12,29 @@
#include "uhd.h" #include "uhd.h"
#include "uhd_utils.h" #include "uhd_utils.h"
int nof_slots=1000; #define MHZ 1000000
#define SAMP_FREQ 1920000
#define RSSI_FS 1000000
#define FLEN 9600
#define FLEN_PERIOD 0.005
#define IS_SIGNAL(i) (10*log10f(rssi[i]) + 30 > rssi_threshold)
int band, earfcn=-1; int band, earfcn=-1;
float pss_threshold=15.0; float find_threshold = 40.0, track_threshold = 25.0;
int earfcn_start, earfcn_end = -1; int earfcn_start=-1, earfcn_end = -1;
float rssi_threshold = -42.0; float rssi_threshold = -30.0;
int max_track_lost=9;
int nof_frames_find=8, nof_frames_track=100, nof_samples_rssi=50000;
cf_t *input_buffer; cf_t *input_buffer;
float *cfo_v; float *cfo_v;
int *idx_v; int *idx_v, *idx_valid, *t;
float *p2a_v; float *p2a_v;
void *uhd; void *uhd;
int nof_bands; int nof_bands;
int force_N_id_2; float gain = 20.0;
float gain = 30.0;
#define MAX_EARFCN 1000 #define MAX_EARFCN 1000
lte_earfcn_t channels[MAX_EARFCN]; lte_earfcn_t channels[MAX_EARFCN];
@ -34,45 +43,28 @@ float freqs[MAX_EARFCN];
float cfo[MAX_EARFCN]; float cfo[MAX_EARFCN];
float p2a[MAX_EARFCN]; float p2a[MAX_EARFCN];
#define MHZ 1000000 enum sync_state {INIT, FIND, TRACK, DONE};
#define SAMP_FREQ 1920000
#define RSSI_FS 1000000
#define RSSI_NSAMP 50000
#define FLEN 9600
#define FLEN_PERIOD 0.005
#define IS_SIGNAL(i) (10*log10f(rssi[i]) + 30 > rssi_threshold)
void print_to_matlab(); void print_to_matlab();
void usage(char *prog) { void usage(char *prog) {
printf("Usage: %s [senvtr] -b band\n", prog); printf("Usage: %s [seRrFfTtgv] -b band\n", prog);
printf("\t-s earfcn_start [Default %d]\n", earfcn_start); printf("\t-s earfcn_start [Default All]\n");
printf("\t-e earfcn_end [Default All]\n"); printf("\t-e earfcn_end [Default All]\n");
printf("\t-n number of frames [Default %d]\n", nof_slots); printf("\t-R rssi_nof_samples [Default %d]\n", nof_samples_rssi);
printf("\t-v [set verbose to debug, default none]\n");
printf("\t-t pss_threshold [Default %.2f]\n", pss_threshold);
printf("\t-r rssi_threshold [Default %.2f dBm]\n", rssi_threshold); printf("\t-r rssi_threshold [Default %.2f dBm]\n", rssi_threshold);
printf("\t-f force_N_id_2 [Default no]\n"); printf("\t-F pss_find_nof_frames [Default %d]\n", nof_frames_find);
printf("\t-g gain [Default no %.2f dB]\n", gain); printf("\t-f pss_find_threshold [Default %.2f]\n", find_threshold);
printf("\t-T pss_track_nof_frames [Default %d]\n", nof_frames_track);
printf("\t-t pss_track_threshold [Default %.2f]\n", track_threshold);
printf("\t-g gain [Default %.2f dB]\n", gain);
printf("\t-v [set verbose to debug, default none]\n");
} }
void parse_args(int argc, char **argv) { void parse_args(int argc, char **argv) {
int opt; int opt;
while ((opt = getopt(argc, argv, "gfrtbsenv")) != -1) { while ((opt = getopt(argc, argv, "bseRrFfTtgv")) != -1) {
switch(opt) { switch(opt) {
case 'g':
gain = atof(argv[optind]);
break;
case 'f':
force_N_id_2 = atoi(argv[optind]);
break;
case 't':
pss_threshold = atof(argv[optind]);
break;
case 'r':
rssi_threshold = -atof(argv[optind]);
break;
case 'b': case 'b':
band = atoi(argv[optind]); band = atoi(argv[optind]);
break; break;
@ -82,8 +74,26 @@ void parse_args(int argc, char **argv) {
case 'e': case 'e':
earfcn_end = atoi(argv[optind]); earfcn_end = atoi(argv[optind]);
break; break;
case 'n': case 'R':
nof_slots = atoi(argv[optind]); nof_samples_rssi = atoi(argv[optind]);
break;
case 'r':
rssi_threshold = -atof(argv[optind]);
break;
case 'F':
nof_frames_find = atoi(argv[optind]);
break;
case 'f':
find_threshold = atof(argv[optind]);
break;
case 'T':
nof_frames_track = atoi(argv[optind]);
break;
case 't':
track_threshold = atof(argv[optind]);
break;
case 'g':
gain = atof(argv[optind]);
break; break;
case 'v': case 'v':
verbose++; verbose++;
@ -103,17 +113,27 @@ int base_init(int frame_length) {
exit(-1); exit(-1);
} }
idx_v = malloc(nof_slots * sizeof(int)); idx_v = malloc(nof_frames_track * sizeof(int));
if (!idx_v) { if (!idx_v) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
cfo_v = malloc(nof_slots * sizeof(float)); idx_valid = malloc(nof_frames_track * sizeof(int));
if (!idx_valid) {
perror("malloc");
exit(-1);
}
t = malloc(nof_frames_track * sizeof(int));
if (!t) {
perror("malloc");
exit(-1);
}
cfo_v = malloc(nof_frames_track * sizeof(float));
if (!cfo_v) { if (!cfo_v) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
} }
p2a_v = malloc(nof_slots * sizeof(float)); p2a_v = malloc(nof_frames_track * sizeof(float));
if (!p2a_v) { if (!p2a_v) {
perror("malloc"); perror("malloc");
exit(-1); exit(-1);
@ -137,6 +157,8 @@ void base_free() {
uhd_close(&uhd); uhd_close(&uhd);
free(input_buffer); free(input_buffer);
free(idx_v); free(idx_v);
free(idx_valid);
free(t);
free(cfo_v); free(cfo_v);
free(p2a_v); free(p2a_v);
} }
@ -158,14 +180,61 @@ float mean_valid(int *idx_v, float *x, int nof_frames) {
} }
} }
int main(int argc, char **argv) { int preprocess_idx(int *in, int *out, int *period, int len) {
int frame_cnt; int i, n;
n=0;
for (i=0;i<len;i++) {
if (in[i] != -1) {
out[n] = in[i];
period[n] = i;
n++;
}
}
return n;
}
int rssi_scan() {
int n=0;
int i; int i;
int nsamples; float rssi_d[MAX_EARFCN/10];
if (nof_bands > 100) {
/* scan every Mhz, that is 10 freqs */
for (i=0;i<nof_bands;i+=10) {
freqs[n] = channels[i].fd * MHZ;
n++;
}
if (uhd_rssi_scan(uhd, freqs, rssi_d, n, (double) RSSI_FS, nof_samples_rssi)) {
fprintf(stderr, "Error while doing RSSI scan\n");
return -1;
}
/* linearly interpolate the rssi vector */
interp_linear_f(rssi_d, rssi, 10, n);
} else {
for (i=0;i<nof_bands;i++) {
freqs[i] = channels[i].fd * MHZ;
}
if (uhd_rssi_scan(uhd, freqs, rssi, nof_bands, (double) RSSI_FS, nof_samples_rssi)) {
fprintf(stderr, "Error while doing RSSI scan\n");
return -1;
}
n = nof_bands;
}
return n;
}
int main(int argc, char **argv) {
int frame_cnt, valid_frames;
int freq;
int cell_id; int cell_id;
sync_t synch; sync_t synch;
float max_peak_to_avg; float max_peak_to_avg;
float sfo; float sfo;
int find_idx, last_found;
enum sync_state state;
int n;
if (argc < 3) { if (argc < 3) {
usage(argv[0]); usage(argv[0]);
@ -179,104 +248,140 @@ int main(int argc, char **argv) {
exit(-1); exit(-1);
} }
if (sync_init(&synch)) { if (sync_init(&synch, FLEN)) {
fprintf(stderr, "Error initiating PSS/SSS\n"); fprintf(stderr, "Error initiating PSS/SSS\n");
exit(-1); exit(-1);
} }
sync_set_threshold(&synch, pss_threshold);
sync_pss_det_peakmean(&synch); sync_pss_det_peakmean(&synch);
if (force_N_id_2 != -1) {
sync_force_N_id_2(&synch, force_N_id_2);
}
nof_bands = lte_band_get_fd_band(band, channels, earfcn_start, earfcn_end, MAX_EARFCN); nof_bands = lte_band_get_fd_band(band, channels, earfcn_start, earfcn_end, MAX_EARFCN);
printf("RSSI scan: %d freqs in band %d\n", nof_bands, band); printf("RSSI scan: %d freqs in band %d, RSSI threshold %.2f dBm\n", nof_bands, band, rssi_threshold);
for (i=0;i<nof_bands;i++) {
freqs[i] = channels[i].fd * MHZ;
}
n = rssi_scan();
if (uhd_rssi_scan(uhd, freqs, rssi, nof_bands, (double) RSSI_FS, RSSI_NSAMP)) { if (n == -1) {
fprintf(stderr, "Error while doing RSSI scan\n");
exit(-1); exit(-1);
} }
printf("\nDone. Starting PSS search\n"); printf("\nDone. Starting PSS search on %d channels\n", n);
usleep(500000); usleep(500000);
printf("Setting sampling frequency %.2f MHz\n", (float) SAMP_FREQ/MHZ); INFO("Setting sampling frequency %.2f MHz\n", (float) SAMP_FREQ/MHZ);
uhd_set_rx_srate(uhd, SAMP_FREQ); uhd_set_rx_srate(uhd, SAMP_FREQ);
uhd_set_rx_gain(uhd, gain); uhd_set_rx_gain(uhd, gain);
print_to_matlab(); print_to_matlab();
int first = 1;
for (i=0;i<nof_bands;i++) { freq=0;
state = INIT;
while(freq<nof_bands) {
/* scan only bands above rssi_threshold */ /* scan only bands above rssi_threshold */
if (IS_SIGNAL(i)) { if (!IS_SIGNAL(freq)) {
uhd_set_rx_freq(uhd, (double) channels[i].fd * MHZ); INFO("[%3d/%d]: Skipping EARFCN %d %.2f MHz RSSI %.2f dB\n", freq, nof_bands,
channels[freq].id, channels[freq].fd,10*log10f(rssi[freq]) + 30);
freq++;
} else {
if (state == TRACK || state == FIND) {
uhd_recv(uhd, &input_buffer[FLEN], FLEN, 1);
}
switch(state) {
case INIT:
DEBUG("Stopping receiver...\n",0);
uhd_stop_rx_stream(uhd);
/* set freq */
uhd_set_rx_freq(uhd, (double) channels[freq].fd * MHZ);
uhd_rx_wait_lo_locked(uhd); uhd_rx_wait_lo_locked(uhd);
DEBUG("Set freq to %.3f MHz\n", (double) channels[freq].fd);
if (first) { DEBUG("Starting receiver...\n",0);
INFO("Starting receiver...\n",0);
uhd_start_rx_stream(uhd); uhd_start_rx_stream(uhd);
first = 0;
}
/* init variables */
frame_cnt = 0; frame_cnt = 0;
nsamples = 0;
max_peak_to_avg = -99; max_peak_to_avg = -99;
nsamples += uhd_recv(uhd, input_buffer, FLEN, 1);
cell_id = -1; cell_id = -1;
while(frame_cnt < nof_slots) {
if (frame_cnt) {
nsamples += uhd_recv(uhd, &input_buffer[FLEN], FLEN, 1);
}
idx_v[frame_cnt] = sync_run(&synch, input_buffer, frame_cnt?FLEN:0); /* receive first frame */
uhd_recv(uhd, input_buffer, FLEN, 1);
/* set find_threshold and go to FIND state */
sync_set_threshold(&synch, find_threshold);
sync_force_N_id_2(&synch, -1);
state = FIND;
break;
case FIND:
/* find peak in all frame */
find_idx = sync_run(&synch, input_buffer, FLEN);
DEBUG("[%3d/%d]: PAR=%.2f\n", freq, nof_bands, sync_get_peak_to_avg(&synch));
if (find_idx != -1) {
/* if found peak, go to track and set lower threshold */
frame_cnt = -1;
last_found = 0;
sync_set_threshold(&synch, track_threshold);
sync_force_N_id_2(&synch, sync_get_N_id_2(&synch));
state = TRACK;
INFO("[%3d/%d]: EARFCN %d Freq. %.2f MHz PSS found PAR %.2f dB\n", freq, nof_bands,
channels[freq].id, channels[freq].fd,
10*log10f(sync_get_peak_to_avg(&synch)));
} else {
if (frame_cnt >= nof_frames_find) {
state = INIT;
printf("[%3d/%d]: EARFCN %d Freq. %.2f MHz No PSS found\r", freq, nof_bands,
channels[freq].id, channels[freq].fd, frame_cnt - last_found);
if (VERBOSE_ISINFO()) {
printf("\n");
}
freq++;
}
}
break;
case TRACK:
/* TODO: find peak around find_idx */
idx_v[frame_cnt] = sync_run(&synch, input_buffer, FLEN);
p2a_v[frame_cnt] = sync_get_peak_to_avg(&synch); p2a_v[frame_cnt] = sync_get_peak_to_avg(&synch);
if (idx_v[frame_cnt] != -1) {
/* save cell id for the best peak-to-avg */ /* save cell id for the best peak-to-avg */
if (p2a_v[frame_cnt] > max_peak_to_avg) { if (p2a_v[frame_cnt] > max_peak_to_avg) {
max_peak_to_avg = p2a_v[frame_cnt]; max_peak_to_avg = p2a_v[frame_cnt];
cell_id = sync_get_cell_id(&synch); cell_id = sync_get_cell_id(&synch);
} }
if (idx_v[frame_cnt] != -1) {
cfo_v[frame_cnt] = sync_get_cfo(&synch); cfo_v[frame_cnt] = sync_get_cfo(&synch);
last_found = frame_cnt;
} else { } else {
cfo_v[frame_cnt] = 0.0; cfo_v[frame_cnt] = 0.0;
} }
if (frame_cnt) { /* if we missed to many frames it is not a cell, next freq */
memcpy(input_buffer, &input_buffer[FLEN], FLEN * sizeof(cf_t)); if (frame_cnt - last_found > max_track_lost) {
} INFO("\n[%3d/%d]: EARFCN %d Freq. %.2f MHz %d frames lost\n", freq, nof_bands,
if (VERBOSE_ISINFO()) { channels[freq].id, channels[freq].fd, frame_cnt - last_found);
printf("[%4d] - idx: %5d\tpeak-to-avg: %3.2f\tcfo=%.3f\r", frame_cnt,
idx_v[frame_cnt], p2a_v[frame_cnt], cfo_v[frame_cnt]);
}
frame_cnt++;
}
cfo[i] = mean_valid(idx_v, cfo_v, nof_slots); state = INIT;
p2a[i] = sum_r(p2a_v, nof_slots) / nof_slots; freq++;
if (channels[i].id == 1900 } else if (frame_cnt >= nof_frames_track) {
|| channels[i].id == 1901) { state = DONE;
vec_fprint_i(stdout, idx_v, nof_slots);
} }
break;
sfo = sfo_estimate(idx_v, nof_slots, FLEN_PERIOD); case DONE:
if (VERBOSE_ISINFO()) {
printf("\n"); cfo[freq] = mean_valid(idx_v, cfo_v, frame_cnt);
p2a[freq] = mean_valid(idx_v, p2a_v, frame_cnt);
valid_frames = preprocess_idx(idx_v, idx_valid, t, frame_cnt);
sfo = sfo_estimate_period(idx_valid, t, valid_frames, FLEN_PERIOD);
printf("\n[%3d/%d]: FOUND EARFCN %d Freq. %.2f MHz, "
"RSSI %3.2f dBm, PAR %2.2f dB, CFO=%+.2f KHz, SFO=%+2.3f KHz, CELL_ID=%3d\n", freq, nof_bands,
channels[freq].id, channels[freq].fd, 10*log10f(rssi[freq]) + 30,
10*log10f(p2a[freq]), cfo[freq] * 15, sfo / 1000, cell_id);
state = INIT;
freq++;
break;
} }
if (state == TRACK || (state == FIND && frame_cnt)) {
printf("[%3d/%d]: EARFCN %d Freq. %.2f MHz, " memcpy(input_buffer, &input_buffer[FLEN], FLEN * sizeof(cf_t));
"RSSI %3.2f dBm, PSS %2.2f dB, CFO=%+2.1f KHz, SFO=%+2.1f KHz, CELL_ID=%3d\n", i, nof_bands, }
channels[i].id, channels[i].fd, 10*log10f(rssi[i]) + 30, frame_cnt++;
10*log10f(p2a[i]), cfo[i] * 15, sfo / 1000, cell_id);
print_to_matlab();
} else {
INFO("[%3d/%d]: EARFCN %d Freq. %.2f MHz. RSSI below threshold (%3.2f < %3.2f dBm)\n",
i, nof_bands, channels[i].id, channels[i].fd, 10*log10f(rssi[i]) + 30, rssi_threshold);
} }
} }
@ -285,7 +390,7 @@ int main(int argc, char **argv) {
sync_free(&synch); sync_free(&synch);
base_free(); base_free();
printf("Done\n"); printf("\n\nDone\n");
exit(0); exit(0);
} }

@ -21,3 +21,4 @@ typedef _Complex float cf_t;
void interp_linear_offset(cf_t *input, cf_t *output, int M, int len, int off_st, int off_end); void interp_linear_offset(cf_t *input, cf_t *output, int M, int len, int off_st, int off_end);
void interp_linear(cf_t *input, cf_t *output, int M, int len); void interp_linear(cf_t *input, cf_t *output, int M, int len);
void interp_linear_f(float *input, float *output, int M, int len);

@ -20,6 +20,6 @@
#define SFO_ #define SFO_
float sfo_estimate(int *t0, int len, float period); float sfo_estimate(int *t0, int len, float period);
float sfo_estimate_period(int *t0, int *t, int len, float period);
#endif #endif

@ -49,7 +49,7 @@ int sync_get_N_id_2(sync_t *q);
int sync_get_N_id_1(sync_t *q); int sync_get_N_id_1(sync_t *q);
int sync_get_cell_id(sync_t *q); int sync_get_cell_id(sync_t *q);
void sync_set_threshold(sync_t *q, float threshold); void sync_set_threshold(sync_t *q, float threshold);
int sync_init(sync_t *q); int sync_init(sync_t *q, int frame_size);
void sync_free(sync_t *q); void sync_free(sync_t *q);
#endif #endif

@ -81,7 +81,7 @@ void chest_ce_ref(chest_t *q, cf_t *input, int nslot, int port_id, int nref) {
q->refsignal[port_id][nslot].refs[nref].recv_simbol = channel_ref; q->refsignal[port_id][nslot].refs[nref].recv_simbol = channel_ref;
/* FIXME: compare with treshold */ /* FIXME: compare with treshold */
if (channel_ref != 0) { if (channel_ref != 0) {
q->refsignal[port_id][nslot].ch_est[nref] = known_ref/channel_ref; q->refsignal[port_id][nslot].ch_est[nref] = channel_ref/known_ref;
} else { } else {
q->refsignal[port_id][nslot].ch_est[nref] = 0; q->refsignal[port_id][nslot].ch_est[nref] = 0;
} }
@ -118,14 +118,10 @@ void chest_ce_slot_port(chest_t *q, cf_t *input, cf_t *ce, int nslot, int port_i
for (i=0;i<q->nof_prb * RE_X_RB; i++) { for (i=0;i<q->nof_prb * RE_X_RB; i++) {
for (j=0;j<r->nsymbols;j++) { for (j=0;j<r->nsymbols;j++) {
x[j] = ce[r->symbols_ref[j] * q->nof_prb * RE_X_RB + i]; x[j] = ce[r->symbols_ref[j] * q->nof_prb * RE_X_RB + i];
printf("x[%d]=ce[%d]=%.3f\n", j,
r->symbols_ref[j] * q->nof_prb * RE_X_RB + i,
cabsf(x[j]));
} }
interp_linear_offset(x, y, r->symbols_ref[1]-r->symbols_ref[0], interp_linear_offset(x, y, r->symbols_ref[1]-r->symbols_ref[0],
2, r->symbols_ref[0], 3); 2, r->symbols_ref[0], 3);
for (j=0;j<q->nof_symbols;j++) { for (j=0;j<q->nof_symbols;j++) {
printf("ce[%d] = y[%d] =%.3f\n", j * q->nof_prb * RE_X_RB + i, j, cabsf(x[j]));
ce[j * q->nof_prb * RE_X_RB + i] = y[j]; ce[j * q->nof_prb * RE_X_RB + i] = y[j];
} }
} }

@ -57,3 +57,14 @@ void interp_linear_offset(cf_t *input, cf_t *output, int M, int len, int off_st,
void interp_linear(cf_t *input, cf_t *output, int M, int len) { void interp_linear(cf_t *input, cf_t *output, int M, int len) {
interp_linear_offset(input, output, M, len, 0, 0); interp_linear_offset(input, output, M, len, 0, 0);
} }
/* Performs 1st order integer linear interpolation */
void interp_linear_f(float *input, float *output, int M, int len) {
int i, j;
for (i=0;i<len-1;i++) {
for (j=0;j<M;j++) {
output[i*M+j] = input[i] + j * (input[i+1]-input[i]) / M;
}
}
}

@ -132,14 +132,14 @@ int pss_generate(cf_t *signal, int direction, int N_id_2) {
for (i = 0; i < PSS_LEN / 2; i++) { for (i = 0; i < PSS_LEN / 2; i++) {
arg = (float) sign * M_PI * root_value[root_idx] arg = (float) sign * M_PI * root_value[root_idx]
* ((float) i * ((float) i + 1.0)) / 63.0; * ((float) i * ((float) i + 1.0)) / 63.0;
__real__ signal[i] = cos(arg); __real__ signal[i] = cosf(arg);
__imag__ signal[i] = sin(arg); __imag__ signal[i] = sinf(arg);
} }
for (i = PSS_LEN / 2; i < PSS_LEN; i++) { for (i = PSS_LEN / 2; i < PSS_LEN; i++) {
arg = (float) sign * M_PI * root_value[root_idx] arg = (float) sign * M_PI * root_value[root_idx]
* (((float) i + 2.0) * ((float) i + 1.0)) / 63.0; * (((float) i + 2.0) * ((float) i + 1.0)) / 63.0;
__real__ signal[i] = cos(arg); __real__ signal[i] = cosf(arg);
__imag__ signal[i] = sin(arg); __imag__ signal[i] = sinf(arg);
} }
return 0; return 0;
} }

@ -16,6 +16,8 @@
* along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>. * along with OSLD-lib. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include "sync/sfo.h" #include "sync/sfo.h"
/* Estimate SFO based on the array of time estimates t0 /* Estimate SFO based on the array of time estimates t0
@ -29,3 +31,17 @@ float sfo_estimate(int *t0, int len, float period) {
} }
return sfo; return sfo;
} }
/* Same as sfo_estimate but period is non-uniform.
* Vector t is the sampling time times period for each t0
*/
float sfo_estimate_period(int *t0, int *t, int len, float period) {
int i;
float sfo=0.0;
for (i=1;i<len;i++) {
if (abs(t0[i]-t0[i-1]) < 5000) {
sfo += (t0[i]-t0[i-1])/(t[i] - t[i-1])/period;
}
}
return sfo/(len-2);
}

@ -23,7 +23,7 @@
#include "lte/base.h" #include "lte/base.h"
#include "sync/sync.h" #include "sync/sync.h"
int sync_init(sync_t *q) { int sync_init(sync_t *q, int frame_size) {
int N_id_2; int N_id_2;
bzero(q, sizeof(sync_t)); bzero(q, sizeof(sync_t));
@ -32,7 +32,7 @@ int sync_init(sync_t *q) {
q->pss_mode = PEAK_MEAN; q->pss_mode = PEAK_MEAN;
for (N_id_2=0;N_id_2<3;N_id_2++) { for (N_id_2=0;N_id_2<3;N_id_2++) {
if (pss_synch_init(&q->pss[N_id_2], 960)) { if (pss_synch_init(&q->pss[N_id_2], frame_size)) {
fprintf(stderr, "Error initializing PSS object\n"); fprintf(stderr, "Error initializing PSS object\n");
return -1; return -1;
} }
@ -153,10 +153,11 @@ int sync_run(sync_t *q, cf_t *input, int read_offset) {
} }
if (peak_detected) { if (peak_detected) {
INFO("PSS peak detected N_id_2=%d, pos=%d value=%.2f\n", N_id_2, peak_pos[N_id_2], peak_value[N_id_2]);
q->cfo = pss_synch_cfo_compute(&q->pss[N_id_2], &input[read_offset + peak_pos[N_id_2]-128]); q->cfo = pss_synch_cfo_compute(&q->pss[N_id_2], &input[read_offset + peak_pos[N_id_2]-128]);
INFO("Estimated CFO=%.4f\n", q->cfo);
INFO("PSS peak detected N_id_2=%d, pos=%d peak=%.2f par=%.2f th=%.2f cfo=%.4f\n", N_id_2,
peak_pos[N_id_2], peak_value[N_id_2], q->peak_to_avg, q->threshold, q->cfo);
sss_idx = read_offset + peak_pos[N_id_2]-2*(128+CP(128,CPNORM_LEN)); sss_idx = read_offset + peak_pos[N_id_2]-2*(128+CP(128,CPNORM_LEN));
if (sss_idx>= 0) { if (sss_idx>= 0) {

@ -117,7 +117,7 @@ void vec_fprint_c(FILE *stream, _Complex float *x, int len) {
//if (!((i+1)%10)) //if (!((i+1)%10))
// fprintf(stream, "\n"); // fprintf(stream, "\n");
} }
fprintf(stream, "]\n"); fprintf(stream, "];\n");
} }
void vec_fprint_f(FILE *stream, float *x, int len) { void vec_fprint_f(FILE *stream, float *x, int len) {
@ -128,7 +128,7 @@ void vec_fprint_f(FILE *stream, float *x, int len) {
//if (!((i+1)%10)) //if (!((i+1)%10))
// fprintf(stream, "\n"); // fprintf(stream, "\n");
} }
fprintf(stream, "]\n"); fprintf(stream, "];\n");
} }
@ -138,7 +138,7 @@ void vec_fprint_i(FILE *stream, int *x, int len) {
for (i=0;i<len;i++) { for (i=0;i<len;i++) {
fprintf(stream, "%d, ", x[i]); fprintf(stream, "%d, ", x[i]);
} }
fprintf(stream, "]\n"); fprintf(stream, "];\n");
} }
void vec_conj(_Complex float *x, _Complex float *y, int len) { void vec_conj(_Complex float *x, _Complex float *y, int len) {

@ -0,0 +1,20 @@
function [ out ] = read_complex( filename, count )
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'r');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (nargin==1)
count=inf;
end
x=fread(tidin,2*count,'single');
i=1:2:length(x);
out=x(i)+x(i+1)*1i;
end

@ -0,0 +1,22 @@
function [ out ] = write_complex( filename, x)
%READ_COMPLEX Summary of this function goes here
% Detailed explanation goes here
[tidin msg]=fopen(filename,'w');
if (tidin==-1)
fprintf('error opening %s: %s\n',filename, msg);
out=[];
return
end
if (isreal(x))
y=x;
else
i=1:2:2*length(x);
y(i)=real(x);
y(i+1)=imag(x);
end
fwrite(tidin,y,'single');
end

@ -1,4 +1,4 @@
function [ fs ] = check_pss( x, N_id_2) function [ fs ] = check_pss( x, N_id_2, threshold)
%CHECK_PSS Summary of this function goes here %CHECK_PSS Summary of this function goes here
% Detailed explanation goes here % Detailed explanation goes here
flen=9600; flen=9600;
@ -11,28 +11,23 @@ fs=zeros(nf,1);
cfo=zeros(nf,1); cfo=zeros(nf,1);
cfo2=zeros(nf,1); cfo2=zeros(nf,1);
m_p=zeros(nf,1); m_p=zeros(nf,1);
for i=1:nf-1 for i=1:nf
[fs(i) cfo(i) m_p(i)]=find_pss(xf(:,i),N_id_2,false); [fs(i) cfo(i) m_p(i)]=find_pss(xf(:,i),N_id_2,false, threshold);
if (fs(i)<0)
j=0;
end
% cfo2(i) = cfo_estimate_cp(xf(fs(i)+960:fs(i)+2*960,i),7,128,10,9);
end end
sfo=sfo_estimate(fs, 5/1000); fs=fs+960;
[sfo sfo_v]=sfo_estimate(fs, 5/1000);
subplot(1,3,1) subplot(1,3,1)
plot(1:nf,fs) plot(1:nf,fs)
legend('PSS-based');
subplot(1,3,2) subplot(1,3,2)
plot(1:nf, cfo, 1:nf, cfo2) plot(1:nf, cfo)
legend('PSS-based','CP-based');
if (nf > 0) if (nf > 0)
axis([0 nf -0.5 0.5]) axis([0 nf -0.5 0.5])
end end
subplot(1,3,3) subplot(1,3,3)
plot(m_p) plot(m_p)
fprintf('pss_mean=%g, pss_var=%g, cp_mean=%g, cp_var=%g m_p=%g sfo=%g Hz\n',mean(cfo),var(cfo), mean(cfo2), var(cfo2), mean(m_p), sfo) fprintf('cfo_mean=%g Hz, cfo_std=%g Hz, m_p=%g sfo=%g Hz\n',15000*nanmean(cfo),15000*nanstd(cfo), nanmean(m_p), sfo)
end end

@ -1,6 +1,10 @@
function [ fs eps p_m w2] = find_pss( x, N_id_2, doplot) function [ fs eps p_m w2] = find_pss( x, N_id_2, doplot, threshold)
if nargin == 2 if nargin == 2
doplot = false; doplot = false;
threshold = 0;
end
if nargin == 3
threshold = 0;
end end
c=lte_pss_zc(N_id_2); c=lte_pss_zc(N_id_2);
@ -10,26 +14,29 @@ function [ fs eps p_m w2] = find_pss( x, N_id_2, doplot)
w2=conv(x,ccf); w2=conv(x,ccf);
if (doplot) if (doplot)
plot(abs(w2)) plot(10*log10(abs(w2)./mean(abs(w2))));
axis([0 length(w2) 0 20])
end end
[m i]=max(abs(w2)); [m i]=max(abs(w2));
fs=i-960; fs=i-960;
p_m = m/mean(abs(w2)); p_m = m/mean(abs(w2));
if doplot if doplot
fprintf('Frame starts at %d, m=%g, p=%g, p/m=%g dB\n',fs, ... fprintf('Frame starts at %d, m=%g, p=%g, p/m=%g dB\n',fs, ...
mean(abs(w2)), m, 10*log10(m/mean(abs(w2)))); mean(abs(w2)), m, 10*log10(m/mean(abs(w2))));
end end
% Estimate PSS-aided CFO % Estimate PSS-aided CFO
% if (i - 129) if (i > 200 && i<length(x)&& p_m > threshold)
% y=ccf.*x(i-128:i-1); y=ccf.*x(i-128:i-1);
%
% y0=y(1:64); y0=y(1:64);
% y1=y(65:length(y)); y1=y(65:length(y));
%
% eps=angle(conj(sum(y0))*sum(y1))/pi; eps=angle(conj(sum(y0))*sum(y1))/pi;
% else else
eps = NaN; eps = NaN;
% end fs = NaN;
end
end end

@ -0,0 +1,13 @@
function [ ifo ] = ifo_pss( r_pss, x_pss)
k=1;
v=-31:31;
c=zeros(length(v),1);
for i=v
c(k) = ifo_pss_corr(i, r_pss, x_pss);
k=k+1;
end
[m i]=max(c);
ifo=v(i);
plot(v,c);

@ -0,0 +1,10 @@
function [ corr ] = ifo_pss_corr( n, r_pss, x_pss)
x=0;
for i=1:length(x_pss)
x=x+r_pss(1+mod(i+n-1,length(r_pss)))*conj(x_pss(i));
end
corr=real(exp(1i*2*pi*9*n/128)*x);
% corr=abs(x);
end

@ -1,7 +1,18 @@
function [ sfo ] = sfo_estimate( fs, T ) function [ sfo sfo_v ] = sfo_estimate( fs, T )
sfo = 0;
for i=2:length(fs) nanfs=fs(~isnan(fs));
sfo=sfo + (fs(i)-fs(i-1))/length(fs)/T; idx=find(~isnan(fs));
sfo_v = zeros(length(nanfs)-1,1);
for i=2:length(nanfs)
if (abs(nanfs(i)-nanfs(i-1))<9000)
sfo_v(i-1)=(nanfs(i)-nanfs(i-1))/T/(idx(i)-idx(i-1));
else
sfo_v(i-1)=sfo_v(i-2);
end
end end
sfo = mean(sfo_v);

@ -70,7 +70,7 @@ int uhd_open(char *args, void **h) {
std::string _args=std::string(args); std::string _args=std::string(args);
handler->usrp = uhd::usrp::multi_usrp::make(_args); handler->usrp = uhd::usrp::multi_usrp::make(_args);
uhd::msg::register_handler(&my_handler); //uhd::msg::register_handler(&my_handler);
std::string otw, cpu; std::string otw, cpu;
otw="sc16"; otw="sc16";

Loading…
Cancel
Save