SDR: disable TX or RX by setting TX or RX frequency to 0

This way it is possible to use SDR simplex
This commit is contained in:
Andreas Eversberg
2017-03-20 19:57:37 +01:00
parent 6e0e0c9ce8
commit 65694f3b80
3 changed files with 482 additions and 401 deletions

View File

@@ -81,7 +81,7 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
{ {
sdr_t *sdr; sdr_t *sdr;
double bandwidth; double bandwidth;
double tx_center_frequency, rx_center_frequency; double tx_center_frequency = 0.0, rx_center_frequency = 0.0;
int rc; int rc;
int c; int c;
@@ -117,102 +117,124 @@ void *sdr_open(const char __attribute__((__unused__)) *audiodev, double *tx_freq
PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n"); PDEBUG(DSDR, DEBUG_ERROR, "NO MEM!\n");
goto error; 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); if (tx_frequency) {
sdr->chan[c].tx_frequency = tx_frequency[c]; /* calculate required bandwidth (IQ rate) */
sdr->chan[c].rx_frequency = rx_frequency[c]; for (c = 0; c < channels; c++) {
} PDEBUG(DSDR, DEBUG_INFO, "Frequency #%d: TX = %.6f MHz\n", c, tx_frequency[c] / 1e6);
if (sdr->paging_channel) { sdr->chan[c].tx_frequency = tx_frequency[c];
PDEBUG(DSDR, DEBUG_INFO, "Paging Frequency: TX = %.6f MHz\n", paging_frequency / 1e6); }
sdr->chan[sdr->paging_channel].tx_frequency = paging_frequency; 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) */ if (rx_frequency) {
double tx_low_frequency = sdr->chan[0].tx_frequency, tx_high_frequency = sdr->chan[0].tx_frequency; for (c = 0; c < channels; c++) {
double rx_low_frequency = sdr->chan[0].rx_frequency, rx_high_frequency = sdr->chan[0].rx_frequency; PDEBUG(DSDR, DEBUG_INFO, "Frequency #%d: RX = %.6f MHz\n", c, rx_frequency[c] / 1e6);
double range; sdr->chan[c].rx_frequency = rx_frequency[c];
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 (sdr_write_iq_rx_wave) { /* calculate required bandwidth (IQ rate) */
rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, sdr->samplerate, 2, 1.0); double rx_low_frequency = sdr->chan[0].rx_frequency, rx_high_frequency = sdr->chan[0].rx_frequency;
if (rc < 0) { for (c = 1; c < channels; c++) {
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); 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; goto error;
} }
} rx_center_frequency = (rx_high_frequency + rx_low_frequency) / 2.0;
if (sdr_write_iq_tx_wave) { PDEBUG(DSDR, DEBUG_INFO, "Using center frequency: RX %.6f MHz\n", rx_center_frequency / 1e6);
rc = wave_create_record(&sdr->wave_tx_rec, sdr_write_iq_tx_wave, sdr->samplerate, 2, 1.0); /* set offsets to center frequency */
if (rc < 0) { for (c = 0; c < channels; c++) {
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n"); double rx_offset;
goto error; 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);
} }
} /* show gain */
if (sdr_read_iq_rx_wave) { PDEBUG(DSDR, DEBUG_INFO, "Using gain: RX %.1f dB\n", sdr_rx_gain);
rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, sdr->samplerate, 2, 1.0); /* open wave */
if (rc < 0) { if (sdr_write_iq_rx_wave) {
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); rc = wave_create_record(&sdr->wave_rx_rec, sdr_write_iq_rx_wave, sdr->samplerate, 2, 1.0);
goto error; if (rc < 0) {
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE recoding instance!\n");
goto error;
}
} }
} if (sdr_read_iq_rx_wave) {
if (sdr_read_iq_tx_wave) { rc = wave_create_playback(&sdr->wave_rx_play, sdr_read_iq_rx_wave, sdr->samplerate, 2, 1.0);
rc = wave_create_playback(&sdr->wave_tx_play, sdr_read_iq_tx_wave, sdr->samplerate, 2, 1.0); if (rc < 0) {
if (rc < 0) { PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n");
PDEBUG(DSDR, DEBUG_ERROR, "Failed to create WAVE playback instance!\n"); goto error;
goto error; }
} }
} }

