diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 74d7a885a..484b412ae 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -32,54 +32,56 @@ #include "srslte/srslte.h" #include "rf_soapy_imp.h" -#include "srslte/rf/rf.h" +#include "srslte/phy/rf/rf.h" #include #include -//#include "lime/LimeSuite.h" typedef struct { - - SoapySDRKwargs args; - SoapySDRDevice *device; - SoapySDRRange *ranges; - - SoapySDRStream *rxStream; - SoapySDRStream *txStream; - - + SoapySDRKwargs args; + SoapySDRDevice *device; + SoapySDRRange *ranges; + SoapySDRStream *rxStream; + SoapySDRStream *txStream; + bool tx_stream_active; } rf_soapy_handler_t; + cf_t zero_mem[64*1024]; int soapy_error(void *h) { - + return 0; } + void rf_soapy_get_freq_range(void *h) { - + } + void rf_soapy_suppress_handler(const char *x) { - // not supported + // not supported } + void rf_soapy_msg_handler(const char *msg) { - // not supported + // not supported } + void rf_soapy_suppress_stdout(void *h) { - // not supported + // not supported } + void rf_soapy_register_error_handler(void *notused, srslte_rf_error_handler_t new_handler) { - // not supported + // not supported } static bool isLocked(rf_soapy_handler_t *handler, char *sensor_name, void *value_h) @@ -88,348 +90,336 @@ static bool isLocked(rf_soapy_handler_t *handler, char *sensor_name, void *value return true; } + char* rf_soapy_devname(void* h) { - + return "soapy"; } bool rf_soapy_rx_wait_lo_locked(void *h) { - // not supported + printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n"); return true; } + void rf_soapy_set_tx_cal(void *h, srslte_rf_cal_t *cal) { + printf("TODO: implement rf_soapy_rx_wait_lo_locked()\n"); // not supported } -void rf_soapy_set_rx_cal(void *h, srslte_rf_cal_t *cal) + +void rf_soapy_set_rx_cal(void *h, srslte_rf_cal_t *cal) { - // not supported + printf("TODO: implement rf_soapy_set_rx_cal()\n"); } + int rf_soapy_start_rx_stream(void *h) { - //printf("starting SOAPY rx stream \n"); - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if(SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0)!=0)//start streaming - return SRSLTE_ERROR; - - - return SRSLTE_SUCCESS; + if (SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0) != 0) + return SRSLTE_ERROR; + + return SRSLTE_SUCCESS; } int rf_soapy_start_tx_stream(void *h) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if(SoapySDRDevice_activateStream(handler->device, handler->txStream, 0, 0, 0) != 0) - return SRSLTE_ERROR; - - - return SRSLTE_SUCCESS; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { + printf("setupStream fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + + if(SoapySDRDevice_activateStream(handler->device, handler->txStream, 0, 0, 0) != 0) + return SRSLTE_ERROR; + + return SRSLTE_SUCCESS; } + int rf_soapy_stop_rx_stream(void *h) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if(SoapySDRDevice_deactivateStream(handler->device, handler->rxStream, 0, 0) != 0) - return SRSLTE_ERROR; - - - - return SRSLTE_SUCCESS; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_deactivateStream(handler->device, handler->rxStream, 0, 0) != 0) + return SRSLTE_ERROR; + + return SRSLTE_SUCCESS; } + + int rf_soapy_stop_tx_stream(void *h) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - - if(SoapySDRDevice_deactivateStream(handler->device, handler->txStream, 0, 0) != 0) - return SRSLTE_ERROR; - - - - return SRSLTE_SUCCESS; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if(SoapySDRDevice_deactivateStream(handler->device, handler->txStream, 0, 0) != 0) + return SRSLTE_ERROR; + + return SRSLTE_SUCCESS; } + void rf_soapy_flush_buffer(void *h) { - int n; + int n; cf_t tmp1[1024]; cf_t tmp2[1024]; void *data[2] = {tmp1, tmp2}; do { n = rf_soapy_recv_with_time_multi(h, data, 1024, 0, NULL, NULL); - } while (n > 0); + } while (n > 0); } + bool rf_soapy_has_rssi(void *h) { - + printf("TODO: implement rf_soapy_has_rssi()\n"); + return false; } + float rf_soapy_get_rssi(void *h) { - + printf("TODO: implement rf_soapy_get_rssi()\n"); + return 0.0; } + //TODO: add multi-channel support int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) -{//SoapySDRKwargs soapy_args = {}; - size_t length; - const SoapySDRKwargs *soapy_args = SoapySDRDevice_enumerate(NULL, &length); - - if(length == 0) +{ + size_t length; + const SoapySDRKwargs *soapy_args = SoapySDRDevice_enumerate(NULL, &length); + + if (length == 0) { + printf("No Soapy devices found.\n"); + return SRSLTE_ERROR; + } + + 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++) { - return SRSLTE_ERROR; + printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]); } - - 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]); - } - printf("\n"); - } - - // SoapySDRrgs_set(&soapy_args, "driver", "rtlsdr"); - SoapySDRDevice *sdr = SoapySDRDevice_make(&(soapy_args[0])); - - if(sdr == NULL) - { - printf("failed to create SOAPY object\n"); - return SRSLTE_ERROR; - - } - - //SoapySDRKwargs_clear(&soapy_args); - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) malloc(sizeof(rf_soapy_handler_t)); - *h = handler; - handler->device = sdr; - - - - //size_t channels[1]; - //channels[0] = 0; - - if (SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) - { - printf("setupStream fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - - if (SoapySDRDevice_setupStream(handler->device, &(handler->txStream), SOAPY_SDR_TX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) - { - printf("setupStream fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - - - - return SRSLTE_SUCCESS; - + printf("\n"); + } + + SoapySDRDevice *sdr = SoapySDRDevice_make(&(soapy_args[0])); + if (sdr == NULL) { + printf("failed to create SOAPY object\n"); + return SRSLTE_ERROR; + } + + // create handler + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) malloc(sizeof(rf_soapy_handler_t)); + bzero(handler, sizeof(rf_soapy_handler_t)); + *h = handler; + handler->device = sdr; + handler->tx_stream_active = false; + if (SoapySDRDevice_setupStream(handler->device, &(handler->rxStream), SOAPY_SDR_RX, SOAPY_SDR_CF32, NULL, 0, NULL) != 0) { + printf("setupStream fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + + return SRSLTE_SUCCESS; } + int rf_soapy_open(char *args, void **h) { - return rf_soapy_open_multi(args, h, 1); + return rf_soapy_open_multi(args, h, 1); } int rf_soapy_close(void *h) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - SoapySDRDevice_closeStream(handler->device, handler->txStream); - SoapySDRDevice_closeStream(handler->device, handler->rxStream); - SoapySDRDevice_unmake(handler->device); + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (handler->txStream) { + rf_soapy_stop_tx_stream(handler); + SoapySDRDevice_closeStream(handler->device, handler->txStream); + } + + if (handler->rxStream) { + rf_soapy_stop_rx_stream(handler); + SoapySDRDevice_closeStream(handler->device, handler->rxStream); + } + + SoapySDRDevice_unmake(handler->device); + free(handler); + + return SRSLTE_SUCCESS; } void rf_soapy_set_master_clock_rate(void *h, double rate) { // Allow the soapy to automatically set the appropriate clock rate - - printf("SET MASTER CLOCK RATE\n"); + // TODO: implement this function } -bool rf_soapy_is_master_clock_dynamic(void *h) + +bool rf_soapy_is_master_clock_dynamic(void *h) { - + printf("TODO: implement rf_soapy_is_master_clock_dynamic()\n"); + return false; } + double rf_soapy_set_rx_srate(void *h, double rate) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - SoapySDRRange range = SoapySDRDevice_getGainRange(handler->device, SOAPY_SDR_RX,0); - printf("rx min gain is %f \n",range.minimum); - printf("rx max gain is %f \n",range.maximum); - if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_RX, 0, rate) != 0) - { - printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - - double ret = SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0); - printf("Sampling rate is set to %f : \n",ret); - return ret; + 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()); + return SRSLTE_ERROR; + } + return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_RX,0); } double rf_soapy_set_tx_srate(void *h, double rate) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - SoapySDRRange range = SoapySDRDevice_getGainRange(handler->device, SOAPY_SDR_TX,0); - printf("tx min gain is %f \n",range.minimum); - printf("tx max gain is %f \n",range.maximum); - - if (SoapySDRDevice_setSampleRate(handler->device, SOAPY_SDR_TX, 0, rate) != 0) - { - printf("setSampleRate fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - double ret = SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); - printf("Sampling rate is set to %f : \n",ret); - return ret; + 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()); + return SRSLTE_ERROR; + } + return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); } + double rf_soapy_set_rx_gain(void *h, double gain) { - - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_RX, 0, gain) != 0) - { - printf("setGain fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - double ret = rf_soapy_get_rx_gain(h); - printf("gain has been set to %f \n",ret); - return ret; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_RX, 0, gain) != 0) + { + printf("setGain fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return rf_soapy_get_rx_gain(h); } + double rf_soapy_set_tx_gain(void *h, double gain) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_TX, 0, gain) != 0) - { - printf("setGain fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - double ret = rf_soapy_get_tx_gain(h); - printf("gain has been set to %f \n",ret); - return ret; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_setGain(handler->device, SOAPY_SDR_TX, 0, gain) != 0) + { + printf("setGain fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return rf_soapy_get_tx_gain(h); } + double rf_soapy_get_rx_gain(void *h) { - - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_RX,0); - + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_RX,0); } + double rf_soapy_get_tx_gain(void *h) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_TX,0); + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + return SoapySDRDevice_getGain(handler->device,SOAPY_SDR_TX,0); } + double rf_soapy_set_rx_freq(void *h, double freq) { - - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if (SoapySDRDevice_setFrequency(handler->device, SOAPY_SDR_RX, 0, freq, NULL) != 0) - { - printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - double ret = SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0); - printf("Frequency has been set to %f : \n",ret); - return ret; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_setFrequency(handler->device, SOAPY_SDR_RX, 0, freq, NULL) != 0) + { + printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0); } double rf_soapy_set_tx_freq(void *h, double freq) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - if (SoapySDRDevice_setFrequency(handler->device, SOAPY_SDR_TX, 0, freq, NULL) != 0) - { - printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); - return SRSLTE_ERROR; - } - double ret = SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0); - printf("Frequency has been set to %f : \n",ret); - return ret; - + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + if (SoapySDRDevice_setFrequency(handler->device, SOAPY_SDR_TX, 0, freq, NULL) != 0) + { + printf("setFrequency fail: %s\n", SoapySDRDevice_lastError()); + return SRSLTE_ERROR; + } + return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_TX, 0); } 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, - uint32_t nsamples, - bool blocking, - time_t *secs, - double *frac_secs) + void **data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - //void *buffs[] = {buff}; //array of buffers - - int flags; //flags set by receive operation - - int num_channels = 1; // temp - - int trials = 0; - int ret = 0; - long long timeNs; //timestamp for receive buffer - int n = 0; - do{ - - size_t rx_samples = nsamples; - - if (rx_samples > nsamples - n) - { - rx_samples = nsamples - n; - } - void *buffs_ptr[4]; - for (int i=0;idevice, handler->rxStream, buffs_ptr , rx_samples, &flags, &timeNs, 1000000); - - if(ret < 0) - return SRSLTE_ERROR; - 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; + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + //void *buffs[] = {buff}; //array of buffers + + int flags; //flags set by receive operation + + int num_channels = 1; // temp + + int trials = 0; + int ret = 0; + long long timeNs; //timestamp for receive buffer + int n = 0; + do { + size_t rx_samples = nsamples; - + if (rx_samples > nsamples - n) + { + rx_samples = nsamples - n; + } + void *buffs_ptr[4]; + for (int i=0; idevice, handler->rxStream, buffs_ptr , rx_samples, &flags, &timeNs, 1000000); + if(ret < 0) { + // continue when getting overflows + if (ret == SOAPY_SDR_OVERFLOW) { + fprintf(stderr, "O"); + fflush(stderr); + continue; + } else { + return SRSLTE_ERROR; + } + } + + 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, - bool blocking, - time_t *secs, - double *frac_secs) + void *data, + uint32_t nsamples, + bool blocking, + time_t *secs, + double *frac_secs) { - return rf_soapy_recv_with_time_multi(h, &data, nsamples, blocking, secs, frac_secs); + return rf_soapy_recv_with_time_multi(h, &data, nsamples, blocking, secs, frac_secs); } - + int rf_soapy_send_timed(void *h, void *data, @@ -444,27 +434,33 @@ int rf_soapy_send_timed(void *h, int flags; long long timeNs; - int trials = 0; - int ret = 0; + 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 num_channels = 1; - int n = 0; + int num_channels = 1; + 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; - } - 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++; + 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); @@ -476,7 +472,3 @@ int rf_soapy_send_timed(void *h, return ret; } - - - -