From 81b143715b0b0bb5e7f3f22b31f0f0c5bd43e411 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 4 Oct 2017 16:17:44 +0200 Subject: [PATCH 1/5] fix formating --- lib/src/phy/rf/rf_soapy_imp.c | 95 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 31649af69..084308116 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -88,12 +88,12 @@ void rf_soapy_register_error_handler(void *notused, srslte_rf_error_handler_t ne } - char* rf_soapy_devname(void* h) { return "soapy"; } + bool rf_soapy_rx_wait_lo_locked(void *h) { printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n"); @@ -155,7 +155,6 @@ int rf_soapy_stop_tx_stream(void *h) if(SoapySDRDevice_deactivateStream(handler->device, handler->txStream, 0, 0) != 0) return SRSLTE_ERROR; - handler->tx_stream_active = false; return SRSLTE_SUCCESS; } @@ -199,9 +198,8 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) } 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("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]); } printf("\n"); @@ -221,7 +219,6 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) handler->tx_stream_active = false; handler->rx_stream_active = false; - 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) { @@ -364,7 +361,8 @@ double rf_soapy_set_tx_freq(void *h, double freq) } -void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs) { +void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs) +{ } @@ -430,49 +428,46 @@ int rf_soapy_recv_with_time(void *h, int rf_soapy_send_timed(void *h, - void *data, - int nsamples, - time_t secs, - double frac_secs, - bool has_time_spec, - bool blocking, - bool is_start_of_burst, - bool is_end_of_burst) -{ - - int flags; - long long timeNs; - int trials = 0; - int ret = 0; - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - timeNs = secs * 1000000000; - timeNs = timeNs + (frac_secs * 1000000000); - int n = 0; - - if(!handler->tx_stream_active){ - rf_soapy_start_tx_stream(h); + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst) +{ + int flags; + long long timeNs; + int trials = 0; + int ret = 0; + rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h; + timeNs = secs * 1000000000; + timeNs = timeNs + (frac_secs * 1000000000); + int n = 0; + + if (!handler->tx_stream_active) { + rf_soapy_start_tx_stream(h); + } + + cf_t *data_c = (cf_t *) data; + do { + size_t tx_samples = nsamples; + if (tx_samples > nsamples - n) { + tx_samples = nsamples - n; } - - - cf_t *data_c = (cf_t*) data; - do{ - size_t tx_samples = nsamples; - if (tx_samples > nsamples - n) { - tx_samples = nsamples - n; - } - void *buff = (void*) &data_c[n]; - const void *buffs_ptr[1] = {buff}; - ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, buffs_ptr, tx_samples, &flags, timeNs, 10000); - if(ret < 0) - return SRSLTE_ERROR; - - n += ret; - trials++; - }while (n < nsamples && trials < 100); - - if(ret != nsamples) - return SRSLTE_ERROR; - - return ret; + void *buff = (void *) &data_c[n]; + const void *buffs_ptr[1] = {buff}; + ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, buffs_ptr, tx_samples, &flags, timeNs, 10000); + if (ret < 0) + return SRSLTE_ERROR; + + n += ret; + trials++; + } while (n < nsamples && trials < 100); + + if (ret != nsamples) + return SRSLTE_ERROR; + return ret; } From df2bbd40871be545f151cf3e1a382f691d56c3bf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 5 Oct 2017 16:26:23 +0200 Subject: [PATCH 2/5] fix multi channel tx support in soapy --- lib/src/phy/rf/rf_dev.h | 2 +- lib/src/phy/rf/rf_soapy_imp.c | 129 ++++++++++++++++++++++++++++------ lib/src/phy/rf/rf_soapy_imp.h | 11 ++- 3 files changed, 117 insertions(+), 25 deletions(-) diff --git a/lib/src/phy/rf/rf_dev.h b/lib/src/phy/rf/rf_dev.h index 00f157b6b..d41adbeed 100644 --- a/lib/src/phy/rf/rf_dev.h +++ b/lib/src/phy/rf/rf_dev.h @@ -177,7 +177,7 @@ static rf_dev_t dev_soapy = { rf_soapy_recv_with_time, rf_soapy_recv_with_time_multi, rf_soapy_send_timed, - .srslte_rf_send_timed_multi = /* FIXME: Implement srslte_rf_send_timed_multi for Soapy SDR */ NULL, + .srslte_rf_send_timed_multi = rf_soapy_send_timed_multi, rf_soapy_set_tx_cal, rf_soapy_set_rx_cal }; diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 084308116..0eaf34c32 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -248,12 +248,12 @@ int rf_soapy_open(char *args, void **h) int rf_soapy_close(void *h) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if (handler->txStream) { + if (handler->tx_stream_active) { rf_soapy_stop_tx_stream(handler); SoapySDRDevice_closeStream(handler->device, handler->txStream); } - if (handler->rxStream) { + if (handler->rx_stream_active) { rf_soapy_stop_rx_stream(handler); SoapySDRDevice_closeStream(handler->device, handler->rxStream); } @@ -285,6 +285,12 @@ double rf_soapy_set_rx_srate(void *h, double rate) printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } + + if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_RX, 0, rate) != 0) { + printf("setBandwidth failed: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0); } @@ -295,6 +301,12 @@ double rf_soapy_set_tx_srate(void *h, double rate) printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } + + if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_TX, 0, rate) != 0) { + printf("setBandwidth failed: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); } @@ -345,7 +357,15 @@ double rf_soapy_set_rx_freq(void *h, double freq) printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } - + + // Todo: expose antenna setting + if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_RX, 0, "LNAH") != 0) { + fprintf(stderr, "Failed to set Rx antenna.\n"); + } + + char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_RX, 0); + printf("Rx antenna set to %s\n", ant); + return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0); } @@ -357,6 +377,16 @@ double rf_soapy_set_tx_freq(void *h, double freq) printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } + + // Todo: expose antenna name in arguments + if (SoapySDRDevice_setAntenna(handler->device, SOAPY_SDR_TX, 0, "BAND1") != 0) { + fprintf(stderr, "Failed to set Tx antenna.\n"); + } + + + char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_TX, 0); + printf("Tx antenna set to %s\n", ant); + return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0); } @@ -366,6 +396,7 @@ void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs) } + //TODO: add multi-channel support int rf_soapy_recv_with_time_multi(void *h, void **data, @@ -405,17 +436,22 @@ int rf_soapy_recv_with_time_multi(void *h, } } +#if 0 + *secs = timeNs / 1000000000; + *frac_secs = (timeNs % 1000000000)/1000000000; + printf("ret=%d, flags=%d, timeNs=%lld\n", ret, flags, timeNs); +#endif + n += ret; trials++; } while (n < nsamples && trials < 100); - //*secs = timeNs / 1000000000; - //*frac_secs = (timeNs % 1000000000)/1000000000; - // printf("ret=%d, flags=%d, timeNs=%lld\n", ret, flags, timeNs); + return n; } + int rf_soapy_recv_with_time(void *h, void *data, uint32_t nsamples, @@ -428,19 +464,37 @@ int rf_soapy_recv_with_time(void *h, int rf_soapy_send_timed(void *h, - void *data, - int nsamples, - time_t secs, - double frac_secs, - bool has_time_spec, - bool blocking, - bool is_start_of_burst, - bool is_end_of_burst) -{ - int flags; + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst) +{ + void *_data[SRSLTE_MAX_PORTS]= {data, zero_mem, zero_mem, zero_mem}; + return rf_soapy_send_timed_multi(h, _data, nsamples, secs, frac_secs, has_time_spec, blocking, is_start_of_burst, is_end_of_burst); +} + + +// Todo: Check correct handling of flags, use RF metrics API, fix timed transmissions +int rf_soapy_send_timed_multi(void *h, + void *data[SRSLTE_MAX_PORTS], + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst) +{ + int flags = 0; + const long timeoutUs = 2000; // arbitrarily chosen long long timeNs; int trials = 0; int ret = 0; + rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h; timeNs = secs * 1000000000; timeNs = timeNs + (frac_secs * 1000000000); @@ -449,25 +503,54 @@ int rf_soapy_send_timed(void *h, if (!handler->tx_stream_active) { rf_soapy_start_tx_stream(h); } - - cf_t *data_c = (cf_t *) data; + + //printf("send_timed_multi(): time_spec=%d blocking=%d, is_start_of_burst=%d is_end_of_burst=%d\n", has_time_spec, blocking, is_start_of_burst, is_end_of_burst); + + if (is_start_of_burst && is_end_of_burst) { + flags |= SOAPY_SDR_ONE_PACKET; + } + + if (is_end_of_burst) { + flags |= SOAPY_SDR_END_BURST; + } + + if (has_time_spec) { + flags |= SOAPY_SDR_HAS_TIME; + } + do { size_t tx_samples = nsamples; if (tx_samples > nsamples - n) { tx_samples = nsamples - n; } - void *buff = (void *) &data_c[n]; - const void *buffs_ptr[1] = {buff}; - ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, buffs_ptr, tx_samples, &flags, timeNs, 10000); - if (ret < 0) + + ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, (const void *)data, tx_samples, &flags, timeNs, timeoutUs); + if (ret == SOAPY_SDR_TIMEOUT) { + printf("L"); + continue; + } + if (ret == SOAPY_SDR_OVERFLOW) { + printf("O"); + continue; + } + if (ret == SOAPY_SDR_UNDERFLOW) { + printf("U"); + continue; + } + if (ret < 0) { + fprintf(stderr, "Error during writeStream\n"); + exit(-1); return SRSLTE_ERROR; + } n += ret; trials++; } while (n < nsamples && trials < 100); - if (ret != nsamples) + if (n != nsamples) { + fprintf(stderr, "Couldn't write all samples.\n"); return SRSLTE_ERROR; + } return ret; } diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index 23b59a8b3..19de4536c 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -106,7 +106,7 @@ SRSLTE_API void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs); -SRSLTE_API int rf_soapy_send_timed(void *h, +SRSLTE_API int rf_soapy_send_timed(void *h, void *data, int nsamples, time_t secs, @@ -116,3 +116,12 @@ SRSLTE_API int rf_soapy_send_timed(void *h, bool is_start_of_burst, bool is_end_of_burst); +int rf_soapy_send_timed_multi(void *h, + void *data[4], + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst); From 5bd92fb6581d5294a65c87803adcacff6e533b27 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 6 Oct 2017 10:30:58 +0200 Subject: [PATCH 3/5] fix prach example and close rf at exit --- lib/src/phy/phch/test/prach_test_usrp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/test/prach_test_usrp.c b/lib/src/phy/phch/test/prach_test_usrp.c index 2defdec4f..c0fae365c 100644 --- a/lib/src/phy/phch/test/prach_test_usrp.c +++ b/lib/src/phy/phch/test/prach_test_usrp.c @@ -231,7 +231,8 @@ int main(int argc, char **argv) { } srslte_vec_save_file(output_filename,buffer,11*flen*sizeof(cf_t)); - + + srslte_rf_close(&rf); srslte_prach_free(p); free(p); From f619f53cc460df6230b69e2598550b190720f1d6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 6 Oct 2017 10:40:59 +0200 Subject: [PATCH 4/5] fix soapy support --- lib/src/phy/rf/rf_soapy_imp.c | 36 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 0eaf34c32..e1b451412 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -174,7 +174,7 @@ void rf_soapy_flush_buffer(void *h) bool rf_soapy_has_rssi(void *h) { - printf("TODO: implement rf_soapy_has_rssi()\n"); + // TODO: implement rf_soapy_has_rssi() return false; } @@ -282,12 +282,12 @@ double rf_soapy_set_rx_srate(void *h, double rate) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0) { - printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); + printf("setSampleRate Rx fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_RX, 0, rate) != 0) { - printf("setBandwidth failed: %s\n", SoapySDRDevice_lastError()); + printf("setBandwidth Rx failed: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } @@ -298,12 +298,12 @@ double rf_soapy_set_tx_srate(void *h, double rate) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0) { - printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); + printf("setSampleRate Tx fail: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } if (SoapySDRDevice_setBandwidth(handler->device, SOAPY_SDR_TX, 0, rate) != 0) { - printf("setBandwidth failed: %s\n", SoapySDRDevice_lastError()); + printf("setBandwidth Tx failed: %s\n", SoapySDRDevice_lastError()); return SRSLTE_ERROR; } @@ -393,7 +393,7 @@ double rf_soapy_set_tx_freq(void *h, double freq) void rf_soapy_get_time(void *h, time_t *secs, double *frac_secs) { - + printf("Todo: implement rf_soapy_get_time()\n"); } @@ -424,7 +424,7 @@ int rf_soapy_recv_with_time_multi(void *h, cf_t *data_c = (cf_t*) data[i]; buffs_ptr[i] = &data_c[n]; } - ret = SoapySDRDevice_readStream(handler->device, handler->rxStream, buffs_ptr , rx_samples, &flags, &timeNs, 1000000); + ret = SoapySDRDevice_readStream(handler->device, handler->rxStream, buffs_ptr, rx_samples, &flags, &timeNs, 10000); if(ret < 0) { // continue when getting overflows if (ret == SOAPY_SDR_OVERFLOW) { @@ -436,11 +436,12 @@ int rf_soapy_recv_with_time_multi(void *h, } } -#if 0 - *secs = timeNs / 1000000000; - *frac_secs = (timeNs % 1000000000)/1000000000; - printf("ret=%d, flags=%d, timeNs=%lld\n", ret, flags, timeNs); -#endif + // update rx time + if (secs != NULL && frac_secs != NULL) { + *secs = timeNs / 1e9; + *frac_secs = (timeNs % 1000000000)/1e9; + //printf("rx_time: secs=%d, frac_secs=%lf timeNs=%lld\n", *secs, *frac_secs, timeNs); + } n += ret; trials++; @@ -489,23 +490,19 @@ int rf_soapy_send_timed_multi(void *h, bool is_start_of_burst, bool is_end_of_burst) { + rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h; int flags = 0; const long timeoutUs = 2000; // arbitrarily chosen long long timeNs; int trials = 0; int ret = 0; - - rf_soapy_handler_t *handler = (rf_soapy_handler_t *) h; - timeNs = secs * 1000000000; - timeNs = timeNs + (frac_secs * 1000000000); int n = 0; + if (!handler->tx_stream_active) { rf_soapy_start_tx_stream(h); } - //printf("send_timed_multi(): time_spec=%d blocking=%d, is_start_of_burst=%d is_end_of_burst=%d\n", has_time_spec, blocking, is_start_of_burst, is_end_of_burst); - if (is_start_of_burst && is_end_of_burst) { flags |= SOAPY_SDR_ONE_PACKET; } @@ -516,6 +513,9 @@ int rf_soapy_send_timed_multi(void *h, if (has_time_spec) { flags |= SOAPY_SDR_HAS_TIME; + timeNs = secs * 1000000000; + timeNs = timeNs + (frac_secs * 1000000000); + //printf("time_spec: secs=%d, frac_secs=%lf timeNs=%lld\n", secs, frac_secs, timeNs); } do { From 5d5e8167b7e4b5dd7ea08a952d37fd77f314a8f8 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 6 Oct 2017 15:04:17 +0200 Subject: [PATCH 5/5] stop radio after radio error --- lib/src/phy/rf/rf_soapy_imp.c | 1 - srsue/src/phy/phch_recv.cc | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index e1b451412..ee646c2c2 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -383,7 +383,6 @@ double rf_soapy_set_tx_freq(void *h, double freq) fprintf(stderr, "Failed to set Tx antenna.\n"); } - char *ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_TX, 0); printf("Tx antenna set to %s\n", ant); diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index dad2c82b8..718b15b81 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -171,6 +171,7 @@ void phch_recv::radio_error() { // Need to find a method to effectively reset radio, reloading the driver does not work //radio_h->reset(); + radio_h->stop(); fprintf(stdout, "Error while receiving samples. Restart srsUE\n"); exit(-1);