View File

@@ -68,132 +68,156 @@ int soapy_open(const char *device_args, double tx_frequency, double rx_frequency
return -EIO; return -EIO;
} }
/* set rate */ if (tx_frequency) {
if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_TX, channel, rate) != 0) { /* set rate */
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_TX, channel, rate) != 0) {
soapy_close(); PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate);
return -EIO; 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(); /* see what rate actually is */
return -EIO; 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 */ if (rx_frequency) {
got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_TX, channel); /* set rate */
if (got_rate != rate) { if (SoapySDRDevice_setSampleRate(sdr, SOAPY_SDR_RX, channel, rate) != 0) {
PDEBUG(DUHD, DEBUG_ERROR, "Given TX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate); PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate);
soapy_close(); soapy_close();
return -EINVAL; return -EIO;
} }
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;
}
/* set gain */ /* see what rate actually is */
if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_TX, channel, tx_gain) != 0) { got_rate = SoapySDRDevice_getSampleRate(sdr, SOAPY_SDR_RX, channel);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); if (got_rate != rate) {
soapy_close(); PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate);
return -EIO; soapy_close();
} return -EINVAL;
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 gain actually is */ /* set gain */
got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_TX, channel); if (SoapySDRDevice_setGain(sdr, SOAPY_SDR_RX, channel, rx_gain) != 0) {
if (got_gain != tx_gain) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain);
PDEBUG(DUHD, DEBUG_NOTICE, "Given TX gain %.0f is not supported, we use %0.f\n", tx_gain, got_gain); soapy_close();
tx_gain = got_gain; return -EIO;
} }
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 frequency */ /* see what gain actually is */
if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_TX, channel, tx_frequency, NULL) != 0) { got_gain = SoapySDRDevice_getGain(sdr, SOAPY_SDR_RX, channel);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequency to %.0f Hz\n", tx_frequency); if (got_gain != rx_gain) {
soapy_close(); PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain);
return -EIO; rx_gain = got_gain;
} }
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 frequency actually is */ /* set frequency */
got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_TX, channel); if (SoapySDRDevice_setFrequency(sdr, SOAPY_SDR_RX, channel, rx_frequency, NULL) != 0) {
if (got_frequency != tx_frequency) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequency to %.0f Hz\n", rx_frequency);
PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); soapy_close();
soapy_close(); return -EIO;
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 bandwidth */ /* see what frequency actually is */
if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_TX, channel, bandwidth) != 0) { got_frequency = SoapySDRDevice_getFrequency(sdr, SOAPY_SDR_RX, channel);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); if (got_frequency != rx_frequency) {
soapy_close(); PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency);
return -EIO; soapy_close();
} return -EINVAL;
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 bandwidth actually is */ /* set bandwidth */
got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_TX, channel); if (SoapySDRDevice_setBandwidth(sdr, SOAPY_SDR_RX, channel, bandwidth) != 0) {
if (got_bandwidth != bandwidth) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth);
PDEBUG(DUHD, DEBUG_ERROR, "Given TX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth); soapy_close();
soapy_close(); return -EIO;
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 up streamer */ /* see what bandwidth actually is */
if (SoapySDRDevice_setupStream(sdr, &txStream, SOAPY_SDR_TX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) { got_bandwidth = SoapySDRDevice_getBandwidth(sdr, SOAPY_SDR_RX, channel);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); if (got_bandwidth != bandwidth) {
soapy_close(); PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth);
return -EIO; soapy_close();
} return -EINVAL;
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 */ /* set up streamer */
tx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, txStream); if (SoapySDRDevice_setupStream(sdr, &rxStream, SOAPY_SDR_RX, SOAPY_SDR_CF32, &channel, 1, NULL) != 0) {
if (tx_samps_per_buff == 0) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n");
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); soapy_close();
soapy_close(); return -EIO;
return -EIO; }
}
rx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, rxStream); /* get buffer sizes */
if (rx_samps_per_buff == 0) { rx_samps_per_buff = SoapySDRDevice_getStreamMTU(sdr, rxStream);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); if (rx_samps_per_buff == 0) {
soapy_close(); PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n");
return -EIO; soapy_close();
return -EIO;
}
} }
return 0; return 0;

