Fixed USRP buffer overflows due to small num_recv_frames. AGC working using vec_max. Improved cell search

master
ismagom 10 years ago
parent ee78f0111b
commit c382f2cbba

@ -42,4 +42,5 @@ public:
pthread_mutex_t mutex;
double cur_rx_gain;
double new_rx_gain;
uhd::gain_range_t rx_gain_range;
};

@ -30,11 +30,12 @@
#include <complex>
#include <cstdio>
#include <uhd/utils/msg.hpp>
#include <sys/time.h>
#include "cuhd_handler.hpp"
#include "srslte/cuhd/cuhd.h"
//#define METADATA_VERBOSE
#define METADATA_VERBOSE
//#define HIDE_MESSAGES
@ -119,15 +120,13 @@ int cuhd_start_rx_stream_nsamples(void *h, uint32_t nsamples)
double cuhd_set_rx_gain_th(void *h, double gain)
{
/*
cuhd_handler *handler = static_cast < cuhd_handler * >(h);
// round to avoid histeresis
gain = roundf(gain);
gain = handler->rx_gain_range.clip(gain);
pthread_mutex_lock(&handler->mutex);
handler->new_rx_gain = gain;
pthread_cond_signal(&handler->cond);
pthread_mutex_unlock(&handler->mutex);
*/
return gain;
}
@ -142,7 +141,7 @@ static void* thread_gain_fcn(void *h) {
handler->cur_rx_gain = handler->new_rx_gain;
pthread_mutex_unlock(&handler->mutex);
cuhd_set_rx_gain(h, handler->cur_rx_gain);
printf("set gain to %f\n", handler->cur_rx_gain);
//printf("Set gain %.2f\n", handler->cur_rx_gain);
}
}
@ -150,7 +149,7 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain)
{
cuhd_handler *handler = new cuhd_handler();
std::string _args = std::string(args);
handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000");
handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000, num_recv_frames=512");
// handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=50000000" + ", num_recv_frames=512");
handler->usrp->set_clock_source("internal");
@ -166,6 +165,10 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain)
handler->rx_stream = handler->usrp->get_rx_stream(stream_args);
handler->tx_stream = handler->usrp->get_tx_stream(stream_args);
handler->rx_gain_range = handler->usrp->get_rx_gain_range();
*h = handler;
if (create_thread_gain) {

@ -48,7 +48,8 @@ float gain_offset = B210_DEFAULT_GAIN_CORREC;
cell_search_cfg_t cell_detect_config = {
5000, // maximum number of frames to receive for MIB decoding
50, // maximum number of frames to receive for PSS correlation
16.0 // early-stops cell detection if mean PSR is above this value
10.0,
50.0
};
/**********************************************************************

@ -55,7 +55,7 @@
int band = -1;
int earfcn_start=-1, earfcn_end = -1;
cell_search_cfg_t config = {100, 10, 16, true};
cell_search_cfg_t config = {100, 10, 10.0, 50};
float uhd_gain = 60.0;
@ -167,8 +167,8 @@ int main(int argc, char **argv) {
if (config.threshold) {
srslte_ue_cellsearch_set_threshold(&cs, config.threshold);
}
if (config.do_agc) {
srslte_ue_sync_start_agc(&cs.ue_sync, cuhd_set_rx_gain);
if (config.init_agc) {
srslte_ue_sync_start_agc(&cs.ue_sync, cuhd_set_rx_gain, config.init_agc);
}
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000);

@ -60,8 +60,8 @@ int cuhd_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell)
goto clean_exit;
}
if (config->do_agc) {
srslte_ue_sync_start_agc(&ue_mib.ue_sync, cuhd_set_rx_gain_th);
if (config->init_agc > 0) {
srslte_ue_sync_start_agc(&ue_mib.ue_sync, cuhd_set_rx_gain_th, config->init_agc);
}
int srate = srslte_sampling_freq_hz(SRSLTE_UE_MIB_NOF_PRB);
@ -81,6 +81,11 @@ int cuhd_mib_decoder(void *uhd, cell_search_cfg_t *config, srslte_cell_t *cell)
srslte_pbch_mib_unpack(bch_payload, cell, NULL);
}
// Save AGC value
if (config->init_agc > 0) {
config->init_agc = srslte_agc_get_gain(&ue_mib.ue_sync.agc);
}
clean_exit:
cuhd_stop_rx_stream(uhd);
@ -112,8 +117,8 @@ int cuhd_cell_search(void *uhd, cell_search_cfg_t *config,
srslte_ue_cellsearch_set_threshold(&cs, config->threshold);
}
if (config->do_agc) {
srslte_ue_sync_start_agc(&cs.ue_sync, cuhd_set_rx_gain_th);
if (config->init_agc > 0) {
srslte_ue_sync_start_agc(&cs.ue_sync, cuhd_set_rx_gain_th, config->init_agc);
}
INFO("Setting sampling frequency %.2f MHz for PSS search\n", SRSLTE_CS_SAMP_FREQ/1000000);
@ -138,12 +143,29 @@ int cuhd_cell_search(void *uhd, cell_search_cfg_t *config,
return SRSLTE_SUCCESS;
}
for (int i=0;i<3;i++) {
if (i == max_peak_cell) {
printf("*");
} else {
printf(" ");
}
printf("Found Cell_id: %3d CP: %s, DetectRatio=%2.0f%% PSR=%.2f, Power=%.1f dBm\n",
found_cells[i].cell_id, srslte_cp_string(found_cells[i].cp),
found_cells[i].mode*100,
found_cells[i].psr, 20*log10(found_cells[i].peak*1000));
}
// Save result
if (cell) {
cell->id = found_cells[max_peak_cell].cell_id;
cell->cp = found_cells[max_peak_cell].cp;
}
// Save AGC value for MIB decoding
if (config->init_agc > 0) {
config->init_agc = srslte_agc_get_gain(&cs.ue_sync.agc);
}
cuhd_stop_rx_stream(uhd);
srslte_ue_cellsearch_free(&cs);

@ -32,7 +32,7 @@ typedef struct SRSLTE_API {
uint32_t max_frames_pbch; // maximum number of 5ms frames to capture for MIB decoding
uint32_t max_frames_pss; // maximum number of 5ms frames to capture for PSS correlation
float threshold; // early-stops cell detection if mean PSR is above this value
bool do_agc;
float init_agc; // 0 or negative to disable AGC
}cell_search_cfg_t;
int cuhd_mib_decoder(void *uhd,

@ -47,8 +47,8 @@
cell_search_cfg_t cell_detect_config = {
5000,
100, // nof_frames_total
16.0 // threshold
200, // nof_frames_total
10.0 // threshold
};
#endif
@ -63,13 +63,6 @@ sem_t plot_sem;
uint32_t plot_sf_idx=0;
#endif
#define B210_DEFAULT_GAIN 40.0
#define B210_DEFAULT_GAIN_CORREC 110.0 // Gain of the Rx chain when the gain is set to 40
float gain_offset = B210_DEFAULT_GAIN_CORREC;
/**********************************************************************
* Program arguments processing
***********************************************************************/
@ -269,19 +262,23 @@ int main(int argc, char **argv) {
#ifndef DISABLE_UHD
if (!prog_args.input_file_name) {
/* Set receiver gain */
if (prog_args.uhd_gain > 0) {
printf("Opening UHD device...\n");
if (cuhd_open_th(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
exit(-1);
}
cuhd_set_rx_gain(uhd, 50);
/* Set receiver gain */
if (prog_args.uhd_gain > 0) {
cuhd_set_rx_gain(uhd, prog_args.uhd_gain);
} else {
cell_detect_config.do_agc = true;
printf("Opening UHD device with threaded RX Gain control ...\n");
if (cuhd_open_th(prog_args.uhd_args, &uhd)) {
fprintf(stderr, "Error opening uhd\n");
exit(-1);
}
cuhd_set_rx_gain(uhd, 50);
cell_detect_config.init_agc = 50;
}
/* set receiver frequency */
@ -289,14 +286,16 @@ int main(int argc, char **argv) {
cuhd_rx_wait_lo_locked(uhd);
printf("Tunning receiver to %.3f MHz\n", (double ) prog_args.uhd_freq/1000000);
uint32_t ntrial=0;
do {
ret = cuhd_search_and_decode_mib(uhd, &cell_detect_config, prog_args.force_N_id_2, &cell);
if (ret < 0) {
fprintf(stderr, "Error searching for cell\n");
exit(-1);
} else if (ret == 0) {
printf("Cell not found\n");
exit(0);
printf("Cell not found after %d trials. Trying again (Press Ctrl+C to exit)\n", ntrial++);
}
} while (ret == 0);
/* set sampling frequency */
int srate = srslte_sampling_freq_hz(cell.nof_prb);
@ -377,7 +376,7 @@ int main(int argc, char **argv) {
int pdcch_tx=0;
if (prog_args.uhd_gain < 0) {
srslte_ue_sync_start_agc(&ue_sync, cuhd_set_rx_gain_th);
srslte_ue_sync_start_agc(&ue_sync, cuhd_set_rx_gain_th, cell_detect_config.init_agc);
}
INFO("\nEntering main loop...\n\n", 0);
@ -478,15 +477,19 @@ int main(int argc, char **argv) {
sfn, 100*(1-(float) ue_dl.nof_detected/nof_trials),pdcch_tx-ue_dl.nof_detected,
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,ue_dl.pkt_errors);
#else
float gain = prog_args.uhd_gain;
if (gain < 0) {
gain = 10*log10(srslte_agc_get_gain(&ue_sync.agc));
}
printf("CFO: %+6.2f KHz, SFO: %+6.2f Khz, "
"RSRP: %+5.1f dBm, SNR: %4.1f dB, "
"PDCCH-Miss: %5.2f%% (%u), PDSCH-BLER: %5.2f%% Peak: %.2f Gain: %.1f dB\r",
"PDCCH-Miss: %5.2f%%, PDSCH-BLER: %5.2f%% Peak: %.2f Gain: %.1f dB\r",
srslte_ue_sync_get_cfo(&ue_sync)/1000, srslte_ue_sync_get_sfo(&ue_sync)/1000,
10*log10(rsrp*1000)-gain_offset,
10*log10(rsrp*1000)-gain,
10*log10(snr),
100*(1-(float) ue_dl.nof_detected/nof_trials), pdcch_tx-ue_dl.nof_detected,
100*(1-(float) ue_dl.nof_detected/nof_trials),
(float) 100*ue_dl.pkt_errors/ue_dl.pkts_total,
srslte_agc_get_output_level(&ue_sync.agc), 10*log10(srslte_agc_get_gain(&ue_sync.agc)));
srslte_agc_get_output_level(&ue_sync.agc), gain);
#endif
}

@ -46,8 +46,8 @@
cell_search_cfg_t cell_detect_config = {
5000,
100, // nof_frames_total
16.0 // threshold
200, // nof_frames_total
10.0 // threshold
};
#define B210_DEFAULT_GAIN 40.0

@ -43,8 +43,8 @@
#include "srslte/config.h"
#define SRSLTE_AGC_DEFAULT_TARGET 0.5
#define SRSLTE_AGC_DEFAULT_BW (2e-1)
#define SRSLTE_AGC_DEFAULT_TARGET 1.0
#define SRSLTE_AGC_DEFAULT_BW (5e-2)
typedef enum SRSLTE_API {
SRSLTE_AGC_MODE_ENERGY = 0,
@ -92,6 +92,9 @@ SRSLTE_API float srslte_agc_get_output_level(srslte_agc_t *q);
SRSLTE_API float srslte_agc_get_gain(srslte_agc_t *q);
SRSLTE_API void srslte_agc_set_gain(srslte_agc_t *q,
float init_gain_value);
SRSLTE_API void srslte_agc_lock(srslte_agc_t *q,
bool enable);

@ -128,7 +128,8 @@ SRSLTE_API int srslte_ue_sync_init_file(srslte_ue_sync_t *q,
SRSLTE_API void srslte_ue_sync_free(srslte_ue_sync_t *q);
SRSLTE_API int srslte_ue_sync_start_agc(srslte_ue_sync_t *q,
double (set_gain_callback)(void*, double));
double (set_gain_callback)(void*, double),
float init_gain_value);
SRSLTE_API uint32_t srslte_ue_sync_sf_len(srslte_ue_sync_t *q);

@ -39,7 +39,7 @@
#include "srslte/utils/debug.h"
int srslte_agc_init (srslte_agc_t *q, srslte_agc_mode_t mode) {
return srslte_agc_init_acc(q, mode, 1);
return srslte_agc_init_acc(q, mode, 0);
}
int srslte_agc_init_acc(srslte_agc_t *q, srslte_agc_mode_t mode, uint32_t nof_frames) {
@ -107,6 +107,10 @@ float srslte_agc_get_gain(srslte_agc_t *q) {
return q->gain;
}
void srslte_agc_set_gain(srslte_agc_t *q, float init_gain_value) {
q->gain = init_gain_value;
}
void srslte_agc_lock(srslte_agc_t *q, bool enable) {
q->lock = enable;
}
@ -127,7 +131,7 @@ void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
q->gain = 10.0;
} else {
gain_uhd_db = q->set_gain_callback(q->uhd_handler, gain_db);
//gain_uhd = pow(10, gain_uhd_db/10);
q->gain = pow(10, gain_uhd_db/10);
}
}
float *t;
@ -173,7 +177,7 @@ void srslte_agc_process(srslte_agc_t *q, cf_t *signal, uint32_t len) {
gg = expf(-0.5*q->bandwidth*logf(q->y_out/q->target));
q->gain *= gg;
}
INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f %d/%d\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg, q->frame_cnt, q->nof_frames);
INFO("AGC gain: %.2f (%.2f) y_out=%.3f, y=%.3f target=%.1f gg=%.2f\n", gain_db, gain_uhd_db, q->y_out, y, q->target, gg);
}
}
}

@ -336,7 +336,7 @@ int srslte_pss_synch_find_pss(srslte_pss_synch_t *q, cf_t *input, float *corr_pe
}
// Find end of peak lobe to the left
int pl_lb;
if (corr_peak_pos > 0) {
if (corr_peak_pos > 2) {
pl_lb = corr_peak_pos-1;
while(q->conv_output_avg[pl_lb-1] <= q->conv_output_avg[pl_lb] && pl_lb > 1) {
pl_lb --;

@ -68,7 +68,7 @@ int srslte_sync_init(srslte_sync_t *q, uint32_t frame_size, uint32_t fft_size) {
q->N_id_1 = 1000;
q->fft_size = fft_size;
q->frame_size = frame_size;
q->sss_alg = SSS_PARTIAL_3;
q->sss_alg = SSS_FULL;
if (srslte_pss_synch_init_fft(&q->pss, frame_size, fft_size)) {
fprintf(stderr, "Error initializing PSS object\n");

@ -36,9 +36,6 @@
#include "srslte/utils/debug.h"
#include "srslte/utils/vector.h"
float tmp_pss_corr[32*10000];
float tmp_sss_corr[31*10000];
int srslte_ue_cellsearch_init(srslte_ue_cellsearch_t * q, int (recv_callback)(void*, void*, uint32_t,srslte_timestamp_t*), void *stream_handler)
{
return srslte_ue_cellsearch_init_max(q, SRSLTE_CS_DEFAULT_MAXFRAMES_TOTAL, recv_callback, stream_handler);
@ -82,6 +79,7 @@ int srslte_ue_cellsearch_init_max(srslte_ue_cellsearch_t * q, uint32_t max_frame
q->max_frames = max_frames;
q->nof_frames_to_scan = SRSLTE_CS_DEFAULT_NOFFRAMES_TOTAL;
q->detect_threshold = 1.0;
ret = SRSLTE_SUCCESS;
}
@ -233,6 +231,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, uint32_t N_id_2
/* This means a peak was found and ue_sync is now in tracking state */
ret = srslte_sync_get_cell_id(&q->ue_sync.strack);
if (ret >= 0) {
if (srslte_sync_get_peak_value(&q->ue_sync.strack) > q->detect_threshold) {
/* Save cell id, cp and peak */
q->candidates[nof_detected_frames].cell_id = (uint32_t) ret;
q->candidates[nof_detected_frames].cp = srslte_sync_get_cp(&q->ue_sync.strack);
@ -242,13 +241,12 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, uint32_t N_id_2
INFO
("CELL SEARCH: [%3d/%3d/%d]: Found peak PSR=%.3f, Cell_id: %d CP: %s\n",
nof_detected_frames, nof_scanned_frames, q->nof_frames_to_scan,
q->candidates[nof_detected_frames].peak, q->candidates[nof_detected_frames].cell_id,
q->candidates[nof_detected_frames].psr, q->candidates[nof_detected_frames].cell_id,
srslte_cp_string(q->candidates[nof_detected_frames].cp));
memcpy(&tmp_pss_corr[nof_detected_frames*32],
&q->ue_sync.strack.pss.conv_output_avg[128], 32*sizeof(float));
memcpy(&tmp_sss_corr[nof_detected_frames*31],
&q->ue_sync.strack.sss.corr_output_m0, 31*sizeof(float));
nof_detected_frames++;
}
}
} else if (ret == 0) {
/* This means a peak is not yet found and ue_sync is in find state
@ -258,9 +256,7 @@ int srslte_ue_cellsearch_scan_N_id_2(srslte_ue_cellsearch_t * q, uint32_t N_id_2
nof_scanned_frames++;
} while ((srslte_sync_get_peak_value(&q->ue_sync.strack) < q->detect_threshold ||
nof_detected_frames < 4) &&
nof_scanned_frames < q->nof_frames_to_scan);
} while (nof_scanned_frames < q->nof_frames_to_scan);
/* In either case, check if the mean PSR is above the minimum threshold */
if (nof_detected_frames > 0) {

@ -80,9 +80,18 @@ clean_exit:
return ret;
}
int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double)) {
int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, 10, set_gain_callback, q->stream);
int srslte_ue_sync_start_agc(srslte_ue_sync_t *q, double (set_gain_callback)(void*, double), float init_gain_value) {
uint32_t nframes;
if (q->nof_recv_sf == 1) {
nframes = 10;
} else {
nframes = 0;
}
int n = srslte_agc_init_uhd(&q->agc, SRSLTE_AGC_MODE_PEAK_AMPLITUDE, nframes, set_gain_callback, q->stream);
q->do_agc = n==0?true:false;
if (q->do_agc) {
srslte_agc_set_gain(&q->agc, init_gain_value);
}
return n;
}
@ -144,8 +153,7 @@ int srslte_ue_sync_init(srslte_ue_sync_t *q,
srslte_sync_correct_cfo(&q->sfind, true);
srslte_sync_correct_cfo(&q->strack, true);
srslte_sync_set_threshold(&q->sfind, 1.3);
srslte_sync_set_em_alpha(&q->sfind, 0.01);
srslte_sync_set_threshold(&q->sfind, 1.5);
q->nof_avg_find_frames = FIND_NOF_AVG_FRAMES;
srslte_sync_set_threshold(&q->strack, 1.0);

@ -48,7 +48,7 @@
cell_search_cfg_t cell_detect_config = {
5000,
100, // nof_frames_total
16.0 // threshold
10.0 // threshold
};
#endif

Loading…
Cancel
Save