From 4f1f002ffad12144237352ad096353b8872171be Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Wed, 1 Feb 2023 13:48:11 +0100 Subject: Remove dexter timestamp_state_t --- src/output/Dexter.cpp | 131 ++++++++++++++++++++++++++------------------------ src/output/Dexter.h | 12 ++--- 2 files changed, 72 insertions(+), 71 deletions(-) diff --git a/src/output/Dexter.cpp b/src/output/Dexter.cpp index 5904824..cc10c57 100644 --- a/src/output/Dexter.cpp +++ b/src/output/Dexter.cpp @@ -175,7 +175,16 @@ Dexter::Dexter(SDRDeviceConfig& config) : etiLog.level(warn) << "Failed to set dexter_dsp_tx.stream0_start_clks = " << 0 << " : " << get_iio_error(r); } - // Prepare streams +#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() +{ + 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) { @@ -185,17 +194,23 @@ Dexter::Dexter(SDRDeviceConfig& config) : iio_channel_enable(m_tx_channel); m_buffer = iio_device_create_buffer(m_ad9957_tx0, IIO_BUFFER_LEN/sizeof(int16_t), 0); - if (!m_buffer) { + if (not m_buffer) { throw std::runtime_error("Dexter: Cannot create IIO buffer."); } +} -#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_down() +{ + iio_channel_disable(m_tx_channel); + + etiLog.level(debug) << "DEXTER CHANNEL_DOWN"; + if (m_buffer) { + iio_buffer_destroy(m_buffer); + m_buffer = nullptr; + } } + Dexter::~Dexter() { m_running = false; @@ -208,10 +223,6 @@ Dexter::~Dexter() iio_device_attr_write_longlong(m_dexter_dsp_tx, "gain0", 0); } - if (m_buffer) { - iio_buffer_destroy(m_buffer); - } - iio_context_destroy(m_ctx); m_ctx = nullptr; } @@ -363,67 +374,66 @@ void Dexter::transmit_frame(const struct FrameData& frame) const bool require_timestamped_tx = (m_conf.enableSync and frame.ts.timestamp_valid); - if (not require_timestamped_tx) { - etiLog.level(debug) << "TIMESTAMP_STATE STREAMING 1"; - timestamp_state = timestamp_state_t::STREAMING; - } - else if (require_timestamped_tx and timestamp_state == timestamp_state_t::REQUIRES_SET) { - /* - uint64_t timeS = frame.ts.timestamp_sec; - etiLog.level(debug) << "Dexter: TS S " << timeS << " - " << m_utc_seconds_at_startup << " = " << - timeS - m_utc_seconds_at_startup; - */ - - // 10 because timestamp_pps is represented in 16.384 MHz clocks - constexpr uint64_t TIMESTAMP_PPS_PER_DSP_CLOCKS = DSP_CLOCK / 16384000; - uint64_t frame_ts_clocks = - // at second level - ((int64_t)frame.ts.timestamp_sec - (int64_t)m_utc_seconds_at_startup) * DSP_CLOCK + m_clock_count_at_startup + - // at subsecond level - (uint64_t)frame.ts.timestamp_pps * TIMESTAMP_PPS_PER_DSP_CLOCKS; - - long long pps_clks = 0; - int r; - if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "pps_clks", &pps_clks)) != 0) { - etiLog.level(error) << "Failed to get dexter_dsp_tx.pps_clks: " << get_iio_error(r); - } + if (m_buffer == nullptr) { + if (require_timestamped_tx) { + /* + uint64_t timeS = frame.ts.timestamp_sec; + etiLog.level(debug) << "Dexter: TS S " << timeS << " - " << m_utc_seconds_at_startup << " = " << + timeS - m_utc_seconds_at_startup; + */ + + // 10 because timestamp_pps is represented in 16.384 MHz clocks + constexpr uint64_t TIMESTAMP_PPS_PER_DSP_CLOCKS = DSP_CLOCK / 16384000; + uint64_t frame_ts_clocks = + // at second level + ((int64_t)frame.ts.timestamp_sec - (int64_t)m_utc_seconds_at_startup) * DSP_CLOCK + m_clock_count_at_startup + + // at subsecond level + (uint64_t)frame.ts.timestamp_pps * TIMESTAMP_PPS_PER_DSP_CLOCKS; + + long long pps_clks = 0; + int r; + if ((r = iio_device_attr_read_longlong(m_dexter_dsp_tx, "pps_clks", &pps_clks)) != 0) { + etiLog.level(error) << "Failed to get dexter_dsp_tx.pps_clks: " << get_iio_error(r); + } - const double margin = (double)((int64_t)frame_ts_clocks - pps_clks) / DSP_CLOCK; + const double margin = (double)((int64_t)frame_ts_clocks - pps_clks) / DSP_CLOCK; - etiLog.level(debug) << "Dexter: TS CLK " << - ((int64_t)frame.ts.timestamp_sec - (int64_t)m_utc_seconds_at_startup) * DSP_CLOCK << " + " << - m_clock_count_at_startup << " + " << - (uint64_t)frame.ts.timestamp_pps * TIMESTAMP_PPS_PER_DSP_CLOCKS << " = " << - frame_ts_clocks << " DELTA " << - frame_ts_clocks << " - " << pps_clks << " = " << margin; + etiLog.level(debug) << "Dexter: TS CLK " << + ((int64_t)frame.ts.timestamp_sec - (int64_t)m_utc_seconds_at_startup) * DSP_CLOCK << " + " << + m_clock_count_at_startup << " + " << + (uint64_t)frame.ts.timestamp_pps * TIMESTAMP_PPS_PER_DSP_CLOCKS << " = " << + frame_ts_clocks << " DELTA " << + frame_ts_clocks << " - " << pps_clks << " = " << margin; - // Ensure we hand the frame over to HW at least 0.2s before timestamp - if (margin < 0.2) { - etiLog.level(warn) << "Skip frame short margin " << margin; - num_late++; - return; - } + // Ensure we hand the frame over to HW at least 0.2s before timestamp + if (margin < 0.2) { + etiLog.level(warn) << "Skip frame short margin " << margin; + num_late++; + return; + } - if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "stream0_start_clks", frame_ts_clocks)) != 0) { - etiLog.level(warn) << "Skip frame, failed to set dexter_dsp_tx.stream0_start_clks = " << frame_ts_clocks << " : " << get_iio_error(r); - num_late++; - return; + if ((r = iio_device_attr_write_longlong(m_dexter_dsp_tx, "stream0_start_clks", frame_ts_clocks)) != 0) { + etiLog.level(warn) << "Skip frame, failed to set dexter_dsp_tx.stream0_start_clks = " << frame_ts_clocks << " : " << get_iio_error(r); + num_late++; + return; + } } - timestamp_state = timestamp_state_t::STREAMING; - etiLog.level(debug) << "TIMESTAMP_STATE STREAMING 2"; + + channel_up(); } if (m_require_timestamp_refresh) { - etiLog.level(debug) << "TIMESTAMP_STATE WAIT_FOR_UNDERRUN"; - timestamp_state = timestamp_state_t::WAIT_FOR_UNDERRUN; + etiLog.level(debug) << "DEXTER REQUIRE REFRESH"; + channel_down(); + m_require_timestamp_refresh = false; } // DabMod::launch_modulator ensures we get int16_t IQ here //const size_t num_samples = frame.buf.size() / (2*sizeof(int16_t)); //const int16_t *buf = reinterpret_cast(frame.buf.data()); - if (timestamp_state == timestamp_state_t::STREAMING) { + if (m_buffer) { for (size_t i = 0; i < IIO_BUFFERS; i++) { constexpr size_t buflen = TRANSMISSION_FRAME_LEN / IIO_BUFFERS; @@ -433,8 +443,7 @@ void Dexter::transmit_frame(const struct FrameData& frame) etiLog.level(error) << "Dexter: failed to push buffer " << get_iio_error(pushed) << " after " << num_buffers_pushed << " bufs"; num_buffers_pushed = 0; - etiLog.level(debug) << "TIMESTAMP_STATE REQUIRES_SET"; - timestamp_state = timestamp_state_t::REQUIRES_SET; + channel_down(); break; } num_buffers_pushed++; @@ -449,10 +458,6 @@ void Dexter::transmit_frame(const struct FrameData& frame) if (u != 0 and u != prev_underflows) { etiLog.level(warn) << "Dexter: underflow! " << prev_underflows << " -> " << u; - if (timestamp_state == timestamp_state_t::WAIT_FOR_UNDERRUN) { - etiLog.level(debug) << "TIMESTAMP_STATE REQUIRES_SET"; - timestamp_state = timestamp_state_t::REQUIRES_SET; - } } prev_underflows = u; diff --git a/src/output/Dexter.h b/src/output/Dexter.h index a3c827b..36d0ef7 100644 --- a/src/output/Dexter.h +++ b/src/output/Dexter.h @@ -83,6 +83,10 @@ class Dexter : public Output::SDRDevice virtual double get_temperature() const override; private: + + void channel_up(); + void channel_down(); + SDRDeviceConfig& m_conf; struct iio_context* m_ctx = nullptr; @@ -108,14 +112,6 @@ class Dexter : public Output::SDRDevice uint64_t m_utc_seconds_at_startup; uint64_t m_clock_count_at_startup = 0; uint64_t m_clock_count_frame = 0; - - enum class timestamp_state_t { - REQUIRES_SET, - STREAMING, - WAIT_FOR_UNDERRUN, - }; - - timestamp_state_t timestamp_state = timestamp_state_t::REQUIRES_SET; }; } // namespace Output -- cgit v1.2.3