View File

@@ -63,213 +63,248 @@ int uhd_open(const char *device_args, double tx_frequency, double rx_frequency,
return -EIO; return -EIO;
} }
/* create streamers */ if (tx_frequency) {
error = uhd_tx_streamer_make(&tx_streamer); /* create streamers */
if (error) { error = uhd_tx_streamer_make(&tx_streamer);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to create TX streamer\n"); if (error) {
uhd_close(); PDEBUG(DUHD, DEBUG_ERROR, "Failed to create TX streamer\n");
return -EIO; uhd_close();
} return -EIO;
error = uhd_rx_streamer_make(&rx_streamer); }
if (error) {
PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX streamer\n"); /* set rate */
uhd_close(); error = uhd_usrp_set_tx_rate(usrp, rate, channel);
return -EIO; 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 */ if (rx_frequency) {
error = uhd_rx_metadata_make(&rx_metadata); /* create streamers */
if (error) { error = uhd_rx_streamer_make(&rx_streamer);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX metadata\n"); if (error) {
uhd_close(); PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX streamer\n");
return -EIO; uhd_close();
} return -EIO;
}
/* set rate */ /* create metadata */
error = uhd_usrp_set_tx_rate(usrp, rate, channel); error = uhd_rx_metadata_make(&rx_metadata);
if (error) { if (error) {
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX rate to %.0f Hz\n", rate); PDEBUG(DUHD, DEBUG_ERROR, "Failed to create RX metadata\n");
uhd_close(); uhd_close();
return -EIO; 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;
}
/* see what rate actually is */ /* set rate */
error = uhd_usrp_get_tx_rate(usrp, channel, &got_rate); error = uhd_usrp_set_rx_rate(usrp, rate, channel);
if (error) { if (error) {
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX rate\n"); PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX rate to %.0f Hz\n", rate);
uhd_close(); uhd_close();
return -EIO; 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 gain */ /* see what rate actually is */
error = uhd_usrp_set_tx_gain(usrp, tx_gain, channel, ""); error = uhd_usrp_get_rx_rate(usrp, channel, &got_rate);
if (error) { if (error) {
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX gain to %.0f\n", tx_gain); PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX rate\n");
uhd_close(); uhd_close();
return -EIO; return -EIO;
} }
error = uhd_usrp_set_rx_gain(usrp, rx_gain, channel, ""); if (got_rate != rate) {
if (error) { PDEBUG(DUHD, DEBUG_ERROR, "Given RX rate %.0f Hz is not supported, try %0.f Hz\n", rate, got_rate);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain); uhd_close();
uhd_close(); return -EINVAL;
return -EIO; }
}
/* see what gain actually is */ /* set gain */
error = uhd_usrp_get_tx_gain(usrp, channel, "", &got_gain); error = uhd_usrp_set_rx_gain(usrp, rx_gain, channel, "");
if (error) { if (error) {
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX gain\n"); PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX gain to %.0f\n", rx_gain);
uhd_close(); uhd_close();
return -EIO; 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 frequency */ /* see what gain actually is */
memset(&tune_request, 0, sizeof(tune_request)); error = uhd_usrp_get_rx_gain(usrp, channel, "", &got_gain);
tune_request.target_freq = tx_frequency; if (error) {
tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX gain\n");
tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO; uhd_close();
error = uhd_usrp_set_tx_freq(usrp, &tune_request, channel, &tune_result); return -EIO;
if (error) { }
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX frequeny to %.0f Hz\n", tx_frequency); if (got_gain != rx_gain) {
uhd_close(); PDEBUG(DUHD, DEBUG_NOTICE, "Given RX gain %.3f is not supported, we use %.3f\n", rx_gain, got_gain);
return -EIO; rx_gain = got_gain;
} }
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 frequency actually is */ /* set frequency */
error = uhd_usrp_get_tx_freq(usrp, channel, &got_frequency); memset(&tune_request, 0, sizeof(tune_request));
if (error) { tune_request.target_freq = rx_frequency;
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX frequency\n"); tune_request.rf_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
uhd_close(); tune_request.dsp_freq_policy = UHD_TUNE_REQUEST_POLICY_AUTO;
return -EIO; error = uhd_usrp_set_rx_freq(usrp, &tune_request, channel, &tune_result);
} if (error) {
if (got_frequency != tx_frequency) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX frequeny to %.0f Hz\n", rx_frequency);
PDEBUG(DUHD, DEBUG_ERROR, "Given TX frequency %.0f Hz is not supported, try %0.f Hz\n", tx_frequency, got_frequency); uhd_close();
uhd_close(); return -EIO;
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 bandwidth */ /* see what frequency actually is */
if (uhd_usrp_set_tx_bandwidth(usrp, bandwidth, channel) != 0) { error = uhd_usrp_get_rx_freq(usrp, channel, &got_frequency);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX bandwidth to %.0f Hz\n", bandwidth); if (error) {
uhd_close(); PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX frequency\n");
return -EIO; 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); if (got_frequency != rx_frequency) {
uhd_close(); PDEBUG(DUHD, DEBUG_ERROR, "Given RX frequency %.0f Hz is not supported, try %0.f Hz\n", rx_frequency, got_frequency);
return -EIO; uhd_close();
} return -EINVAL;
}
/* see what bandwidth actually is */ /* set bandwidth */
error = uhd_usrp_get_tx_bandwidth(usrp, channel, &got_bandwidth); if (uhd_usrp_set_rx_bandwidth(usrp, bandwidth, channel) != 0) {
if (error) { PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX bandwidth to %.0f Hz\n", bandwidth);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX bandwidth\n"); uhd_close();
uhd_close(); return -EIO;
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 up streamer */ /* see what bandwidth actually is */
memset(&stream_args, 0, sizeof(stream_args)); error = uhd_usrp_get_rx_bandwidth(usrp, channel, &got_bandwidth);
stream_args.cpu_format = "fc32"; if (error) {
stream_args.otw_format = "sc16"; PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX bandwidth\n");
stream_args.args = ""; uhd_close();
stream_args.channel_list = &channel; return -EIO;
stream_args.n_channels = 1; }
error = uhd_usrp_get_tx_stream(usrp, &stream_args, tx_streamer); if (got_bandwidth != bandwidth) {
if (error) { PDEBUG(DUHD, DEBUG_ERROR, "Given RX bandwidth %.0f Hz is not supported, try %0.f Hz\n", bandwidth, got_bandwidth);
PDEBUG(DUHD, DEBUG_ERROR, "Failed to set TX streamer args\n"); uhd_close();
uhd_close(); return -EINVAL;
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;
}
/* get buffer sizes */ /* set up streamer */
error = uhd_tx_streamer_max_num_samps(tx_streamer, &tx_samps_per_buff); memset(&stream_args, 0, sizeof(stream_args));
if (error) { stream_args.cpu_format = "fc32";
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get TX streamer sample buffer\n"); stream_args.otw_format = "sc16";
uhd_close(); stream_args.args = "";
return -EIO; stream_args.channel_list = &channel;
} stream_args.n_channels = 1;
error = uhd_rx_streamer_max_num_samps(rx_streamer, &rx_samps_per_buff); error = uhd_usrp_get_rx_stream(usrp, &stream_args, rx_streamer);
if (error) { if (error) {
PDEBUG(DUHD, DEBUG_ERROR, "Failed to get RX streamer sample buffer\n"); PDEBUG(DUHD, DEBUG_ERROR, "Failed to set RX streamer args\n");
uhd_close(); uhd_close();
return -EIO; 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; return 0;