diff --git a/lib/examples/pdsch_enodeb.c b/lib/examples/pdsch_enodeb.c index 800e04de9..db288ae1c 100644 --- a/lib/examples/pdsch_enodeb.c +++ b/lib/examples/pdsch_enodeb.c @@ -510,7 +510,7 @@ int main(int argc, char **argv) { sigaddset(&sigset, SIGINT); sigprocmask(SIG_UNBLOCK, &sigset, NULL); signal(SIGINT, sig_int_handler); - + if (!output_file_name) { int srate = srslte_sampling_freq_hz(cell.nof_prb); @@ -534,6 +534,7 @@ int main(int argc, char **argv) { printf("Set TX freq: %.2f MHz\n", srslte_rf_set_tx_freq(&rf, rf_freq) / 1000000); } +srslte_rf_start_tx_stream(&rf); #endif if (update_radl(sf_idx)) { @@ -662,7 +663,7 @@ int main(int argc, char **argv) { nf++; sfn = (sfn + 1) % 1024; } - + srslte_rf_stop_tx_stream(&rf); base_free(); printf("Done\n"); diff --git a/lib/include/srslte/phy/rf/rf.h b/lib/include/srslte/phy/rf/rf.h index 907a5a008..e83d4b4cc 100644 --- a/lib/include/srslte/phy/rf/rf.h +++ b/lib/include/srslte/phy/rf/rf.h @@ -99,6 +99,10 @@ SRSLTE_API int srslte_rf_start_rx_stream(srslte_rf_t *h); SRSLTE_API int srslte_rf_stop_rx_stream(srslte_rf_t *h); +SRSLTE_API int srslte_rf_start_tx_stream(srslte_rf_t *h); + +SRSLTE_API int srslte_rf_stop_tx_stream(srslte_rf_t *h); + SRSLTE_API void srslte_rf_flush_buffer(srslte_rf_t *h); SRSLTE_API bool srslte_rf_has_rssi(srslte_rf_t *h); diff --git a/lib/src/phy/rf/rf_blade_imp.c b/lib/src/phy/rf/rf_blade_imp.c index f3dd471f6..04e26e509 100644 --- a/lib/src/phy/rf/rf_blade_imp.c +++ b/lib/src/phy/rf/rf_blade_imp.c @@ -164,6 +164,13 @@ int rf_blade_stop_rx_stream(void *h) return 0; } + +int rf_blade_stop_tx_stream(void *h) +{ + return 0; +} + + void rf_blade_flush_buffer(void *h) { } diff --git a/lib/src/phy/rf/rf_blade_imp.h b/lib/src/phy/rf/rf_blade_imp.h index 07e9bb7cf..a537a86c3 100644 --- a/lib/src/phy/rf/rf_blade_imp.h +++ b/lib/src/phy/rf/rf_blade_imp.h @@ -51,6 +51,11 @@ SRSLTE_API int rf_blade_start_rx_stream_nsamples(void *h, SRSLTE_API int rf_blade_stop_rx_stream(void *h); +SRSLTE_API int rf_blade_start_tx_stream(void *h); + +SRSLTE_API int rf_blade_stop_tx_stream(void *h); + + SRSLTE_API void rf_blade_flush_buffer(void *h); SRSLTE_API bool rf_blade_has_rssi(void *h); diff --git a/lib/src/phy/rf/rf_dev.h b/lib/src/phy/rf/rf_dev.h index e1b761419..bc6882a49 100644 --- a/lib/src/phy/rf/rf_dev.h +++ b/lib/src/phy/rf/rf_dev.h @@ -32,6 +32,8 @@ typedef struct { bool (*srslte_rf_rx_wait_lo_locked) (void *h); int (*srslte_rf_start_rx_stream)(void *h); int (*srslte_rf_stop_rx_stream)(void *h); + int (*srslte_rf_start_tx_stream)(void *h); + int (*srslte_rf_stop_tx_stream)(void *h); void (*srslte_rf_flush_buffer)(void *h); bool (*srslte_rf_has_rssi)(void *h); float (*srslte_rf_get_rssi)(void *h); @@ -75,6 +77,8 @@ static rf_dev_t dev_uhd = { rf_uhd_rx_wait_lo_locked, rf_uhd_start_rx_stream, rf_uhd_stop_rx_stream, + rf_uhd_start_tx_stream, + rf_uhd_stop_tx_stream, rf_uhd_flush_buffer, rf_uhd_has_rssi, rf_uhd_get_rssi, @@ -113,6 +117,8 @@ static rf_dev_t dev_blade = { rf_blade_rx_wait_lo_locked, rf_blade_start_rx_stream, rf_blade_stop_rx_stream, + rf_blade_start_tx_stream, + rf_blade_stop_tx_stream, rf_blade_flush_buffer, rf_blade_has_rssi, rf_blade_get_rssi, @@ -150,6 +156,8 @@ static rf_dev_t dev_soapy = { rf_soapy_rx_wait_lo_locked, rf_soapy_start_rx_stream, rf_soapy_stop_rx_stream, + rf_soapy_start_tx_stream, + rf_soapy_stop_tx_stream, rf_soapy_flush_buffer, rf_soapy_has_rssi, rf_soapy_get_rssi, diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index 92b8143da..44f4bbeda 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -154,11 +154,21 @@ int srslte_rf_start_rx_stream(srslte_rf_t *rf) return ((rf_dev_t*) rf->dev)->srslte_rf_start_rx_stream(rf->handler); } +int srslte_rf_start_tx_stream(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_start_tx_stream(rf->handler); +} + int srslte_rf_stop_rx_stream(srslte_rf_t *rf) { return ((rf_dev_t*) rf->dev)->srslte_rf_stop_rx_stream(rf->handler); } +int srslte_rf_stop_tx_stream(srslte_rf_t *rf) +{ + return ((rf_dev_t*) rf->dev)->srslte_rf_stop_tx_stream(rf->handler); +} + void srslte_rf_flush_buffer(srslte_rf_t *rf) { ((rf_dev_t*) rf->dev)->srslte_rf_flush_buffer(rf->handler); diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 8fcf57c24..74d7a885a 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -32,404 +32,451 @@ #include "srslte/srslte.h" #include "rf_soapy_imp.h" -#include "srslte/phy/rf/rf.h" +#include "srslte/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; + + } 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) +{ + // not supported + return true; +} 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"); + // not supported 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) { - printf("TODO: implement rf_soapy_set_rx_cal()\n"); + // not supported } - int rf_soapy_start_rx_stream(void *h) { - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + //printf("starting SOAPY rx stream \n"); + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + - if (SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0) != 0) - return SRSLTE_ERROR; - - return SRSLTE_SUCCESS; + if(SoapySDRDevice_activateStream(handler->device, handler->rxStream, 0, 0, 0)!=0)//start streaming + 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_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; + 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; } - 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) -{ - 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++) +{//SoapySDRKwargs soapy_args = {}; + size_t length; + const SoapySDRKwargs *soapy_args = SoapySDRDevice_enumerate(NULL, &length); + + if(length == 0) { - printf("%s=%s, ", soapy_args[i].keys[j], soapy_args[i].vals[j]); + return SRSLTE_ERROR; } - 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; - - 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; -} + + 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; + +} 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; - 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; + 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); } 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 + + printf("SET MASTER CLOCK RATE\n"); } - -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; - 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); + 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; } 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()); - return SRSLTE_ERROR; - } - return SoapySDRDevice_getSampleRate(handler->device, SOAPY_SDR_TX,0); -} + 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; +} 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; - } - return rf_soapy_get_rx_gain(h); -} + 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; +} 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; - } - return rf_soapy_get_rx_gain(h); + 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; } - 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; - } + + 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; - 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; - } - return SoapySDRDevice_getFrequency(handler->device, SOAPY_SDR_RX, 0); + 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; + } 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; + 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; - 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, - 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, + 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; - rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; - timeNs = secs * 1000000000; - timeNs = timeNs + (frac_secs * 1000000000); - int ret = SoapySDRDevice_writeStream(handler->device, handler->txStream, data, nsamples, &flags, timeNs, 100000); - if(ret != nsamples) - return SRSLTE_ERROR; - - return ret; + + 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 num_channels = 1; + int n = 0; + 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; + } + + + + diff --git a/lib/src/phy/rf/rf_soapy_imp.h b/lib/src/phy/rf/rf_soapy_imp.h index 23b59a8b3..7b081b9ff 100644 --- a/lib/src/phy/rf/rf_soapy_imp.h +++ b/lib/src/phy/rf/rf_soapy_imp.h @@ -49,6 +49,10 @@ SRSLTE_API int rf_soapy_start_rx_stream(void *h); SRSLTE_API int rf_soapy_stop_rx_stream(void *h); +SRSLTE_API int rf_soapy_start_tx_stream(void *h); + +SRSLTE_API int rf_soapy_stop_tx_stream(void *h); + SRSLTE_API void rf_soapy_flush_buffer(void *h); SRSLTE_API bool rf_soapy_has_rssi(void *h); diff --git a/lib/src/phy/rf/rf_uhd_imp.c b/lib/src/phy/rf/rf_uhd_imp.c index 319093994..e6a5ea162 100644 --- a/lib/src/phy/rf/rf_uhd_imp.c +++ b/lib/src/phy/rf/rf_uhd_imp.c @@ -235,6 +235,17 @@ int rf_uhd_start_rx_stream(void *h) return 0; } +int rf_uhd_start_tx_stream(void *h) +{ + return 0; +} + +int rf_uhd_stop_tx_stream(void *h) +{ + return 0; +} + + int rf_uhd_stop_rx_stream(void *h) { rf_uhd_handler_t *handler = (rf_uhd_handler_t*) h; diff --git a/lib/src/phy/rf/rf_uhd_imp.h b/lib/src/phy/rf/rf_uhd_imp.h index 7c26f015c..2d9808b22 100644 --- a/lib/src/phy/rf/rf_uhd_imp.h +++ b/lib/src/phy/rf/rf_uhd_imp.h @@ -51,6 +51,10 @@ SRSLTE_API void rf_uhd_set_rx_cal(void *h, srslte_rf_cal_t *cal); SRSLTE_API int rf_uhd_start_rx_stream(void *h); +SRSLTE_API int rf_uhd_start_tx_stream(void *h); + +SRSLTE_API int rf_uhd_stop_tx_stream(void *h); + SRSLTE_API int rf_uhd_start_rx_stream_nsamples(void *h, uint32_t nsamples);