From a0f059b34bac2df04074b14b9f3c2b41d370d181 Mon Sep 17 00:00:00 2001 From: Alexander Hurd Date: Sat, 16 Jun 2018 20:30:32 -0400 Subject: [PATCH] adding iq_swap setting --- Settings.cpp | 23 ++++++++++++++++++++++- SoapySidekiq.hpp | 3 +++ Streaming.cpp | 42 +++++++++++++++++++++++++++--------------- 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Settings.cpp b/Settings.cpp index b4526ca..305b94f 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -16,6 +16,8 @@ SoapySidekiq::SoapySidekiq(const SoapySDR::Kwargs &args) { tx_bandwidth = 2048000; tx_center_frequency = 100000000; + iq_swap = false; + // this may change later according to format shortsPerWord = 1; bufferLength = bufferElems * elementsPerSample * shortsPerWord; @@ -444,12 +446,31 @@ std::vector SoapySidekiq::listBandwidths(const int direction, const size SoapySDR::ArgInfoList SoapySidekiq::getSettingInfo(void) const { SoapySDR::ArgInfoList setArgs; + SoapySDR::ArgInfo iqSwapArg; + + iqSwapArg.key = "iq_swap"; + iqSwapArg.value = "false"; + iqSwapArg.name = "I/Q Swap"; + iqSwapArg.description = "I/Q Swap Mode"; + iqSwapArg.type = SoapySDR::ArgInfo::BOOL; + + setArgs.push_back(iqSwapArg); + return setArgs; } void SoapySidekiq::writeSetting(const std::string &key, const std::string &value) { + if (key == "iq_swap") { + iq_swap = ((value == "true") ? true : false); + SoapySDR_logf(SOAPY_SDR_DEBUG, "I/Q swap: %s", iq_swap ? "true" : "false"); + } } std::string SoapySidekiq::readSetting(const std::string &key) const { - return SoapySDR::Device::readSetting(key); + if (key == "iq_swap") { + return iq_swap ? "true" : "false"; + } + + SoapySDR_logf(SOAPY_SDR_WARNING, "Unknown setting '%s'", key.c_str()); + return ""; } diff --git a/SoapySidekiq.hpp b/SoapySidekiq.hpp index 993a6a0..a432616 100644 --- a/SoapySidekiq.hpp +++ b/SoapySidekiq.hpp @@ -206,6 +206,9 @@ class SoapySidekiq : public SoapySDR::Device { uint64_t tx_center_frequency; uint32_t tx_sample_rate, tx_bandwidth; + // setting + bool iq_swap; + // buffer size_t numBuffers; const unsigned int bufferElems = DEFAULT_BUFFER_LENGTH; diff --git a/Streaming.cpp b/Streaming.cpp index c898bf7..8cd83ee 100644 --- a/Streaming.cpp +++ b/Streaming.cpp @@ -64,13 +64,13 @@ void SoapySidekiq::rx_receive_operation(void) { SoapySDR_logf(SOAPY_SDR_ERROR, "Failure: skiq_start_rx_streaming (card %d)", card); } - //skiq receive params + // skiq receive params skiq_rx_block_t *p_rx_block; uint32_t len; - // loop until stream is deactivated + // loop until stream is deactivated while (rx_running) { - // check for overflow + // check for overflow if (_buf_count == numBuffers) { SoapySDR_log(SOAPY_SDR_WARNING, "Detected overflow Event in RX Sidekiq Thread"); _overflowEvent = true; @@ -78,20 +78,20 @@ void SoapySidekiq::rx_receive_operation(void) { /* blocking skiq_receive */ if (skiq_receive(card, &rx_hdl, &p_rx_block, &len) == skiq_rx_status_success) { - // number of i and q samples + // number of i and q samples uint32_t num_samples = (len - SKIQ_RX_HEADER_SIZE_IN_BYTES) / sizeof(int16_t); - // buffer space required + // buffer space required uint32_t space_req = num_samples * elementsPerSample * shortsPerWord; - // buf mutex + // buf mutex { std::lock_guard lock(_buf_mutex); // check if we need to move on to next buffer in ring if ((_buffs[_buf_tail].size() + space_req) >= (bufferLength)) { SoapySDR_logf(SOAPY_SDR_TRACE, "Rotating Buffer Ring %d", _buf_count.load()); - // increment the tail pointer and buffer count + // increment the tail pointer and buffer count _buf_tail = (_buf_tail + 1) % numBuffers; _buf_count++; @@ -99,24 +99,36 @@ void SoapySidekiq::rx_receive_operation(void) { _buf_cond.notify_one(); } - // get current fill buffer + // get current fill buffer auto &buff = _buffs[_buf_tail]; buff.resize(buff.size() + space_req); // copy into the buffer queue unsigned int i = 0; - if (useShort) { + if (useShort) { // int16_t int16_t *dptr = buff.data(); dptr += (buff.size() - space_req); - for (i = 0; i < num_samples; i++) { - *dptr++ = p_rx_block->data[i]; // copy qi data to buffer + for (i = 0; i < (num_samples / elementsPerSample); i++) { + if (iq_swap) { + dptr[i * 2] = p_rx_block->data[i * 2 + 1]; // I + dptr[i * 2 + 1] = p_rx_block->data[i * 2]; // Q + } else { + dptr[i * 2] = p_rx_block->data[i * 2]; // Q + dptr[i * 2 + 1] = p_rx_block->data[i * 2 + 1]; // I + } } - } else { + } else { // float float *dptr = (float *) buff.data(); dptr += ((buff.size() - space_req) / shortsPerWord); - for (i = 0; i < num_samples; i++) { - *dptr++ = (float) p_rx_block->data[i] / 32768.0f; // convert qi to float + for (i = 0; i < (num_samples / elementsPerSample); i++) { + if (iq_swap) { + dptr[i * 2] = (float)p_rx_block->data[i * 2 + 1] / 32768.0f ; // I + dptr[i * 2 + 1] = (float)p_rx_block->data[i * 2]/ 32768.0f; // Q + } else { + dptr[i * 2] = (float)p_rx_block->data[i * 2] / 32768.0f ; // Q + dptr[i * 2 + 1] = (float)p_rx_block->data[i * 2 + 1] / 32768.0f; // I + } } } } @@ -234,7 +246,7 @@ int SoapySidekiq::deactivateStream(SoapySDR::Stream *stream, const int flags, co } /* stop rx streaming */ - if(skiq_stop_rx_streaming(card, rx_hdl) < 0){ + if (skiq_stop_rx_streaming(card, rx_hdl) < 0) { SoapySDR_logf(SOAPY_SDR_ERROR, "Failure: skiq_stop_rx_streaming (card %d)", card); }