diff --git a/src/common/sdr.c b/src/common/sdr.c index e18ef92..d1b53fb 100644 --- a/src/common/sdr.c +++ b/src/common/sdr.c @@ -81,7 +81,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq { sdr_t *sdr; double bandwidth; - double tx_center_frequency, rx_center_frequency; + double tx_center_frequency = 0.0, rx_center_frequency = 0.0; int rc; int c; @@ -117,102 +117,124 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); goto error; } - for (c = 0; c < channels; c++) { - PDEBUG(DSDR, DEBUG_INFO, "Frequency #%d: TX = %.6f MHz, RX = %.6f MHz\n", c, tx_frequency[c] / 1e6, rx_frequency[c] / 1e6); - sdr->chan[c].tx_frequency = tx_frequency[c]; - sdr->chan[c].rx_frequency = rx_frequency[c]; - } - if (sdr->paging_channel) { - PDEBUG(DSDR, DEBUG_INFO, "Paging Frequency: TX = %.6f MHz\n", paging_frequency / 1e6); - sdr->chan[sdr->paging_channel].tx_frequency = paging_frequency; + + if (tx_frequency) { + /* calculate required bandwidth (IQ rate) */ + for (c = 0; c < channels; c++) { + PDEBUG(DSDR, DEBUG_INFO, "Frequency #%d: TX = %.6f MHz\n", c, tx_frequency[c] / 1e6); + sdr->chan[c].tx_frequency = tx_frequency[c]; + } + if (sdr->paging_channel) { + PDEBUG(DSDR, DEBUG_INFO, "Paging Frequency: TX = %.6f MHz\n", paging_frequency / 1e6); + sdr->chan[sdr->paging_channel].tx_frequency = paging_frequency; + } + + double tx_low_frequency = sdr->chan[0].tx_frequency, tx_high_frequency = sdr->chan[0].tx_frequency; + for (c = 1; c < channels; c++) { + if (sdr->chan[c].tx_frequency < tx_low_frequency) + tx_low_frequency = sdr->chan[c].tx_frequency; + if (sdr->chan[c].tx_frequency > tx_high_frequency) + tx_high_frequency = sdr->chan[c].tx_frequency; + } + if (sdr->paging_channel) { + if (sdr->chan[sdr->paging_channel].tx_frequency < tx_low_frequency) + tx_low_frequency = sdr->chan[sdr->paging_channel].tx_frequency; + if (sdr->chan[sdr->paging_channel].tx_frequency > tx_high_frequency) + tx_high_frequency = sdr->chan[sdr->paging_channel].tx_frequency; + } + /* range of TX */ + double range = tx_high_frequency - tx_low_frequency; + if (range) + PDEBUG(DSDR, DEBUG_DEBUG, "Range between all TX Frequencies: %.6f MHz\n", range / 1e6); + if (range * 2 > sdr->samplerate) { + // why that? actually i don't know. i just want to be safe.... + PDEBUG(DSDR, DEBUG_NOTICE, "The sample rate must be at least twice the range between frequencies.\n"); + PDEBUG(DSDR, DEBUG_NOTICE, "The given rate is %.6f MHz, but required rate must be >= %.6f MHz\n", sdr->samplerate / 1e6, range * 2.0 / 1e6); + PDEBUG(DSDR, DEBUG_NOTICE, "Please increase samplerate!\n"); + goto error; + } + tx_center_frequency = (tx_high_frequency + tx_low_frequency) / 2.0; + PDEBUG(DSDR, DEBUG_INFO, "Using center frequency: TX %.6f MHz\n", tx_center_frequency / 1e6); + /* set offsets to center frequency */ + for (c = 0; c < channels; c++) { + double tx_offset; + tx_offset = sdr->chan[c].tx_frequency - tx_center_frequency; + PDEBUG(DSDR, DEBUG_DEBUG, "Frequency #%d: TX offset: %.6f MHz\n", c, tx_offset / 1e6); + fm_mod_init(&sdr->chan[c].mod, sdr->samplerate, tx_offset, sdr->amplitude); + } + if (sdr->paging_channel) { + double tx_offset; + tx_offset = sdr->chan[sdr->paging_channel].tx_frequency - tx_center_frequency; + PDEBUG(DSDR, DEBUG_DEBUG, "Paging Frequency: TX offset: %.6f MHz\n", tx_offset / 1e6); + fm_mod_init(&sdr->chan[sdr->paging_channel].mod, sdr->samplerate, tx_offset, sdr->amplitude); + } + /* show gain */ + PDEBUG(DSDR, DEBUG_INFO, "Using gain: TX %.1f dB\n", sdr_tx_gain); + /* open wave */ + if (sdr_write_iq_tx_wave) { + rc = wave_create_record(&sdr->wave_tx_rec, sdr_write_iq_tx_wave, sdr->samplerate, 2, 1.0); + if (rc < 0) { + PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); + goto error; + } + } + if (sdr_read_iq_tx_wave) { + rc = wave_create_playback(&sdr->wave_tx_play, sdr_read_iq_tx_wave, sdr->samplerate, 2, 1.0); + if (rc < 0) { + PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); + goto error; + } + } } - /* calculate required bandwidth (IQ rate) */ - double tx_low_frequency = sdr->chan[0].tx_frequency, tx_high_frequency = sdr->chan[0].tx_frequency; - double rx_low_frequency = sdr->chan[0].rx_frequency, rx_high_frequency = sdr->chan[0].rx_frequency; - double range; - for (c = 1; c < channels; c++) { - if (sdr->chan[c].tx_frequency < tx_low_frequency) - tx_low_frequency = sdr->chan[c].tx_frequency; - if (sdr->chan[c].tx_frequency > tx_high_frequency) - tx_high_frequency = sdr->chan[c].tx_frequency; - if (sdr->chan[c].rx_frequency < rx_low_frequency) - rx_low_frequency = sdr->chan[c].rx_frequency; - if (sdr->chan[c].rx_frequency > rx_high_frequency) - rx_high_frequency = sdr->chan[c].rx_frequency; - } - if (sdr->paging_channel) { - if (sdr->chan[sdr->paging_channel].tx_frequency < tx_low_frequency) - tx_low_frequency = sdr->chan[sdr->paging_channel].tx_frequency; - if (sdr->chan[sdr->paging_channel].tx_frequency > tx_high_frequency) - tx_high_frequency = sdr->chan[sdr->paging_channel].tx_frequency; - } - /* range of TX */ - range = tx_high_frequency - tx_low_frequency; - if (range) - PDEBUG(DSDR, DEBUG_DEBUG, "Range between all TX Frequencies: %.6f MHz\n", range / 1e6); - if (range * 2 > sdr->samplerate) { - // why that? actually i don't know. i just want to be safe.... - PDEBUG(DSDR, DEBUG_NOTICE, "The sample rate must be at least twice the range between frequencies.\n"); - PDEBUG(DSDR, DEBUG_NOTICE, "The given rate is %.6f MHz, but required rate must be >= %.6f MHz\n", sdr->samplerate / 1e6, range * 2.0 / 1e6); - PDEBUG(DSDR, DEBUG_NOTICE, "Please increase samplerate!\n"); - goto error; - } - tx_center_frequency = (tx_high_frequency + tx_low_frequency) / 2.0; - /* range of RX */ - range = rx_high_frequency - rx_low_frequency; - if (range) - PDEBUG(DSDR, DEBUG_DEBUG, "Range between all RX Frequencies: %.6f MHz\n", range / 1e6); - if (range * 2.0 > sdr->samplerate) { - // why that? actually i don't know. i just want to be safe.... - PDEBUG(DSDR, DEBUG_NOTICE, "The sample rate must be at least twice the range between frequencies. Please increment samplerate!\n"); - goto error; - } - rx_center_frequency = (rx_high_frequency + rx_low_frequency) / 2.0; - PDEBUG(DSDR, DEBUG_INFO, "Using center frequency: TX %.6f MHz, RX %.6f\n", tx_center_frequency / 1e6, rx_center_frequency / 1e6); - /* set offsets to center frequency */ - for (c = 0; c < channels; c++) { - double tx_offset, rx_offset; - tx_offset = sdr->chan[c].tx_frequency - tx_center_frequency; - rx_offset = sdr->chan[c].rx_frequency - rx_center_frequency; - PDEBUG(DSDR, DEBUG_DEBUG, "Frequency #%d: TX offset: %.6f MHz, RX offset: %.6f MHz\n", c, tx_offset / 1e6, rx_offset / 1e6); - fm_mod_init(&sdr->chan[c].mod, sdr->samplerate, tx_offset, sdr->amplitude); - fm_demod_init(&sdr->chan[c].demod, sdr->samplerate, rx_offset, bandwidth); - } - if (sdr->paging_channel) { - double tx_offset; - tx_offset = sdr->chan[sdr->paging_channel].tx_frequency - tx_center_frequency; - PDEBUG(DSDR, DEBUG_DEBUG, "Paging Frequency: TX offset: %.6f MHz\n", tx_offset / 1e6); - fm_mod_init(&sdr->chan[sdr->paging_channel].mod, sdr->samplerate, tx_offset, sdr->amplitude); - } - PDEBUG(DSDR, DEBUG_INFO, "Using gain: TX %.1f dB, RX %.1f dB\n", sdr_tx_gain, sdr_rx_gain); + if (rx_frequency) { + for (c = 0; c < channels; c++) { + PDEBUG(DSDR, DEBUG_INFO, "Frequency #%d: RX = %.6f MHz\n", c, rx_frequency[c] / 1e6); + sdr->chan[c].rx_frequency = rx_frequency[c]; + } - if (sdr_write_iq_rx_wave) { - rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, sdr->samplerate, 2, 1.0); - if (rc < 0) { - PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); + /* calculate required bandwidth (IQ rate) */ + double rx_low_frequency = sdr->chan[0].rx_frequency, rx_high_frequency = sdr->chan[0].rx_frequency; + for (c = 1; c < channels; c++) { + if (sdr->chan[c].rx_frequency < rx_low_frequency) + rx_low_frequency = sdr->chan[c].rx_frequency; + if (sdr->chan[c].rx_frequency > rx_high_frequency) + rx_high_frequency = sdr->chan[c].rx_frequency; + } + /* range of RX */ + double range = rx_high_frequency - rx_low_frequency; + if (range) + PDEBUG(DSDR, DEBUG_DEBUG, "Range between all RX Frequencies: %.6f MHz\n", range / 1e6); + if (range * 2.0 > sdr->samplerate) { + // why that? actually i don't know. i just want to be safe.... + PDEBUG(DSDR, DEBUG_NOTICE, "The sample rate must be at least twice the range between frequencies. Please increment samplerate!\n"); goto error; } - } - if (sdr_write_iq_tx_wave) { - rc = wave_create_record(&sdr->wave_tx_rec, sdr_write_iq_tx_wave, sdr->samplerate, 2, 1.0); - if (rc < 0) { - PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); - goto error; + rx_center_frequency = (rx_high_frequency + rx_low_frequency) / 2.0; + PDEBUG(DSDR, DEBUG_INFO, "Using center frequency: RX %.6f MHz\n", rx_center_frequency / 1e6); + /* set offsets to center frequency */ + for (c = 0; c < channels; c++) { + double rx_offset; + rx_offset = sdr->chan[c].rx_frequency - rx_center_frequency; + PDEBUG(DSDR, DEBUG_DEBUG, "Frequency #%d: RX offset: %.6f MHz\n", c, rx_offset / 1e6); + fm_demod_init(&sdr->chan[c].demod, sdr->samplerate, rx_offset, bandwidth); } - } - if (sdr_read_iq_rx_wave) { - rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, sdr->samplerate, 2, 1.0); - if (rc < 0) { - PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); - goto error; + /* show gain */ + PDEBUG(DSDR, DEBUG_INFO, "Using gain: RX %.1f dB\n", sdr_rx_gain); + /* open wave */ + if (sdr_write_iq_rx_wave) { + rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, sdr->samplerate, 2, 1.0); + if (rc < 0) { + PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); + goto error; + } } - } - if (sdr_read_iq_tx_wave) { - rc = wave_create_playback(&sdr->wave_tx_play, sdr_read_iq_tx_wave, sdr->samplerate, 2, 1.0); - if (rc < 0) { - PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); - goto error; + if (sdr_read_iq_rx_wave) { + rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, sdr->samplerate, 2, 1.0); + if (rc < 0) { + PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); + goto error; + } } } diff --git a/src/common/soapy.c b/src/common/soapy.c index a653b76..c005162 100644 --- a/src/common/soapy.c +++ b/src/common/soapy.c @@ -68,132 +68,156 @@ int soapy_open(const char *device_args, double tx_frequency, double rx_frequency return -EIO; } - /* set rate */ - if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_TX, channel, rate) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); - soapy_close(); - return -EIO; - } - if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_RX, channel, rate) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate); - soapy_close(); - return -EIO; + if (tx_frequency) { + /* set rate */ + if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_TX, channel, rate) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); + soapy_close(); + return -EIO; + } + + /* see what rate actually is */ + got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_TX, channel); + if (got_rate != rate) { + PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + soapy_close(); + return -EINVAL; + } + + /* set gain */ + if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_TX, channel, tx_gain) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); + soapy_close(); + return -EIO; + } + + /* see what gain actually is */ + got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_TX, channel); + if (got_gain != tx_gain) { + PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); + tx_gain = got_gain; + } + + /* set frequency */ + if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_TX, channel, tx_frequency, NULL) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequency to %.0f Hz\n", tx_frequency); + soapy_close(); + return -EIO; + } + + /* see what frequency actually is */ + got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_TX, channel); + if (got_frequency != tx_frequency) { + PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); + soapy_close(); + return -EINVAL; + } + + /* set bandwidth */ + if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_TX, channel, bandwidth) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); + soapy_close(); + return -EIO; + } + + /* see what bandwidth actually is */ + got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_TX, channel); + if (got_bandwidth != bandwidth) { + PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + soapy_close(); + return -EINVAL; + } + + /* set up streamer */ + if (SoapySDRDevice_setupStream(sdr, &txStream, SOAPY_SDR_TX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); + soapy_close(); + return -EIO; + } + + /* get buffer sizes */ + tx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, txStream); + if (tx_samps_per_buff == 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); + soapy_close(); + return -EIO; + } } - /* see what rate actually is */ - got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_TX, channel); - if (got_rate != rate) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); - soapy_close(); - return -EINVAL; - } - got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_RX, channel); - if (got_rate != rate) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); - soapy_close(); - return -EINVAL; - } + if (rx_frequency) { + /* set rate */ + if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_RX, channel, rate) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate); + soapy_close(); + return -EIO; + } - /* set gain */ - if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_TX, channel, tx_gain) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); - soapy_close(); - return -EIO; - } - if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_RX, channel, rx_gain) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); - soapy_close(); - return -EIO; - } + /* see what rate actually is */ + got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_RX, channel); + if (got_rate != rate) { + PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + soapy_close(); + return -EINVAL; + } - /* see what gain actually is */ - got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_TX, channel); - if (got_gain != tx_gain) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); - tx_gain = got_gain; - } - got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_RX, channel); - if (got_gain != rx_gain) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain); - rx_gain = got_gain; - } + /* set gain */ + if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_RX, channel, rx_gain) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); + soapy_close(); + return -EIO; + } - /* set frequency */ - if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_TX, channel, tx_frequency, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequency to %.0f Hz\n", tx_frequency); - soapy_close(); - return -EIO; - } - if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_RX, channel, rx_frequency, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequency to %.0f Hz\n", rx_frequency); - soapy_close(); - return -EIO; - } + /* see what gain actually is */ + got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_RX, channel); + if (got_gain != rx_gain) { + PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain); + rx_gain = got_gain; + } - /* see what frequency actually is */ - got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_TX, channel); - if (got_frequency != tx_frequency) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); - soapy_close(); - return -EINVAL; - } - got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_RX, channel); - if (got_frequency != rx_frequency) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency); - soapy_close(); - return -EINVAL; - } + /* set frequency */ + if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_RX, channel, rx_frequency, NULL) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequency to %.0f Hz\n", rx_frequency); + soapy_close(); + return -EIO; + } - /* set bandwidth */ - if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_TX, channel, bandwidth) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); - soapy_close(); - return -EIO; - } - if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_RX, channel, bandwidth) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth); - soapy_close(); - return -EIO; - } + /* see what frequency actually is */ + got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_RX, channel); + if (got_frequency != rx_frequency) { + PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency); + soapy_close(); + return -EINVAL; + } - /* see what bandwidth actually is */ - got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_TX, channel); - if (got_bandwidth != bandwidth) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); - soapy_close(); - return -EINVAL; - } - got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_RX, channel); - if (got_bandwidth != bandwidth) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); - soapy_close(); - return -EINVAL; - } + /* set bandwidth */ + if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_RX, channel, bandwidth) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth); + soapy_close(); + return -EIO; + } - /* set up streamer */ - if (SoapySDRDevice_setupStream(sdr, &txStream, SOAPY_SDR_TX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); - soapy_close(); - return -EIO; - } - if (SoapySDRDevice_setupStream(sdr, &rxStream, SOAPY_SDR_RX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n"); - soapy_close(); - return -EIO; - } + /* see what bandwidth actually is */ + got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_RX, channel); + if (got_bandwidth != bandwidth) { + PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + soapy_close(); + return -EINVAL; + } - /* get buffer sizes */ - tx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, txStream); - if (tx_samps_per_buff == 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); - soapy_close(); - return -EIO; - } - rx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, rxStream); - if (rx_samps_per_buff == 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); - soapy_close(); - return -EIO; + /* set up streamer */ + if (SoapySDRDevice_setupStream(sdr, &rxStream, SOAPY_SDR_RX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n"); + soapy_close(); + return -EIO; + } + + /* get buffer sizes */ + rx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, rxStream); + if (rx_samps_per_buff == 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); + soapy_close(); + return -EIO; + } } return 0; diff --git a/src/common/uhd.c b/src/common/uhd.c index c968798..c039f67 100644 --- a/src/common/uhd.c +++ b/src/common/uhd.c @@ -63,213 +63,248 @@ int uhd_open(const char *device_args, double tx_frequency, double rx_frequency, return -EIO; } - /* create streamers */ - error = uhd_tx_streamer_make(&tx_streamer); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to create TX streamer\n"); - uhd_close(); - return -EIO; - } - error = uhd_rx_streamer_make(&rx_streamer); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX streamer\n"); - uhd_close(); - return -EIO; + if (tx_frequency) { + /* create streamers */ + error = uhd_tx_streamer_make(&tx_streamer); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to create TX streamer\n"); + uhd_close(); + return -EIO; + } + + /* set rate */ + error = uhd_usrp_set_tx_rate(usrp, rate, channel); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); + uhd_close(); + return -EIO; + } + + /* see what rate actually is */ + error = uhd_usrp_get_tx_rate(usrp, channel, &got_rate); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX rate\n"); + uhd_close(); + return -EIO; + } + if (got_rate != rate) { + PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + uhd_close(); + return -EINVAL; + } + + /* set gain */ + error = uhd_usrp_set_tx_gain(usrp, tx_gain, channel, ""); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); + uhd_close(); + return -EIO; + } + + /* see what gain actually is */ + error = uhd_usrp_get_tx_gain(usrp, channel, "", &got_gain); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX gain\n"); + uhd_close(); + return -EIO; + } + if (got_gain != tx_gain) { + PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); + tx_gain = got_gain; + } + + /* set frequency */ + memset(&tune_request, 0, sizeof(tune_request)); + tune_request.target_freq = tx_frequency; + tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; + tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; + error = uhd_usrp_set_tx_freq(usrp, &tune_request, channel, &tune_result); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequeny to %.0f Hz\n", tx_frequency); + uhd_close(); + return -EIO; + } + + /* see what frequency actually is */ + error = uhd_usrp_get_tx_freq(usrp, channel, &got_frequency); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX frequency\n"); + uhd_close(); + return -EIO; + } + if (got_frequency != tx_frequency) { + PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); + uhd_close(); + return -EINVAL; + } + + /* set bandwidth */ + if (uhd_usrp_set_tx_bandwidth(usrp, bandwidth, channel) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); + uhd_close(); + return -EIO; + } + + /* see what bandwidth actually is */ + error = uhd_usrp_get_tx_bandwidth(usrp, channel, &got_bandwidth); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX bandwidth\n"); + uhd_close(); + return -EIO; + } + if (got_bandwidth != bandwidth) { + PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + uhd_close(); + return -EINVAL; + } + + /* set up streamer */ + memset(&stream_args, 0, sizeof(stream_args)); + stream_args.cpu_format = "fc32"; + stream_args.otw_format = "sc16"; + stream_args.args = ""; + stream_args.channel_list = &channel; + stream_args.n_channels = 1; + error = uhd_usrp_get_tx_stream(usrp, &stream_args, tx_streamer); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); + uhd_close(); + return -EIO; + } + + /* get buffer sizes */ + error = uhd_tx_streamer_max_num_samps(tx_streamer, &tx_samps_per_buff); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); + uhd_close(); + return -EIO; + } } - /* create rx metadata */ - error = uhd_rx_metadata_make(&rx_metadata); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX metadata\n"); - uhd_close(); - return -EIO; - } + if (rx_frequency) { + /* create streamers */ + error = uhd_rx_streamer_make(&rx_streamer); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX streamer\n"); + uhd_close(); + return -EIO; + } - /* set rate */ - error = uhd_usrp_set_tx_rate(usrp, rate, channel); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); - uhd_close(); - return -EIO; - } - error = uhd_usrp_set_rx_rate(usrp, rate, channel); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate); - uhd_close(); - return -EIO; - } + /* create metadata */ + error = uhd_rx_metadata_make(&rx_metadata); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX metadata\n"); + uhd_close(); + return -EIO; + } - /* see what rate actually is */ - error = uhd_usrp_get_tx_rate(usrp, channel, &got_rate); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX rate\n"); - uhd_close(); - return -EIO; - } - if (got_rate != rate) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); - uhd_close(); - return -EINVAL; - } - error = uhd_usrp_get_rx_rate(usrp, channel, &got_rate); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX rate\n"); - uhd_close(); - return -EIO; - } - if (got_rate != rate) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); - uhd_close(); - return -EINVAL; - } + /* set rate */ + error = uhd_usrp_set_rx_rate(usrp, rate, channel); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate); + uhd_close(); + return -EIO; + } - /* set gain */ - error = uhd_usrp_set_tx_gain(usrp, tx_gain, channel, ""); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); - uhd_close(); - return -EIO; - } - error = uhd_usrp_set_rx_gain(usrp, rx_gain, channel, ""); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); - uhd_close(); - return -EIO; - } + /* see what rate actually is */ + error = uhd_usrp_get_rx_rate(usrp, channel, &got_rate); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX rate\n"); + uhd_close(); + return -EIO; + } + if (got_rate != rate) { + PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); + uhd_close(); + return -EINVAL; + } - /* see what gain actually is */ - error = uhd_usrp_get_tx_gain(usrp, channel, "", &got_gain); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX gain\n"); - uhd_close(); - return -EIO; - } - if (got_gain != tx_gain) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); - tx_gain = got_gain; - } - error = uhd_usrp_get_rx_gain(usrp, channel, "", &got_gain); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX gain\n"); - uhd_close(); - return -EIO; - } - if (got_gain != rx_gain) { - PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain); - rx_gain = got_gain; - } + /* set gain */ + error = uhd_usrp_set_rx_gain(usrp, rx_gain, channel, ""); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); + uhd_close(); + return -EIO; + } - /* set frequency */ - memset(&tune_request, 0, sizeof(tune_request)); - tune_request.target_freq = tx_frequency; - tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; - tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; - error = uhd_usrp_set_tx_freq(usrp, &tune_request, channel, &tune_result); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequeny to %.0f Hz\n", tx_frequency); - uhd_close(); - return -EIO; - } - tune_request.target_freq = rx_frequency; - error = uhd_usrp_set_rx_freq(usrp, &tune_request, channel, &tune_result); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequeny to %.0f Hz\n", rx_frequency); - uhd_close(); - return -EIO; - } + /* see what gain actually is */ + error = uhd_usrp_get_rx_gain(usrp, channel, "", &got_gain); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX gain\n"); + uhd_close(); + return -EIO; + } + if (got_gain != rx_gain) { + PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain); + rx_gain = got_gain; + } - /* see what frequency actually is */ - error = uhd_usrp_get_tx_freq(usrp, channel, &got_frequency); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX frequency\n"); - uhd_close(); - return -EIO; - } - if (got_frequency != tx_frequency) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); - uhd_close(); - return -EINVAL; - } - error = uhd_usrp_get_rx_freq(usrp, channel, &got_frequency); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX frequency\n"); - uhd_close(); - return -EIO; - } - if (got_frequency != rx_frequency) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency); - uhd_close(); - return -EINVAL; - } + /* set frequency */ + memset(&tune_request, 0, sizeof(tune_request)); + tune_request.target_freq = rx_frequency; + tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; + tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; + error = uhd_usrp_set_rx_freq(usrp, &tune_request, channel, &tune_result); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequeny to %.0f Hz\n", rx_frequency); + uhd_close(); + return -EIO; + } - /* set bandwidth */ - if (uhd_usrp_set_tx_bandwidth(usrp, bandwidth, channel) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); - uhd_close(); - return -EIO; - } - if (uhd_usrp_set_rx_bandwidth(usrp, bandwidth, channel) != 0) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth); - uhd_close(); - return -EIO; - } + /* see what frequency actually is */ + error = uhd_usrp_get_rx_freq(usrp, channel, &got_frequency); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX frequency\n"); + uhd_close(); + return -EIO; + } + if (got_frequency != rx_frequency) { + PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency); + uhd_close(); + return -EINVAL; + } - /* see what bandwidth actually is */ - error = uhd_usrp_get_tx_bandwidth(usrp, channel, &got_bandwidth); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX bandwidth\n"); - uhd_close(); - return -EIO; - } - if (got_bandwidth != bandwidth) { - PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); - uhd_close(); - return -EINVAL; - } - error = uhd_usrp_get_rx_bandwidth(usrp, channel, &got_bandwidth); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX bandwidth\n"); - uhd_close(); - return -EIO; - } - if (got_bandwidth != bandwidth) { - PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); - uhd_close(); - return -EINVAL; - } + /* set bandwidth */ + if (uhd_usrp_set_rx_bandwidth(usrp, bandwidth, channel) != 0) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth); + uhd_close(); + return -EIO; + } - /* set up streamer */ - memset(&stream_args, 0, sizeof(stream_args)); - stream_args.cpu_format = "fc32"; - stream_args.otw_format = "sc16"; - stream_args.args = ""; - stream_args.channel_list = &channel; - stream_args.n_channels = 1; - error = uhd_usrp_get_tx_stream(usrp, &stream_args, tx_streamer); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); - uhd_close(); - return -EIO; - } - error = uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n"); - uhd_close(); - return -EIO; - } + /* see what bandwidth actually is */ + error = uhd_usrp_get_rx_bandwidth(usrp, channel, &got_bandwidth); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX bandwidth\n"); + uhd_close(); + return -EIO; + } + if (got_bandwidth != bandwidth) { + PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); + uhd_close(); + return -EINVAL; + } - /* get buffer sizes */ - error = uhd_tx_streamer_max_num_samps(tx_streamer, &tx_samps_per_buff); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); - uhd_close(); - return -EIO; - } - error = uhd_rx_streamer_max_num_samps(rx_streamer, &rx_samps_per_buff); - if (error) { - PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); - uhd_close(); - return -EIO; + /* set up streamer */ + memset(&stream_args, 0, sizeof(stream_args)); + stream_args.cpu_format = "fc32"; + stream_args.otw_format = "sc16"; + stream_args.args = ""; + stream_args.channel_list = &channel; + stream_args.n_channels = 1; + error = uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n"); + uhd_close(); + return -EIO; + } + + /* get buffer sizes */ + error = uhd_rx_streamer_max_num_samps(rx_streamer, &rx_samps_per_buff); + if (error) { + PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); + uhd_close(); + return -EIO; + } } return 0;