From cd6ca95cd18cb429185b04b35f6f3417c9662db5 Mon Sep 17 00:00:00 2001 From: yagoda Date: Wed, 8 Nov 2017 15:43:38 +0000 Subject: [PATCH 1/2] lime additions and resampler optimizations (#94) * adding optimizations to fractional resampler * adding txrx delay for N210 and Lime * minor corrections to Lime api * optimization of the fractional resampler --- .../srslte/phy/resampling/resample_arb.h | 7 +- lib/src/phy/resampling/resample_arb.c | 171 ++++++++++++------ .../phy/resampling/test/resample_arb_bench.c | 11 +- .../phy/resampling/test/resample_arb_test.c | 9 +- lib/src/phy/rf/rf_soapy_imp.c | 25 ++- lib/src/phy/rf/rf_soapy_imp.h | 2 +- lib/src/radio/radio.cc | 47 ++++- 7 files changed, 201 insertions(+), 71 deletions(-) diff --git a/lib/include/srslte/phy/resampling/resample_arb.h b/lib/include/srslte/phy/resampling/resample_arb.h index 98d004b0b..4ebb8dc08 100644 --- a/lib/include/srslte/phy/resampling/resample_arb.h +++ b/lib/include/srslte/phy/resampling/resample_arb.h @@ -38,10 +38,13 @@ #define RESAMPLE_ARB_ #include +#include #include #include "srslte/config.h" + +#define SRSLTE_RESAMPLE_ARB_N_35 35 #define SRSLTE_RESAMPLE_ARB_N 32 // Polyphase filter rows #define SRSLTE_RESAMPLE_ARB_M 8 // Polyphase filter columns @@ -49,11 +52,13 @@ typedef struct SRSLTE_API { float rate; // Resample rate float step; // Step increment through filter float acc; // Index into filter + bool interpolate; cf_t reg[SRSLTE_RESAMPLE_ARB_M]; // Our window of samples + } srslte_resample_arb_t; SRSLTE_API void srslte_resample_arb_init(srslte_resample_arb_t *q, - float rate); + float rate, bool interpolate); SRSLTE_API int srslte_resample_arb_compute(srslte_resample_arb_t *q, cf_t *input, diff --git a/lib/src/phy/resampling/resample_arb.c b/lib/src/phy/resampling/resample_arb.c index 7bdb4deec..2b04f587c 100644 --- a/lib/src/phy/resampling/resample_arb.c +++ b/lib/src/phy/resampling/resample_arb.c @@ -28,64 +28,104 @@ #include #include "srslte/phy/resampling/resample_arb.h" #include "srslte/phy/utils/debug.h" - -float srslte_resample_arb_polyfilt[SRSLTE_RESAMPLE_ARB_N][SRSLTE_RESAMPLE_ARB_M] = -{{0,0.002400347599485495,-0.006922416132556366,0.0179104136912176,0.99453086623794,-0.008521087756729117,0.0008598969867484128,0.0004992625165376107}, -{-0.001903604727400391,0.004479591950094871,-0.01525319260830623,0.04647449496926549,0.9910477342662829,-0.03275243420114668,0.008048813755373533,-0.001216900416836847}, -{-0.001750442300940216,0.006728826416921727,-0.02407540632178267,0.07708575473589654,0.9841056525667189,-0.05473739187922162,0.01460652754040275,-0.002745266140572769}, -{-0.001807302702047332,0.009130494591071001,-0.03332524241797466,0.1096377743266821,0.9737536341125557,-0.07444712408657775,0.0205085154280773,-0.004077596041064956}, -{-0.002005048395707184,0.01166717081713966,-0.04292591596219218,0.1440068251440274,0.9600641782991848,-0.09187282739868929,0.02573649090563353,-0.005218582609802016}, -{-0.002303606593778858,0.01431549924598744,-0.05279365431190471,0.1800496557331084,0.9431333663677619,-0.107022659158021,0.03028295984887362,-0.006178495199082676}, -{-0.002673824939871474,0.01705308556587308,-0.06283262272105428,0.2176066284621515,0.9230793648715676,-0.1199244901666642,0.03414559686566755,-0.006951034565279722}, -{-0.003099294850834212,0.01985022208215894,-0.07294100481214681,0.2564996326404178,0.9000412628278351,-0.1306207218667012,0.03733448898243594,-0.007554128492547957}, -{-0.003564415127592977,0.02267702927238637,-0.08300660359189582,0.2965368855416621,0.874178327911914,-0.1391710078036285,0.03986356581130199,-0.007992692892036229}, -{-0.004060222849803048,0.02549633298710617,-0.09291211362877161,0.3375102453232687,0.8456688916962831,-0.1456479420005528,0.04175429631970297,-0.00827816851803391}, -{-0.004574770330592958,0.02827133859849648,-0.1025308044303699,0.379200979038518,0.8147072909915275,-0.1501397816831265,0.04303284689167361,-0.008423951215857236}, -{-0.005100453570725489,0.0309593063669097,-0.1117325201826136,0.4213772298764557,0.7815036335229155,-0.1527444636485677,0.0437349357738538,-0.008441129184587313}, -{-0.005625340687997995,0.03351877124912608,-0.1203802123857154,0.463798444519773,0.7462810500374923,-0.1535722712206338,0.04389261707032224,-0.008345136869130621}, -{-0.006140888413286479,0.03590276234084221,-0.1283350405000867,0.5062161107254219,0.7092744343987509,-0.152741400055636,0.04355110899623683,-0.008147838953503964}, -{-0.006634012711933725,0.03806645580467819,-0.1354549138065051,0.5483763739419955,0.6707272107491931,-0.1503798528838644,0.0427502160096194,-0.007865132034489236}, -{-0.007094909626785393,0.03996043743797257,-0.1415969539549883,0.5900207719663111,0.6308907308946271,-0.1466186670140106,0.04153829696698895,-0.007508971112586246}, -{-0.007508971112586246,0.04153829696698895,-0.1466186670140106,0.6308907308946271,0.5900207719663111,-0.1415969539549883,0.03996043743797257,-0.007094909626785393}, -{-0.007865132034489236,0.0427502160096194,-0.1503798528838644,0.6707272107491931,0.5483763739419955,-0.1354549138065051,0.03806645580467819,-0.006634012711933725}, -{-0.008147838953503964,0.04355110899623683,-0.152741400055636,0.7092744343987509,0.5062161107254219,-0.1283350405000867,0.03590276234084221,-0.006140888413286479}, -{-0.008345136869130621,0.04389261707032224,-0.1535722712206338,0.7462810500374923,0.463798444519773,-0.1203802123857154,0.03351877124912608,-0.005625340687997995}, -{-0.008441129184587313,0.0437349357738538,-0.1527444636485677,0.7815036335229155,0.4213772298764557,-0.1117325201826136,0.0309593063669097,-0.005100453570725489}, -{-0.008423951215857236,0.04303284689167361,-0.1501397816831265,0.8147072909915275,0.379200979038518,-0.1025308044303699,0.02827133859849648,-0.004574770330592958}, -{-0.00827816851803391,0.04175429631970297,-0.1456479420005528,0.8456688916962831,0.3375102453232687,-0.09291211362877161,0.02549633298710617,-0.004060222849803048}, -{-0.007992692892036229,0.03986356581130199,-0.1391710078036285,0.874178327911914,0.2965368855416621,-0.08300660359189582,0.02267702927238637,-0.003564415127592977}, -{-0.007554128492547957,0.03733448898243594,-0.1306207218667012,0.9000412628278351,0.2564996326404178,-0.07294100481214681,0.01985022208215894,-0.003099294850834212}, -{-0.006951034565279722,0.03414559686566755,-0.1199244901666642,0.9230793648715676,0.2176066284621515,-0.06283262272105428,0.01705308556587308,-0.002673824939871474}, -{-0.006178495199082676,0.03028295984887362,-0.107022659158021,0.9431333663677619,0.1800496557331084,-0.05279365431190471,0.01431549924598744,-0.002303606593778858}, -{-0.005218582609802016,0.02573649090563353,-0.09187282739868929,0.9600641782991848,0.1440068251440274,-0.04292591596219218,0.01166717081713966,-0.002005048395707184}, -{-0.004077596041064956,0.0205085154280773,-0.07444712408657775,0.9737536341125557,0.1096377743266821,-0.03332524241797466,0.009130494591071001,-0.001807302702047332}, -{-0.002745266140572769,0.01460652754040275,-0.05473739187922162,0.9841056525667189,0.07708575473589654,-0.02407540632178267,0.006728826416921727,-0.001750442300940216}, -{-0.001216900416836847,0.008048813755373533,-0.03275243420114668,0.9910477342662829,0.04647449496926549,-0.01525319260830623,0.004479591950094871,-0.001903604727400391}, -{0.0004992625165376107,0.0008598969867484128,-0.008521087756729117,0.99453086623794,0.0179104136912176,-0.006922416132556366,0.002400347599485495,0}}; +#include "srslte/phy/utils/vector.h" -// TODO: use lte/utils/vector.h and Volk -cf_t srslte_resample_arb_dot_prod(cf_t* x, float *y, int len) -{ - cf_t res = 0+0*I; - for(int i=0;ireg[1], &q->reg[0], (SRSLTE_RESAMPLE_ARB_M-1)*sizeof(cf_t)); q->reg[0] = x; } // Initialize our struct -void srslte_resample_arb_init(srslte_resample_arb_t *q, float rate){ +void srslte_resample_arb_init(srslte_resample_arb_t *q, float rate, bool interpolate){ + memset(q->reg, 0, SRSLTE_RESAMPLE_ARB_M*sizeof(cf_t)); q->acc = 0.0; q->rate = rate; + q->interpolate = interpolate; q->step = (1/rate)*SRSLTE_RESAMPLE_ARB_N; } @@ -94,19 +134,48 @@ int srslte_resample_arb_compute(srslte_resample_arb_t *q, cf_t *input, cf_t *out int cnt = 0; int n_out = 0; int idx = 0; + cf_t res1,res2; + cf_t *filter_input; + float frac = 0; + memset(q->reg, 0, SRSLTE_RESAMPLE_ARB_M*sizeof(cf_t)); + + while (cnt < n_in) { + + if(cntreg[SRSLTE_RESAMPLE_ARB_M - cnt], input, (cnt)*sizeof(cf_t)); + filter_input = q->reg; + } else{ + filter_input = &input[cnt-SRSLTE_RESAMPLE_ARB_M]; + } + + res1 = srslte_resample_arb_dot_prod(filter_input, srslte_resample_arb_polyfilt[idx], SRSLTE_RESAMPLE_ARB_M); + if(q->interpolate){ + res2 = srslte_resample_arb_dot_prod(filter_input, srslte_resample_arb_polyfilt[(idx%SRSLTE_RESAMPLE_ARB_N)+1], SRSLTE_RESAMPLE_ARB_M); + } - while(cnt < n_in) - { - *output = srslte_resample_arb_dot_prod(q->reg, srslte_resample_arb_polyfilt[idx], SRSLTE_RESAMPLE_ARB_M); + if(idx == SRSLTE_RESAMPLE_ARB_N){ + *output = res1; + }else { + *output = (q->interpolate)?(res1 + (res2-res1)*frac):res1; + } + output++; n_out++; q->acc += q->step; - idx = (int)roundf(q->acc); + idx = (int)(q->acc); + while(idx >= SRSLTE_RESAMPLE_ARB_N){ q->acc -= SRSLTE_RESAMPLE_ARB_N; idx -= SRSLTE_RESAMPLE_ARB_N; - if(cnt < n_in) - srslte_resample_arb_push(q, input[cnt++]); + if(cnt < n_in){ + cnt++; + } + } + + if(q->interpolate){ + frac = q->acc - idx; + if(frac < 0) + frac = frac*(-1); } } return n_out; diff --git a/lib/src/phy/resampling/test/resample_arb_bench.c b/lib/src/phy/resampling/test/resample_arb_bench.c index 48879d036..773291913 100644 --- a/lib/src/phy/resampling/test/resample_arb_bench.c +++ b/lib/src/phy/resampling/test/resample_arb_bench.c @@ -35,9 +35,9 @@ #include "srslte/phy/resampling/resample_arb.h" - +#define ITERATIONS 10000 int main(int argc, char **argv) { - int N=10000000; + int N=9000; float rate = 24.0/25.0; cf_t *in = malloc(N*sizeof(cf_t)); cf_t *out = malloc(N*sizeof(cf_t)); @@ -46,12 +46,15 @@ int main(int argc, char **argv) { in[i] = sin(i*2*M_PI/100); srslte_resample_arb_t r; - srslte_resample_arb_init(&r, rate); + srslte_resample_arb_init(&r, rate, 0); clock_t start = clock(), diff; - //int n_out = srslte_resample_arb_compute(&r, in, out, N); + for(int xx = 0; xx diff && pre != post){ - printf("Interpolation failed at index %f", idx); + printf("Interpolation failed at index %f\n", idx); exit(-1); } } - free(in); free(out); } diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 18c5b01cd..90ede26e9 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -38,6 +38,7 @@ #include typedef struct { + char *devname; SoapySDRKwargs args; SoapySDRDevice *device; SoapySDRRange *ranges; @@ -51,7 +52,6 @@ typedef struct { cf_t zero_mem[64*1024]; - int soapy_error(void *h) { return 0; @@ -90,7 +90,8 @@ void rf_soapy_register_error_handler(void *notused, srslte_rf_error_handler_t ne char* rf_soapy_devname(void* h) { - return "soapy"; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + return handler->devname; } @@ -196,11 +197,15 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) printf("No Soapy devices found.\n"); return SRSLTE_ERROR; } - + char* devname; for (size_t i = 0; i < length; i++) { printf("Soapy has Found device #%d: ", (int)i); for (size_t j = 0; j < soapy_args[i].size; j++) { printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]); + if(!strcmp(soapy_args[i].keys[j],"name") && !strcmp(soapy_args[i].vals[j], "LimeSDR-USB")){ + devname = DEVNAME_LIME; + + } } printf("\n"); } @@ -218,7 +223,7 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) handler->device = sdr; handler->tx_stream_active = false; handler->rx_stream_active = false; - + handler->devname = devname; if(SoapySDRDevice_getNumChannels(handler->device,SOAPY_SDR_RX) > 0){ printf("setting up RX stream\n"); if(SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { @@ -234,6 +239,14 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) return SRSLTE_ERROR; } } + size_t sensor_length; + char** sensors; + sensors = SoapySDRDevice_listSensors(handler->device, &sensor_length); + for(int i = 0; i < sensor_length;i++) + { + printf("available sensors are : \n"); + puts(sensors[i]); + } return SRSLTE_SUCCESS; } @@ -267,7 +280,7 @@ int rf_soapy_close(void *h) void rf_soapy_set_master_clock_rate(void *h, double rate) { // Allow the soapy to automatically set the appropriate clock rate - // TODO: implement this function + } @@ -285,7 +298,6 @@ double rf_soapy_set_rx_srate(void *h, double rate) printf("setSampleRate Rx fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } - return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0); } @@ -296,7 +308,6 @@ double rf_soapy_set_tx_srate(void *h, double rate) printf("setSampleRate Tx fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } - return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); } diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index 19de4536c..5dd1c6c44 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -28,7 +28,7 @@ #include #include "srslte/config.h" #include "srslte/phy/rf/rf.h" - +#define DEVNAME_LIME "lime" SRSLTE_API int rf_soapy_open(char *args, void **handler); diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 42d4143f9..dc84ad921 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -59,6 +59,7 @@ bool radio::init(char *args, char *devname) } else if (strstr(srslte_rf_name(&rf_device), "bladerf")) { burst_preamble_sec = blade_default_burst_preamble_sec; } else { + burst_preamble_sec = 0; printf("\nWarning burst preamble is not calibrated for device %s. Set a value manually\n\n", srslte_rf_name(&rf_device)); } @@ -329,11 +330,10 @@ void radio::set_tx_srate(double srate) } burst_preamble_time_rounded = (double) burst_preamble_samples/cur_tx_srate; - int nsamples=0; /* Set time advance for each known device if in auto mode */ if (tx_adv_auto) { - + /* This values have been calibrated using the prach_test_usrp tool in srsLTE */ if (!strcmp(srslte_rf_name(&rf_device), "uhd_b200")) { @@ -355,7 +355,48 @@ void radio::set_tx_srate(double srate) /* Interpolate from known values */ printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate); nsamples = cur_tx_srate*(uhd_default_tx_adv_samples * (1/cur_tx_srate) + uhd_default_tx_adv_offset_sec); - } + } + + }else if(!strcmp(srslte_rf_name(&rf_device), "uhd_usrp2")) { + double srate_khz = round(cur_tx_srate/1e3); + if (srate_khz == 1.92e3) { + nsamples = 14;// estimated + } else if (srate_khz == 3.84e3) { + nsamples = 32; + } else if (srate_khz == 5.76e3) { + nsamples = 43; + } else if (srate_khz == 11.52e3) { + nsamples = 54; + } else if (srate_khz == 15.36e3) { + nsamples = 65;// to calc + } else if (srate_khz == 23.04e3) { + nsamples = 80; // to calc + } else { + /* Interpolate from known values */ + printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate); + nsamples = cur_tx_srate*(uhd_default_tx_adv_samples * (1/cur_tx_srate) + uhd_default_tx_adv_offset_sec); + } + + } else if(!strcmp(srslte_rf_name(&rf_device), "lime")) { + double srate_khz = round(cur_tx_srate/1e3); + if (srate_khz == 1.92e3) { + nsamples = 70;// estimated + } else if (srate_khz == 3.84e3) { + nsamples = 76;//estimated + } else if (srate_khz == 5.76e3) { + nsamples = 76; + } else if (srate_khz == 11.52e3) { + nsamples = 76; + } else if (srate_khz == 15.36e3) { + nsamples = 73; + } else if (srate_khz == 23.04e3) { + nsamples = 87; + } else { + /* Interpolate from known values */ + printf("\nWarning TX/RX time offset for sampling rate %.0f KHz not calibrated. Using interpolated value\n\n", cur_tx_srate); + nsamples = cur_tx_srate*(uhd_default_tx_adv_samples * (1/cur_tx_srate) + uhd_default_tx_adv_offset_sec); + } + } else if (!strcmp(srslte_rf_name(&rf_device), "uhd_x300")) { // In X300 TX/RX offset is independent of sampling rate From 646f949d7706ddefcb425a99cdbf812029b29b87 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Wed, 8 Nov 2017 16:19:32 +0000 Subject: [PATCH 2/2] Fix for debug inline issue --- lib/src/phy/resampling/resample_arb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/resampling/resample_arb.c b/lib/src/phy/resampling/resample_arb.c index 2b04f587c..441e8c0dc 100644 --- a/lib/src/phy/resampling/resample_arb.c +++ b/lib/src/phy/resampling/resample_arb.c @@ -106,7 +106,7 @@ float srslte_resample_arb_polyfilt[SRSLTE_RESAMPLE_ARB_N][SRSLTE_RESAMPLE_ARB_M] {0.000764085430796, -0.030612377229395, 0.154765509342932, 0.702921418438421, 0.206204344739138, -0.034615802155152, 0.000568080243211, 0.000003596427925}, {0.000722236729272, -0.032053439082436, 0.171322660416961, 0.704261032406613, 0.188481383863832, -0.033395686652146, 0.000657994314549 , 0.000002955485215}}; -inline cf_t srslte_resample_arb_dot_prod(cf_t* x, float *y, int len){ +static inline cf_t srslte_resample_arb_dot_prod(cf_t* x, float *y, int len){ cf_t res1 = srslte_vec_dot_prod_cfc(x,y,len); return res1;