diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2023-03-24 10:31:24 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2023-03-24 10:31:24 +0100 |
commit | ed8e8bed00d5ad47a9d4798059fd0e3a8c3f7b8c (patch) | |
tree | 1ad0ca394f2be41b1098c971906298c790617751 | |
parent | 4b3465e0a9e79f18398819f3bd0957efc9952928 (diff) | |
download | dabmod-ed8e8bed00d5ad47a9d4798059fd0e3a8c3f7b8c.tar.gz dabmod-ed8e8bed00d5ad47a9d4798059fd0e3a8c3f7b8c.tar.bz2 dabmod-ed8e8bed00d5ad47a9d4798059fd0e3a8c3f7b8c.zip |
Fix startup hiccup due to iio buffer allocation taking several seconds
-rw-r--r-- | src/output/Dexter.cpp | 105 | ||||
-rw-r--r-- | src/output/Dexter.h | 3 | ||||
-rw-r--r-- | src/output/SDR.cpp | 2 |
3 files changed, 75 insertions, 35 deletions
diff --git a/src/output/Dexter.cpp b/src/output/Dexter.cpp index aa0b7ad..93f1bb6 100644 --- a/src/output/Dexter.cpp +++ b/src/output/Dexter.cpp @@ -48,9 +48,9 @@ static constexpr uint64_t DSP_CLOCK = 2048000uLL * 80; static constexpr uint64_t IIO_TIMEOUT_MS = 1000; -static constexpr size_t TRANSMISSION_FRAME_LEN = (2656 + 76 * 2552) * 4; -static constexpr size_t IIO_BUFFERS = 4; -static constexpr size_t IIO_BUFFER_LEN = TRANSMISSION_FRAME_LEN / IIO_BUFFERS; +static constexpr size_t TRANSMISSION_FRAME_LEN_SAMPS = (2656 + 76 * 2552) * /* I+Q */ 2; +static constexpr size_t IIO_BUFFERS = 2; +static constexpr size_t IIO_BUFFER_LEN_SAMPS = TRANSMISSION_FRAME_LEN_SAMPS / IIO_BUFFERS; static string get_iio_error(int err) { @@ -73,7 +73,7 @@ Dexter::Dexter(SDRDeviceConfig& config) : etiLog.level(info) << "Dexter:Creating the device"; m_ctx = iio_create_local_context(); - if (!m_ctx) { + if (not m_ctx) { throw std::runtime_error("Dexter: Unable to create iio scan context"); } @@ -83,12 +83,12 @@ Dexter::Dexter(SDRDeviceConfig& config) : } m_dexter_dsp_tx = iio_context_find_device(m_ctx, "dexter_dsp_tx"); - if (!m_dexter_dsp_tx) { + if (not m_dexter_dsp_tx) { throw std::runtime_error("Dexter: Unable to find dexter_dsp_tx iio device"); } m_ad9957_tx0 = iio_context_find_device(m_ctx, "ad9957_tx0"); - if (!m_ad9957_tx0) { + if (not m_ad9957_tx0) { throw std::runtime_error("Dexter: Unable to find ad9957_tx0 iio device"); } @@ -101,10 +101,6 @@ Dexter::Dexter(SDRDeviceConfig& config) : etiLog.level(warn) << "Failed to set dexter_dsp_tx.dc1 = false: " << get_iio_error(r); } - if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", m_conf.txgain)) != 0) { - etiLog.level(error) << "Failed to set dexter_dsp_tx.gain0 = 0: " << get_iio_error(r); - } - if (m_conf.sampleRate != 2048000) { throw std::runtime_error("Dexter: Only 2048000 samplerate supported"); } @@ -176,16 +172,11 @@ Dexter::Dexter(SDRDeviceConfig& config) : etiLog.level(warn) << "Failed to set dexter_dsp_tx.stream0_start_clks = " << 0 << " : " << get_iio_error(r); } -#warning "TODO underflow thread" - /* Disabled because it still provokes failed to push buffer Unknown error -110 - m_running = true; - m_underflow_read_thread = std::thread(&Dexter::underflow_read_process, this); - */ -} + if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", 0)) != 0) { + etiLog.level(error) << "Failed to set dexter_dsp_tx.gain0 = 0" << + " : " << get_iio_error(r); + } -void Dexter::channel_up() -{ - etiLog.level(debug) << "DEXTER CHANNEL_UP"; constexpr int CHANNEL_INDEX = 0; m_tx_channel = iio_device_get_channel(m_ad9957_tx0, CHANNEL_INDEX); if (m_tx_channel == nullptr) { @@ -194,21 +185,62 @@ void Dexter::channel_up() iio_channel_enable(m_tx_channel); - m_buffer = iio_device_create_buffer(m_ad9957_tx0, IIO_BUFFER_LEN/sizeof(int16_t), 0); + m_buffer = iio_device_create_buffer(m_ad9957_tx0, IIO_BUFFER_LEN_SAMPS, 0); if (not m_buffer) { throw std::runtime_error("Dexter: Cannot create IIO buffer."); } + + // Flush the FPGA FIFO + { + constexpr size_t buflen_samps = TRANSMISSION_FRAME_LEN_SAMPS / IIO_BUFFERS; + constexpr size_t buflen = buflen_samps * sizeof(int16_t); + + memset(iio_buffer_start(m_buffer), 0, buflen); + ssize_t pushed = iio_buffer_push(m_buffer); + if (pushed < 0) { + etiLog.level(error) << "Dexter: init push buffer " << get_iio_error(pushed); + } + this_thread::sleep_for(chrono::milliseconds(200)); + } + + if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", m_conf.txgain)) != 0) { + etiLog.level(error) << "Failed to set dexter_dsp_tx.gain0 = " << m_conf.txgain << + " : " << get_iio_error(r); + } + +#warning "TODO underflow thread" + /* Disabled because it still provokes failed to push buffer Unknown error -110 + m_running = true; + m_underflow_read_thread = std::thread(&Dexter::underflow_read_process, this); + */ +} + +void Dexter::channel_up() +{ + int r; + if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", m_conf.txgain)) != 0) { + etiLog.level(error) << "Failed to set dexter_dsp_tx.gain0 = " << m_conf.txgain << + " : " << get_iio_error(r); + } + + m_channel_is_up = true; + etiLog.level(debug) << "DEXTER CHANNEL_UP"; } void Dexter::channel_down() { - iio_channel_disable(m_tx_channel); + int r; + if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", 0)) != 0) { + etiLog.level(error) << "Failed to set dexter_dsp_tx.gain0 = 0: " << get_iio_error(r); + } - etiLog.level(debug) << "DEXTER CHANNEL_DOWN"; - if (m_buffer) { - iio_buffer_destroy(m_buffer); - m_buffer = nullptr; + // This will flush out the FIFO + if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "stream0_start_clks", 0)) != 0) { + etiLog.level(warn) << "Failed to set dexter_dsp_tx.stream0_start_clks = 0 : " << get_iio_error(r); } + + m_channel_is_up = false; + etiLog.level(debug) << "DEXTER CHANNEL_DOWN"; } @@ -224,6 +256,11 @@ Dexter::~Dexter() iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", 0); } + if (m_buffer) { + iio_buffer_destroy(m_buffer); + m_buffer = nullptr; + } + iio_context_destroy(m_ctx); m_ctx = nullptr; } @@ -259,12 +296,12 @@ void Dexter::set_txgain(double txgain) { int r = 0; if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", txgain)) != 0) { - etiLog.level(warn) << "Failed to set dexter_dsp_tx.stream0_start_clks = 0: " << get_iio_error(r); + etiLog.level(warn) << "Failed to set dexter_dsp_tx.gain0 = 0: " << get_iio_error(r); } long long txgain_readback = 0; if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "gain0", &txgain_readback)) != 0) { - etiLog.level(warn) << "Failed to set dexter_dsp_tx.stream0_start_clks = 0: " << get_iio_error(r); + etiLog.level(warn) << "Failed to set dexter_dsp_tx.gain0 = 0: " << get_iio_error(r); } else { m_conf.txgain = txgain_readback; @@ -276,7 +313,7 @@ double Dexter::get_txgain(void) const long long txgain_readback = 0; int r = 0; if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "gain0", &txgain_readback)) != 0) { - etiLog.level(warn) << "Failed to set dexter_dsp_tx.stream0_start_clks = 0: " << get_iio_error(r); + etiLog.level(warn) << "Failed to set dexter_dsp_tx.gain0 = 0: " << get_iio_error(r); } return txgain_readback; } @@ -367,9 +404,10 @@ double Dexter::get_temperature(void) const void Dexter::transmit_frame(struct FrameData&& frame) { - if (frame.buf.size() != TRANSMISSION_FRAME_LEN) { + constexpr size_t frame_len_bytes = TRANSMISSION_FRAME_LEN_SAMPS * sizeof(int16_t); + if (frame.buf.size() != frame_len_bytes) { etiLog.level(debug) << "Dexter::transmit_frame Expected " << - TRANSMISSION_FRAME_LEN << " got " << frame.buf.size(); + frame_len_bytes << " got " << frame.buf.size(); throw std::runtime_error("Dexter: invalid buffer size"); } @@ -377,7 +415,7 @@ void Dexter::transmit_frame(struct FrameData&& frame) const double margin_s = frame.ts.offset_to_system_time(); - if (m_buffer == nullptr) { + if (not m_channel_is_up) { if (require_timestamped_tx) { /* uint64_t timeS = frame.ts.timestamp_sec; @@ -430,9 +468,10 @@ void Dexter::transmit_frame(struct FrameData&& frame) //const size_t num_samples = frame.buf.size() / (2*sizeof(int16_t)); //const int16_t *buf = reinterpret_cast<const int16_t*>(frame.buf.data()); - if (m_buffer) { + if (m_channel_is_up) { for (size_t i = 0; i < IIO_BUFFERS; i++) { - constexpr size_t buflen = TRANSMISSION_FRAME_LEN / IIO_BUFFERS; + constexpr size_t buflen_samps = TRANSMISSION_FRAME_LEN_SAMPS / IIO_BUFFERS; + constexpr size_t buflen = buflen_samps * sizeof(int16_t); memcpy(iio_buffer_start(m_buffer), frame.buf.data() + (i * buflen), buflen); ssize_t pushed = iio_buffer_push(m_buffer); diff --git a/src/output/Dexter.h b/src/output/Dexter.h index 2bd63b1..2f0524e 100644 --- a/src/output/Dexter.h +++ b/src/output/Dexter.h @@ -83,10 +83,11 @@ class Dexter : public Output::SDRDevice virtual double get_temperature() const override; private: - void channel_up(); void channel_down(); + bool m_channel_is_up = false; + SDRDeviceConfig& m_conf; struct iio_context* m_ctx = nullptr; diff --git a/src/output/SDR.cpp b/src/output/SDR.cpp index e22617e..f53197e 100644 --- a/src/output/SDR.cpp +++ b/src/output/SDR.cpp @@ -165,7 +165,7 @@ meta_vec_t SDR::process_metadata(const meta_vec_t& metadataIn) const auto max_size = m_config.enableSync ? - (frame.ts.timestamp_offset * 4.0) / frame_duration_s + (frame.ts.timestamp_offset * 400.0) / frame_duration_s : FRAMES_MAX_SIZE; auto r = m_queue.push_overflow(std::move(frame), max_size); |