<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>