<p>Pau Espin Pedrol has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13809">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cosmetic: uhd: Move smpl_buf out of UHDDevice, move UHDDevice class definition to .h<br><br>* move class definition to .h file, like we do for other devices.<br>* move smpl_buf class to a different file inside uhd/.<br>* Preparation work to have smpl_buf being used in a generic way for<br>devices other than UHD (LMS).<br><br>Change-Id: Ib4594320da9bb7f6e9f52e7d70d11ecd11106aae<br>---<br>M Transceiver52M/device/uhd/Makefile.am<br>M Transceiver52M/device/uhd/UHDDevice.cpp<br>A Transceiver52M/device/uhd/UHDDevice.h<br>A Transceiver52M/device/uhd/smpl_buf.cpp<br>A Transceiver52M/device/uhd/smpl_buf.h<br>5 files changed, 418 insertions(+), 362 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/09/13809/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/Transceiver52M/device/uhd/Makefile.am b/Transceiver52M/device/uhd/Makefile.am</span><br><span>index bb34d2f..4fcc0d7 100644</span><br><span>--- a/Transceiver52M/device/uhd/Makefile.am</span><br><span>+++ b/Transceiver52M/device/uhd/Makefile.am</span><br><span>@@ -3,6 +3,8 @@</span><br><span> AM_CPPFLAGS = -Wall $(STD_DEFINES_AND_INCLUDES) -I${srcdir}/..</span><br><span> AM_CXXFLAGS = -lpthread $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(UHD_CFLAGS)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+noinst_HEADERS = UHDDevice.h smpl_buf.h</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> noinst_LTLIBRARIES = libdevice.la</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-libdevice_la_SOURCES = UHDDevice.cpp</span><br><span style="color: hsl(120, 100%, 40%);">+libdevice_la_SOURCES = UHDDevice.cpp smpl_buf.cpp</span><br><span>diff --git a/Transceiver52M/device/uhd/UHDDevice.cpp b/Transceiver52M/device/uhd/UHDDevice.cpp</span><br><span>index 46284e5..67b7416 100644</span><br><span>--- a/Transceiver52M/device/uhd/UHDDevice.cpp</span><br><span>+++ b/Transceiver52M/device/uhd/UHDDevice.cpp</span><br><span>@@ -23,11 +23,9 @@</span><br><span> </span><br><span> #include <map></span><br><span> #include "radioDevice.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "UHDDevice.h"</span><br><span> #include "Threads.h"</span><br><span> #include "Logger.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include <uhd/version.hpp></span><br><span style="color: hsl(0, 100%, 40%);">-#include <uhd/property_tree.hpp></span><br><span style="color: hsl(0, 100%, 40%);">-#include <uhd/usrp/multi_usrp.hpp></span><br><span> </span><br><span> #ifdef HAVE_CONFIG_H</span><br><span> #include "config.h"</span><br><span>@@ -58,20 +56,6 @@</span><br><span>  */</span><br><span> #define UMTRX_VGA1_DEF   -18</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-enum uhd_dev_type {</span><br><span style="color: hsl(0, 100%, 40%);">- USRP1,</span><br><span style="color: hsl(0, 100%, 40%);">-  USRP2,</span><br><span style="color: hsl(0, 100%, 40%);">-  B100,</span><br><span style="color: hsl(0, 100%, 40%);">-   B200,</span><br><span style="color: hsl(0, 100%, 40%);">-   B210,</span><br><span style="color: hsl(0, 100%, 40%);">-   B2XX_MCBTS,</span><br><span style="color: hsl(0, 100%, 40%);">-     E1XX,</span><br><span style="color: hsl(0, 100%, 40%);">-   E3XX,</span><br><span style="color: hsl(0, 100%, 40%);">-   X3XX,</span><br><span style="color: hsl(0, 100%, 40%);">-   UMTRX,</span><br><span style="color: hsl(0, 100%, 40%);">-  LIMESDR,</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /*</span><br><span>  * USRP version dependent device timings</span><br><span>  */</span><br><span>@@ -136,190 +120,6 @@</span><br><span>  { std::make_tuple(B2XX_MCBTS, 4, 4), { 1, 51.2e6, MCBTS_SPACING*4, B2XX_TIMING_MCBTS, "B200/B210 4 SPS Multi-ARFCN" } },</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">-    Sample Buffer - Allows reading and writing of timed samples using osmo-trx</span><br><span style="color: hsl(0, 100%, 40%);">-                    or UHD style timestamps. Time conversions are handled</span><br><span style="color: hsl(0, 100%, 40%);">-                    internally or accessable through the static convert calls.</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-class smpl_buf {</span><br><span style="color: hsl(0, 100%, 40%);">-public:</span><br><span style="color: hsl(0, 100%, 40%);">-    /** Sample buffer constructor</span><br><span style="color: hsl(0, 100%, 40%);">-       @param len number of 32-bit samples the buffer should hold</span><br><span style="color: hsl(0, 100%, 40%);">-      @param rate sample clockrate</span><br><span style="color: hsl(0, 100%, 40%);">-            @param timestamp</span><br><span style="color: hsl(0, 100%, 40%);">-    */</span><br><span style="color: hsl(0, 100%, 40%);">-      smpl_buf(size_t len, double rate);</span><br><span style="color: hsl(0, 100%, 40%);">-      ~smpl_buf();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /** Query number of samples available for reading</span><br><span style="color: hsl(0, 100%, 40%);">-           @param timestamp time of first sample</span><br><span style="color: hsl(0, 100%, 40%);">-           @return number of available samples or error</span><br><span style="color: hsl(0, 100%, 40%);">-        */</span><br><span style="color: hsl(0, 100%, 40%);">-      ssize_t avail_smpls(TIMESTAMP timestamp) const;</span><br><span style="color: hsl(0, 100%, 40%);">- ssize_t avail_smpls(uhd::time_spec_t timestamp) const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /** Read and write</span><br><span style="color: hsl(0, 100%, 40%);">-          @param buf pointer to buffer</span><br><span style="color: hsl(0, 100%, 40%);">-            @param len number of samples desired to read or write</span><br><span style="color: hsl(0, 100%, 40%);">-           @param timestamp time of first stample</span><br><span style="color: hsl(0, 100%, 40%);">-          @return number of actual samples read or written or error</span><br><span style="color: hsl(0, 100%, 40%);">-   */</span><br><span style="color: hsl(0, 100%, 40%);">-      ssize_t read(void *buf, size_t len, TIMESTAMP timestamp);</span><br><span style="color: hsl(0, 100%, 40%);">-       ssize_t read(void *buf, size_t len, uhd::time_spec_t timestamp);</span><br><span style="color: hsl(0, 100%, 40%);">-        ssize_t write(void *buf, size_t len, TIMESTAMP timestamp);</span><br><span style="color: hsl(0, 100%, 40%);">-      ssize_t write(void *buf, size_t len, uhd::time_spec_t timestamp);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /** Buffer status string</span><br><span style="color: hsl(0, 100%, 40%);">-            @return a formatted string describing internal buffer state</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-      std::string str_status(size_t ts) const;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        /** Formatted error string</span><br><span style="color: hsl(0, 100%, 40%);">-          @param code an error code</span><br><span style="color: hsl(0, 100%, 40%);">-       @return a formatted error string</span><br><span style="color: hsl(0, 100%, 40%);">-    */</span><br><span style="color: hsl(0, 100%, 40%);">-      static std::string str_code(ssize_t code);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      enum err_code {</span><br><span style="color: hsl(0, 100%, 40%);">-         ERROR_TIMESTAMP = -1,</span><br><span style="color: hsl(0, 100%, 40%);">-           ERROR_READ = -2,</span><br><span style="color: hsl(0, 100%, 40%);">-                ERROR_WRITE = -3,</span><br><span style="color: hsl(0, 100%, 40%);">-               ERROR_OVERFLOW = -4</span><br><span style="color: hsl(0, 100%, 40%);">-     };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private:</span><br><span style="color: hsl(0, 100%, 40%);">-      uint32_t *data;</span><br><span style="color: hsl(0, 100%, 40%);">- size_t buf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- double clk_rt;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  TIMESTAMP time_start;</span><br><span style="color: hsl(0, 100%, 40%);">-   TIMESTAMP time_end;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     size_t data_start;</span><br><span style="color: hsl(0, 100%, 40%);">-      size_t data_end;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">-    uhd_device - UHD implementation of the Device interface. Timestamped samples</span><br><span style="color: hsl(0, 100%, 40%);">-                are sent to and received from the device. An intermediate buffer</span><br><span style="color: hsl(0, 100%, 40%);">-                on the receive side collects and aligns packets of samples.</span><br><span style="color: hsl(0, 100%, 40%);">-                Events and errors such as underruns are reported asynchronously</span><br><span style="color: hsl(0, 100%, 40%);">-                by the device and received in a separate thread.</span><br><span style="color: hsl(0, 100%, 40%);">-*/</span><br><span style="color: hsl(0, 100%, 40%);">-class uhd_device : public RadioDevice {</span><br><span style="color: hsl(0, 100%, 40%);">-public:</span><br><span style="color: hsl(0, 100%, 40%);">-  uhd_device(size_t tx_sps, size_t rx_sps, InterfaceType type,</span><br><span style="color: hsl(0, 100%, 40%);">-               size_t chans, double offset,</span><br><span style="color: hsl(0, 100%, 40%);">-            const std::vector<std::string>& tx_paths,</span><br><span style="color: hsl(0, 100%, 40%);">-             const std::vector<std::string>& rx_paths);</span><br><span style="color: hsl(0, 100%, 40%);">- ~uhd_device();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  int open(const std::string &args, int ref, bool swap_channels);</span><br><span style="color: hsl(0, 100%, 40%);">-     bool start();</span><br><span style="color: hsl(0, 100%, 40%);">-   bool stop();</span><br><span style="color: hsl(0, 100%, 40%);">-    bool restart();</span><br><span style="color: hsl(0, 100%, 40%);">- void setPriority(float prio);</span><br><span style="color: hsl(0, 100%, 40%);">-   enum TxWindowType getWindowType() { return tx_window; }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- int readSamples(std::vector<short *> &bufs, int len, bool *overrun,</span><br><span style="color: hsl(0, 100%, 40%);">-                   TIMESTAMP timestamp, bool *underrun, unsigned *RSSI);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   int writeSamples(std::vector<short *> &bufs, int len, bool *underrun,</span><br><span style="color: hsl(0, 100%, 40%);">-                  TIMESTAMP timestamp, bool isControl);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bool updateAlignment(TIMESTAMP timestamp);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      bool setTxFreq(double wFreq, size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-      bool setRxFreq(double wFreq, size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      TIMESTAMP initialWriteTimestamp();</span><br><span style="color: hsl(0, 100%, 40%);">-      TIMESTAMP initialReadTimestamp();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       double fullScaleInputValue();</span><br><span style="color: hsl(0, 100%, 40%);">-   double fullScaleOutputValue();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  double setRxGain(double db, size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-       double getRxGain(size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-  double maxRxGain(void) { return rx_gain_max; }</span><br><span style="color: hsl(0, 100%, 40%);">-  double minRxGain(void) { return rx_gain_min; }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  double setTxGain(double db, size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-       double maxTxGain(void) { return tx_gain_max; }</span><br><span style="color: hsl(0, 100%, 40%);">-  double minTxGain(void) { return tx_gain_min; }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  double getTxFreq(size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-  double getRxFreq(size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-  double getRxFreq();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     bool setRxAntenna(const std::string &ant, size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-     std::string getRxAntenna(size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-  bool setTxAntenna(const std::string &ant, size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-     std::string getTxAntenna(size_t chan);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bool requiresRadioAlign();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      GSM::Time minLatency();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- inline double getSampleRate() { return tx_rate; }</span><br><span style="color: hsl(0, 100%, 40%);">-       inline double numberRead() { return rx_pkt_cnt; }</span><br><span style="color: hsl(0, 100%, 40%);">-       inline double numberWritten() { return 0; }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     /** Receive and process asynchronous message</span><br><span style="color: hsl(0, 100%, 40%);">-        @return true if message received or false on timeout or error</span><br><span style="color: hsl(0, 100%, 40%);">-       */</span><br><span style="color: hsl(0, 100%, 40%);">-      bool recv_async_msg();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  enum err_code {</span><br><span style="color: hsl(0, 100%, 40%);">-         ERROR_TIMING = -1,</span><br><span style="color: hsl(0, 100%, 40%);">-              ERROR_TIMEOUT = -2,</span><br><span style="color: hsl(0, 100%, 40%);">-             ERROR_UNRECOVERABLE = -3,</span><br><span style="color: hsl(0, 100%, 40%);">-               ERROR_UNHANDLED = -4,</span><br><span style="color: hsl(0, 100%, 40%);">-   };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-private:</span><br><span style="color: hsl(0, 100%, 40%);">-      uhd::usrp::multi_usrp::sptr usrp_dev;</span><br><span style="color: hsl(0, 100%, 40%);">-   uhd::tx_streamer::sptr tx_stream;</span><br><span style="color: hsl(0, 100%, 40%);">-       uhd::rx_streamer::sptr rx_stream;</span><br><span style="color: hsl(0, 100%, 40%);">-       enum TxWindowType tx_window;</span><br><span style="color: hsl(0, 100%, 40%);">-    enum uhd_dev_type dev_type;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     double tx_rate, rx_rate;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        double tx_gain_min, tx_gain_max;</span><br><span style="color: hsl(0, 100%, 40%);">-        double rx_gain_min, rx_gain_max;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        std::vector<double> tx_gains, rx_gains;</span><br><span style="color: hsl(0, 100%, 40%);">-   std::vector<double> tx_freqs, rx_freqs;</span><br><span style="color: hsl(0, 100%, 40%);">-   size_t tx_spp, rx_spp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  bool started;</span><br><span style="color: hsl(0, 100%, 40%);">-   bool aligned;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   size_t rx_pkt_cnt;</span><br><span style="color: hsl(0, 100%, 40%);">-      size_t drop_cnt;</span><br><span style="color: hsl(0, 100%, 40%);">-        uhd::time_spec_t prev_ts;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       TIMESTAMP ts_initial, ts_offset;</span><br><span style="color: hsl(0, 100%, 40%);">-        std::vector<smpl_buf *> rx_buffers;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       void init_gains();</span><br><span style="color: hsl(0, 100%, 40%);">-      void set_channels(bool swap);</span><br><span style="color: hsl(0, 100%, 40%);">-   void set_rates();</span><br><span style="color: hsl(0, 100%, 40%);">-       bool parse_dev_type();</span><br><span style="color: hsl(0, 100%, 40%);">-  bool flush_recv(size_t num_pkts);</span><br><span style="color: hsl(0, 100%, 40%);">-       int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     std::string str_code(uhd::rx_metadata_t metadata);</span><br><span style="color: hsl(0, 100%, 40%);">-      std::string str_code(uhd::async_metadata_t metadata);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   uhd::tune_request_t select_freq(double wFreq, size_t chan, bool tx);</span><br><span style="color: hsl(0, 100%, 40%);">-    bool set_freq(double freq, size_t chan, bool tx);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       Thread *async_event_thrd;</span><br><span style="color: hsl(0, 100%, 40%);">-       Mutex tune_lock;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> void *async_event_loop(uhd_device *dev)</span><br><span> {</span><br><span>   set_selfthread_name("UHDAsyncEvent");</span><br><span>@@ -1386,166 +1186,6 @@</span><br><span>    return ost.str();</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-smpl_buf::smpl_buf(size_t len, double rate)</span><br><span style="color: hsl(0, 100%, 40%);">-   : buf_len(len), clk_rt(rate),</span><br><span style="color: hsl(0, 100%, 40%);">-     time_start(0), time_end(0), data_start(0), data_end(0)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       data = new uint32_t[len];</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-smpl_buf::~smpl_buf()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        delete[] data;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ssize_t smpl_buf::avail_smpls(TIMESTAMP timestamp) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        if (timestamp < time_start)</span><br><span style="color: hsl(0, 100%, 40%);">-          return ERROR_TIMESTAMP;</span><br><span style="color: hsl(0, 100%, 40%);">- else if (timestamp >= time_end)</span><br><span style="color: hsl(0, 100%, 40%);">-              return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       else</span><br><span style="color: hsl(0, 100%, 40%);">-            return time_end - timestamp;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ssize_t smpl_buf::avail_smpls(uhd::time_spec_t timespec) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-    return avail_smpls(timespec.to_ticks(clk_rt));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ssize_t smpl_buf::read(void *buf, size_t len, TIMESTAMP timestamp)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      int type_sz = 2 * sizeof(short);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        // Check for valid read</span><br><span style="color: hsl(0, 100%, 40%);">- if (timestamp < time_start)</span><br><span style="color: hsl(0, 100%, 40%);">-          return ERROR_TIMESTAMP;</span><br><span style="color: hsl(0, 100%, 40%);">- if (timestamp >= time_end)</span><br><span style="color: hsl(0, 100%, 40%);">-           return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       if (len >= buf_len)</span><br><span style="color: hsl(0, 100%, 40%);">-          return ERROR_READ;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      // How many samples should be copied</span><br><span style="color: hsl(0, 100%, 40%);">-    size_t num_smpls = time_end - timestamp;</span><br><span style="color: hsl(0, 100%, 40%);">-        if (num_smpls > len)</span><br><span style="color: hsl(0, 100%, 40%);">-         num_smpls = len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        // Starting index</span><br><span style="color: hsl(0, 100%, 40%);">-       size_t read_start = (data_start + (timestamp - time_start)) % buf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  // Read it</span><br><span style="color: hsl(0, 100%, 40%);">-      if (read_start + num_smpls < buf_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-              size_t numBytes = len * type_sz;</span><br><span style="color: hsl(0, 100%, 40%);">-                memcpy(buf, data + read_start, numBytes);</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                size_t first_cp = (buf_len - read_start) * type_sz;</span><br><span style="color: hsl(0, 100%, 40%);">-             size_t second_cp = len * type_sz - first_cp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(buf, data + read_start, first_cp);</span><br><span style="color: hsl(0, 100%, 40%);">-               memcpy((char*) buf + first_cp, data, second_cp);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       data_start = (read_start + len) % buf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-      time_start = timestamp + len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   if (time_start > time_end)</span><br><span style="color: hsl(0, 100%, 40%);">-           return ERROR_READ;</span><br><span style="color: hsl(0, 100%, 40%);">-      else</span><br><span style="color: hsl(0, 100%, 40%);">-            return num_smpls;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ssize_t smpl_buf::read(void *buf, size_t len, uhd::time_spec_t ts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   return read(buf, len, ts.to_ticks(clk_rt));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        int type_sz = 2 * sizeof(short);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        // Check for valid write</span><br><span style="color: hsl(0, 100%, 40%);">-        if ((len == 0) || (len >= buf_len))</span><br><span style="color: hsl(0, 100%, 40%);">-          return ERROR_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-     if ((timestamp + len) <= time_end)</span><br><span style="color: hsl(0, 100%, 40%);">-           return ERROR_TIMESTAMP;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (timestamp < time_end) {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGC(DDEV, ERR) << "Overwriting old buffer data: timestamp="<<timestamp<<" time_end="<<time_end;</span><br><span style="color: hsl(0, 100%, 40%);">-            uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(timestamp, clk_rt);</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGC(DDEV, DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << ts.to_ticks(clk_rt) << ") rate=" << clk_rt;</span><br><span style="color: hsl(0, 100%, 40%);">-           // Do not return error here, because it's a rounding error and is not fatal</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (timestamp > time_end && time_end != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         LOGC(DDEV, ERR) << "Skipping buffer data: timestamp="<<timestamp<<" time_end="<<time_end;</span><br><span style="color: hsl(0, 100%, 40%);">-           uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(timestamp, clk_rt);</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGC(DDEV, DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << ts.to_ticks(clk_rt) << ") rate=" << clk_rt;</span><br><span style="color: hsl(0, 100%, 40%);">-           // Do not return error here, because it's a rounding error and is not fatal</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       // Starting index</span><br><span style="color: hsl(0, 100%, 40%);">-       size_t write_start = (data_start + (timestamp - time_start)) % buf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- // Write it</span><br><span style="color: hsl(0, 100%, 40%);">-     if ((write_start + len) < buf_len) {</span><br><span style="color: hsl(0, 100%, 40%);">-         size_t numBytes = len * type_sz;</span><br><span style="color: hsl(0, 100%, 40%);">-                memcpy(data + write_start, buf, numBytes);</span><br><span style="color: hsl(0, 100%, 40%);">-      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                size_t first_cp = (buf_len - write_start) * type_sz;</span><br><span style="color: hsl(0, 100%, 40%);">-            size_t second_cp = len * type_sz - first_cp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(data + write_start, buf, first_cp);</span><br><span style="color: hsl(0, 100%, 40%);">-              memcpy(data, (char*) buf + first_cp, second_cp);</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       data_end = (write_start + len) % buf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-       time_end = timestamp + len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     if (!data_start)</span><br><span style="color: hsl(0, 100%, 40%);">-                data_start = write_start;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (((write_start + len) > buf_len) && (data_end > data_start))</span><br><span style="color: hsl(0, 100%, 40%);">-           return ERROR_OVERFLOW;</span><br><span style="color: hsl(0, 100%, 40%);">-  else if (time_end <= time_start)</span><br><span style="color: hsl(0, 100%, 40%);">-             return ERROR_WRITE;</span><br><span style="color: hsl(0, 100%, 40%);">-     else</span><br><span style="color: hsl(0, 100%, 40%);">-            return len;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-ssize_t smpl_buf::write(void *buf, size_t len, uhd::time_spec_t ts)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-        return write(buf, len, ts.to_ticks(clk_rt));</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-std::string smpl_buf::str_status(size_t ts) const</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- std::ostringstream ost("Sample buffer: ");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    ost << "timestamp = " << ts;</span><br><span style="color: hsl(0, 100%, 40%);">-      ost << ", length = " << buf_len;</span><br><span style="color: hsl(0, 100%, 40%);">-  ost << ", time_start = " << time_start;</span><br><span style="color: hsl(0, 100%, 40%);">-   ost << ", time_end = " << time_end;</span><br><span style="color: hsl(0, 100%, 40%);">-       ost << ", data_start = " << data_start;</span><br><span style="color: hsl(0, 100%, 40%);">-   ost << ", data_end = " << data_end;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return ost.str();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-std::string smpl_buf::str_code(ssize_t code)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- switch (code) {</span><br><span style="color: hsl(0, 100%, 40%);">- case ERROR_TIMESTAMP:</span><br><span style="color: hsl(0, 100%, 40%);">-           return "Sample buffer: Requested timestamp is not valid";</span><br><span style="color: hsl(0, 100%, 40%);">-     case ERROR_READ:</span><br><span style="color: hsl(0, 100%, 40%);">-                return "Sample buffer: Read error";</span><br><span style="color: hsl(0, 100%, 40%);">-   case ERROR_WRITE:</span><br><span style="color: hsl(0, 100%, 40%);">-               return "Sample buffer: Write error";</span><br><span style="color: hsl(0, 100%, 40%);">-  case ERROR_OVERFLOW:</span><br><span style="color: hsl(0, 100%, 40%);">-            return "Sample buffer: Overrun";</span><br><span style="color: hsl(0, 100%, 40%);">-      default:</span><br><span style="color: hsl(0, 100%, 40%);">-                return "Sample buffer: Unknown error";</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> RadioDevice *RadioDevice::make(size_t tx_sps, size_t rx_sps,</span><br><span>                          InterfaceType iface, size_t chans, double lo_offset,</span><br><span>                         const std::vector<std::string>& tx_paths,</span><br><span>diff --git a/Transceiver52M/device/uhd/UHDDevice.h b/Transceiver52M/device/uhd/UHDDevice.h</span><br><span>new file mode 100644</span><br><span>index 0000000..93a9660</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/uhd/UHDDevice.h</span><br><span>@@ -0,0 +1,164 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* Copyright 2019 sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.</span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+* This use of this software may be subject to additional restrictions.</span><br><span style="color: hsl(120, 100%, 40%);">+* See the LEGAL file in the main directory for details.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+    but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef _UHD_DEVICE_H_</span><br><span style="color: hsl(120, 100%, 40%);">+#define _UHD_DEVICE_H_</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef HAVE_CONFIG_H</span><br><span style="color: hsl(120, 100%, 40%);">+#include "config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "radioDevice.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "smpl_buf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <uhd/version.hpp></span><br><span style="color: hsl(120, 100%, 40%);">+#include <uhd/property_tree.hpp></span><br><span style="color: hsl(120, 100%, 40%);">+#include <uhd/usrp/multi_usrp.hpp></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum uhd_dev_type {</span><br><span style="color: hsl(120, 100%, 40%);">+        USRP1,</span><br><span style="color: hsl(120, 100%, 40%);">+        USRP2,</span><br><span style="color: hsl(120, 100%, 40%);">+        B100,</span><br><span style="color: hsl(120, 100%, 40%);">+ B200,</span><br><span style="color: hsl(120, 100%, 40%);">+ B210,</span><br><span style="color: hsl(120, 100%, 40%);">+ B2XX_MCBTS,</span><br><span style="color: hsl(120, 100%, 40%);">+   E1XX,</span><br><span style="color: hsl(120, 100%, 40%);">+ E3XX,</span><br><span style="color: hsl(120, 100%, 40%);">+ X3XX,</span><br><span style="color: hsl(120, 100%, 40%);">+ UMTRX,</span><br><span style="color: hsl(120, 100%, 40%);">+        LIMESDR,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+    uhd_device - UHD implementation of the Device interface. Timestamped samples</span><br><span style="color: hsl(120, 100%, 40%);">+                are sent to and received from the device. An intermediate buffer</span><br><span style="color: hsl(120, 100%, 40%);">+                on the receive side collects and aligns packets of samples.</span><br><span style="color: hsl(120, 100%, 40%);">+                Events and errors such as underruns are reported asynchronously</span><br><span style="color: hsl(120, 100%, 40%);">+                by the device and received in a separate thread.</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+class uhd_device : public RadioDevice {</span><br><span style="color: hsl(120, 100%, 40%);">+public:</span><br><span style="color: hsl(120, 100%, 40%);">+  uhd_device(size_t tx_sps, size_t rx_sps, InterfaceType type,</span><br><span style="color: hsl(120, 100%, 40%);">+             size_t chans, double offset,</span><br><span style="color: hsl(120, 100%, 40%);">+                  const std::vector<std::string>& tx_paths,</span><br><span style="color: hsl(120, 100%, 40%);">+                   const std::vector<std::string>& rx_paths);</span><br><span style="color: hsl(120, 100%, 40%);">+       ~uhd_device();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      int open(const std::string &args, int ref, bool swap_channels);</span><br><span style="color: hsl(120, 100%, 40%);">+   bool start();</span><br><span style="color: hsl(120, 100%, 40%);">+ bool stop();</span><br><span style="color: hsl(120, 100%, 40%);">+  bool restart();</span><br><span style="color: hsl(120, 100%, 40%);">+       void setPriority(float prio);</span><br><span style="color: hsl(120, 100%, 40%);">+ enum TxWindowType getWindowType() { return tx_window; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     int readSamples(std::vector<short *> &bufs, int len, bool *overrun,</span><br><span style="color: hsl(120, 100%, 40%);">+                 TIMESTAMP timestamp, bool *underrun, unsigned *RSSI);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       int writeSamples(std::vector<short *> &bufs, int len, bool *underrun,</span><br><span style="color: hsl(120, 100%, 40%);">+                        TIMESTAMP timestamp, bool isControl);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bool updateAlignment(TIMESTAMP timestamp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  bool setTxFreq(double wFreq, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    bool setRxFreq(double wFreq, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  TIMESTAMP initialWriteTimestamp();</span><br><span style="color: hsl(120, 100%, 40%);">+    TIMESTAMP initialReadTimestamp();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   double fullScaleInputValue();</span><br><span style="color: hsl(120, 100%, 40%);">+ double fullScaleOutputValue();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      double setRxGain(double db, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+     double getRxGain(size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+        double maxRxGain(void) { return rx_gain_max; }</span><br><span style="color: hsl(120, 100%, 40%);">+        double minRxGain(void) { return rx_gain_min; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      double setTxGain(double db, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+     double maxTxGain(void) { return tx_gain_max; }</span><br><span style="color: hsl(120, 100%, 40%);">+        double minTxGain(void) { return tx_gain_min; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      double getTxFreq(size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+        double getRxFreq(size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+        double getRxFreq();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bool setRxAntenna(const std::string &ant, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+   std::string getRxAntenna(size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+        bool setTxAntenna(const std::string &ant, size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+   std::string getTxAntenna(size_t chan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bool requiresRadioAlign();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  GSM::Time minLatency();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     inline double getSampleRate() { return tx_rate; }</span><br><span style="color: hsl(120, 100%, 40%);">+     inline double numberRead() { return rx_pkt_cnt; }</span><br><span style="color: hsl(120, 100%, 40%);">+     inline double numberWritten() { return 0; }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /** Receive and process asynchronous message</span><br><span style="color: hsl(120, 100%, 40%);">+      @return true if message received or false on timeout or error</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+    bool recv_async_msg();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      enum err_code {</span><br><span style="color: hsl(120, 100%, 40%);">+               ERROR_TIMING = -1,</span><br><span style="color: hsl(120, 100%, 40%);">+            ERROR_TIMEOUT = -2,</span><br><span style="color: hsl(120, 100%, 40%);">+           ERROR_UNRECOVERABLE = -3,</span><br><span style="color: hsl(120, 100%, 40%);">+             ERROR_UNHANDLED = -4,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private:</span><br><span style="color: hsl(120, 100%, 40%);">+        uhd::usrp::multi_usrp::sptr usrp_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+ uhd::tx_streamer::sptr tx_stream;</span><br><span style="color: hsl(120, 100%, 40%);">+     uhd::rx_streamer::sptr rx_stream;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum TxWindowType tx_window;</span><br><span style="color: hsl(120, 100%, 40%);">+  enum uhd_dev_type dev_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ double tx_rate, rx_rate;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    double tx_gain_min, tx_gain_max;</span><br><span style="color: hsl(120, 100%, 40%);">+      double rx_gain_min, rx_gain_max;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    std::vector<double> tx_gains, rx_gains;</span><br><span style="color: hsl(120, 100%, 40%);">+ std::vector<double> tx_freqs, rx_freqs;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t tx_spp, rx_spp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      bool started;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool aligned;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t rx_pkt_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t drop_cnt;</span><br><span style="color: hsl(120, 100%, 40%);">+      uhd::time_spec_t prev_ts;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   TIMESTAMP ts_initial, ts_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+      std::vector<smpl_buf *> rx_buffers;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   void init_gains();</span><br><span style="color: hsl(120, 100%, 40%);">+    void set_channels(bool swap);</span><br><span style="color: hsl(120, 100%, 40%);">+ void set_rates();</span><br><span style="color: hsl(120, 100%, 40%);">+     bool parse_dev_type();</span><br><span style="color: hsl(120, 100%, 40%);">+        bool flush_recv(size_t num_pkts);</span><br><span style="color: hsl(120, 100%, 40%);">+     int check_rx_md_err(uhd::rx_metadata_t &md, ssize_t num_smpls);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ std::string str_code(uhd::rx_metadata_t metadata);</span><br><span style="color: hsl(120, 100%, 40%);">+    std::string str_code(uhd::async_metadata_t metadata);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       uhd::tune_request_t select_freq(double wFreq, size_t chan, bool tx);</span><br><span style="color: hsl(120, 100%, 40%);">+  bool set_freq(double freq, size_t chan, bool tx);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Thread *async_event_thrd;</span><br><span style="color: hsl(120, 100%, 40%);">+     Mutex tune_lock;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif // _UHD_DEVICE_H_</span><br><span>diff --git a/Transceiver52M/device/uhd/smpl_buf.cpp b/Transceiver52M/device/uhd/smpl_buf.cpp</span><br><span>new file mode 100644</span><br><span>index 0000000..f1a6a89</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/uhd/smpl_buf.cpp</span><br><span>@@ -0,0 +1,162 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include "smpl_buf.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+smpl_buf::smpl_buf(size_t len, double rate)</span><br><span style="color: hsl(120, 100%, 40%);">+       : buf_len(len), clk_rt(rate),</span><br><span style="color: hsl(120, 100%, 40%);">+   time_start(0), time_end(0), data_start(0), data_end(0)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   data = new uint32_t[len];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+smpl_buf::~smpl_buf()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      delete[] data;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ssize_t smpl_buf::avail_smpls(TIMESTAMP timestamp) const</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (timestamp < time_start)</span><br><span style="color: hsl(120, 100%, 40%);">+                return ERROR_TIMESTAMP;</span><br><span style="color: hsl(120, 100%, 40%);">+       else if (timestamp >= time_end)</span><br><span style="color: hsl(120, 100%, 40%);">+            return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     else</span><br><span style="color: hsl(120, 100%, 40%);">+          return time_end - timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ssize_t smpl_buf::avail_smpls(uhd::time_spec_t timespec) const</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return avail_smpls(timespec.to_ticks(clk_rt));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ssize_t smpl_buf::read(void *buf, size_t len, TIMESTAMP timestamp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int type_sz = 2 * sizeof(short);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    // Check for valid read</span><br><span style="color: hsl(120, 100%, 40%);">+       if (timestamp < time_start)</span><br><span style="color: hsl(120, 100%, 40%);">+                return ERROR_TIMESTAMP;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (timestamp >= time_end)</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (len >= buf_len)</span><br><span style="color: hsl(120, 100%, 40%);">+                return ERROR_READ;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  // How many samples should be copied</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t num_smpls = time_end - timestamp;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (num_smpls > len)</span><br><span style="color: hsl(120, 100%, 40%);">+               num_smpls = len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    // Starting index</span><br><span style="color: hsl(120, 100%, 40%);">+     size_t read_start = (data_start + (timestamp - time_start)) % buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      // Read it</span><br><span style="color: hsl(120, 100%, 40%);">+    if (read_start + num_smpls < buf_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+            size_t numBytes = len * type_sz;</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(buf, data + read_start, numBytes);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              size_t first_cp = (buf_len - read_start) * type_sz;</span><br><span style="color: hsl(120, 100%, 40%);">+           size_t second_cp = len * type_sz - first_cp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                memcpy(buf, data + read_start, first_cp);</span><br><span style="color: hsl(120, 100%, 40%);">+             memcpy((char*) buf + first_cp, data, second_cp);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   data_start = (read_start + len) % buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+    time_start = timestamp + len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (time_start > time_end)</span><br><span style="color: hsl(120, 100%, 40%);">+         return ERROR_READ;</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          return num_smpls;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ssize_t smpl_buf::read(void *buf, size_t len, uhd::time_spec_t ts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return read(buf, len, ts.to_ticks(clk_rt));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ssize_t smpl_buf::write(void *buf, size_t len, TIMESTAMP timestamp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int type_sz = 2 * sizeof(short);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    // Check for valid write</span><br><span style="color: hsl(120, 100%, 40%);">+      if ((len == 0) || (len >= buf_len))</span><br><span style="color: hsl(120, 100%, 40%);">+                return ERROR_WRITE;</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((timestamp + len) <= time_end)</span><br><span style="color: hsl(120, 100%, 40%);">+         return ERROR_TIMESTAMP;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (timestamp < time_end) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGC(DDEV, ERR) << "Overwriting old buffer data: timestamp="<<timestamp<<" time_end="<<time_end;</span><br><span style="color: hsl(120, 100%, 40%);">+          uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(timestamp, clk_rt);</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGC(DDEV, DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << ts.to_ticks(clk_rt) << ") rate=" << clk_rt;</span><br><span style="color: hsl(120, 100%, 40%);">+         // Do not return error here, because it's a rounding error and is not fatal</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (timestamp > time_end && time_end != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               LOGC(DDEV, ERR) << "Skipping buffer data: timestamp="<<timestamp<<" time_end="<<time_end;</span><br><span style="color: hsl(120, 100%, 40%);">+         uhd::time_spec_t ts = uhd::time_spec_t::from_ticks(timestamp, clk_rt);</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGC(DDEV, DEBUG) << "Requested timestamp = " << timestamp << " (real_sec=" << std::fixed << ts.get_real_secs() << " = " << ts.to_ticks(clk_rt) << ") rate=" << clk_rt;</span><br><span style="color: hsl(120, 100%, 40%);">+         // Do not return error here, because it's a rounding error and is not fatal</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // Starting index</span><br><span style="color: hsl(120, 100%, 40%);">+     size_t write_start = (data_start + (timestamp - time_start)) % buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     // Write it</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((write_start + len) < buf_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+               size_t numBytes = len * type_sz;</span><br><span style="color: hsl(120, 100%, 40%);">+              memcpy(data + write_start, buf, numBytes);</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              size_t first_cp = (buf_len - write_start) * type_sz;</span><br><span style="color: hsl(120, 100%, 40%);">+          size_t second_cp = len * type_sz - first_cp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                memcpy(data + write_start, buf, first_cp);</span><br><span style="color: hsl(120, 100%, 40%);">+            memcpy(data, (char*) buf + first_cp, second_cp);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   data_end = (write_start + len) % buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+     time_end = timestamp + len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!data_start)</span><br><span style="color: hsl(120, 100%, 40%);">+              data_start = write_start;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (((write_start + len) > buf_len) && (data_end > data_start))</span><br><span style="color: hsl(120, 100%, 40%);">+         return ERROR_OVERFLOW;</span><br><span style="color: hsl(120, 100%, 40%);">+        else if (time_end <= time_start)</span><br><span style="color: hsl(120, 100%, 40%);">+           return ERROR_WRITE;</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          return len;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ssize_t smpl_buf::write(void *buf, size_t len, uhd::time_spec_t ts)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return write(buf, len, ts.to_ticks(clk_rt));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+std::string smpl_buf::str_status(size_t ts) const</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       std::ostringstream ost("Sample buffer: ");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ost << "timestamp = " << ts;</span><br><span style="color: hsl(120, 100%, 40%);">+    ost << ", length = " << buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+        ost << ", time_start = " << time_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ ost << ", time_end = " << time_end;</span><br><span style="color: hsl(120, 100%, 40%);">+     ost << ", data_start = " << data_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ ost << ", data_end = " << data_end;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return ost.str();</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+std::string smpl_buf::str_code(ssize_t code)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (code) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case ERROR_TIMESTAMP:</span><br><span style="color: hsl(120, 100%, 40%);">+         return "Sample buffer: Requested timestamp is not valid";</span><br><span style="color: hsl(120, 100%, 40%);">+   case ERROR_READ:</span><br><span style="color: hsl(120, 100%, 40%);">+              return "Sample buffer: Read error";</span><br><span style="color: hsl(120, 100%, 40%);">+ case ERROR_WRITE:</span><br><span style="color: hsl(120, 100%, 40%);">+             return "Sample buffer: Write error";</span><br><span style="color: hsl(120, 100%, 40%);">+        case ERROR_OVERFLOW:</span><br><span style="color: hsl(120, 100%, 40%);">+          return "Sample buffer: Overrun";</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return "Sample buffer: Unknown error";</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/Transceiver52M/device/uhd/smpl_buf.h b/Transceiver52M/device/uhd/smpl_buf.h</span><br><span>new file mode 100644</span><br><span>index 0000000..2c1e435</span><br><span>--- /dev/null</span><br><span>+++ b/Transceiver52M/device/uhd/smpl_buf.h</span><br><span>@@ -0,0 +1,88 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+* Copyright 2019 sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.</span><br><span style="color: hsl(120, 100%, 40%);">+*</span><br><span style="color: hsl(120, 100%, 40%);">+* This use of this software may be subject to additional restrictions.</span><br><span style="color: hsl(120, 100%, 40%);">+* See the LEGAL file in the main directory for details.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+    but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef _SAMPLE_BUF_H_</span><br><span style="color: hsl(120, 100%, 40%);">+#define _SAMPLE_BUF_H_</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <uhd/types/time_spec.hpp></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "radioDevice.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+    Sample Buffer - Allows reading and writing of timed samples using osmo-trx</span><br><span style="color: hsl(120, 100%, 40%);">+                    or UHD style timestamps. Time conversions are handled</span><br><span style="color: hsl(120, 100%, 40%);">+                    internally or accessable through the static convert calls.</span><br><span style="color: hsl(120, 100%, 40%);">+*/</span><br><span style="color: hsl(120, 100%, 40%);">+class smpl_buf {</span><br><span style="color: hsl(120, 100%, 40%);">+public:</span><br><span style="color: hsl(120, 100%, 40%);">+  /** Sample buffer constructor</span><br><span style="color: hsl(120, 100%, 40%);">+     @param len number of 32-bit samples the buffer should hold</span><br><span style="color: hsl(120, 100%, 40%);">+            @param rate sample clockrate</span><br><span style="color: hsl(120, 100%, 40%);">+          @param timestamp</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+    smpl_buf(size_t len, double rate);</span><br><span style="color: hsl(120, 100%, 40%);">+    ~smpl_buf();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /** Query number of samples available for reading</span><br><span style="color: hsl(120, 100%, 40%);">+         @param timestamp time of first sample</span><br><span style="color: hsl(120, 100%, 40%);">+         @return number of available samples or error</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+    ssize_t avail_smpls(TIMESTAMP timestamp) const;</span><br><span style="color: hsl(120, 100%, 40%);">+       ssize_t avail_smpls(uhd::time_spec_t timestamp) const;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /** Read and write</span><br><span style="color: hsl(120, 100%, 40%);">+        @param buf pointer to buffer</span><br><span style="color: hsl(120, 100%, 40%);">+          @param len number of samples desired to read or write</span><br><span style="color: hsl(120, 100%, 40%);">+         @param timestamp time of first stample</span><br><span style="color: hsl(120, 100%, 40%);">+        @return number of actual samples read or written or error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+    ssize_t read(void *buf, size_t len, TIMESTAMP timestamp);</span><br><span style="color: hsl(120, 100%, 40%);">+     ssize_t read(void *buf, size_t len, uhd::time_spec_t timestamp);</span><br><span style="color: hsl(120, 100%, 40%);">+      ssize_t write(void *buf, size_t len, TIMESTAMP timestamp);</span><br><span style="color: hsl(120, 100%, 40%);">+    ssize_t write(void *buf, size_t len, uhd::time_spec_t timestamp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /** Buffer status string</span><br><span style="color: hsl(120, 100%, 40%);">+          @return a formatted string describing internal buffer state</span><br><span style="color: hsl(120, 100%, 40%);">+       */</span><br><span style="color: hsl(120, 100%, 40%);">+    std::string str_status(size_t ts) const;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /** Formatted error string</span><br><span style="color: hsl(120, 100%, 40%);">+        @param code an error code</span><br><span style="color: hsl(120, 100%, 40%);">+     @return a formatted error string</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+    static std::string str_code(ssize_t code);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  enum err_code {</span><br><span style="color: hsl(120, 100%, 40%);">+               ERROR_TIMESTAMP = -1,</span><br><span style="color: hsl(120, 100%, 40%);">+         ERROR_READ = -2,</span><br><span style="color: hsl(120, 100%, 40%);">+              ERROR_WRITE = -3,</span><br><span style="color: hsl(120, 100%, 40%);">+             ERROR_OVERFLOW = -4</span><br><span style="color: hsl(120, 100%, 40%);">+   };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+private:</span><br><span style="color: hsl(120, 100%, 40%);">+        uint32_t *data;</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     double clk_rt;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      TIMESTAMP time_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ TIMESTAMP time_end;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t data_start;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t data_end;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif // _SAMPLE_BUF_H_</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13809">change 13809</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13809"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-trx </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ib4594320da9bb7f6e9f52e7d70d11ecd11106aae </div>
<div style="display:none"> Gerrit-Change-Number: 13809 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Pau Espin Pedrol <pespin@sysmocom.de> </div>