osmo-trx/Transceiver52M/device/lms/LMSDevice.h

204 lines
5.7 KiB
C++

/*
* Copyright 2018 sysmocom - s.f.m.c. GmbH
*
* SPDX-License-Identifier: AGPL-3.0+
*
* This software is distributed under multiple licenses; see the COPYING file in
* the main directory for licensing information for this specific distribuion.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef _LMS_DEVICE_H_
#define _LMS_DEVICE_H_
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "radioDevice.h"
#include "smpl_buf.h"
#include <sys/time.h>
#include <math.h>
#include <limits.h>
#include <string>
#include <iostream>
#include <lime/LimeSuite.h>
/* Definition of LIMESDR_TX_AMPL limits maximum amplitude of I and Q
* channels separately. Hence LIMESDR_TX_AMPL value must be 1/sqrt(2) =
* 0.7071.... to get an amplitude of 1 of the complex signal:
* A^2 = I^2 + Q^2
* A^2 = (1/sqrt(2))^2 + (1/sqrt(2))^2
* A^2 = 1/2 + 1/2
* A^2 = 1 */
#define LIMESDR_TX_AMPL 0.707
/** A class to handle a LimeSuite supported device */
class LMSDevice:public RadioDevice {
private:
lms_device_t *m_lms_dev;
std::vector<lms_stream_t> m_lms_stream_rx;
std::vector<lms_stream_t> m_lms_stream_tx;
std::vector<smpl_buf *> rx_buffers;
double actualSampleRate; ///< the actual USRP sampling rate
bool started; ///< flag indicates LMS has started
bool skipRx; ///< set if LMS is transmit-only.
TIMESTAMP ts_initial, ts_offset;
double rxGain;
double maxTxGainClamp;
bool do_calib(size_t chan);
bool do_filters(size_t chan);
int get_ant_idx(const std::string & name, bool dir_tx, size_t chan);
bool flush_recv(size_t num_pkts);
void update_stream_stats(size_t chan, bool * underrun, bool * overrun);
public:
/** Object constructor */
LMSDevice(size_t tx_sps, size_t rx_sps, InterfaceType iface, size_t chans, double lo_offset,
const std::vector<std::string>& tx_paths,
const std::vector<std::string>& rx_paths);
~LMSDevice();
/** Instantiate the LMS */
int open(const std::string &args, int ref, bool swap_channels);
/** Start the LMS */
bool start();
/** Stop the LMS */
bool stop();
/** Set priority not supported */
void setPriority(float prio = 0.5) {
}
enum TxWindowType getWindowType() {
return TX_WINDOW_LMS1;
}
/**
Read samples from the LMS.
@param buf preallocated buf to contain read result
@param len number of samples desired
@param overrun Set if read buffer has been overrun, e.g. data not being read fast enough
@param timestamp The timestamp of the first samples to be read
@param underrun Set if LMS does not have data to transmit, e.g. data not being sent fast enough
@param RSSI The received signal strength of the read result
@return The number of samples actually read
*/
int readSamples(std::vector < short *>&buf, int len, bool * overrun,
TIMESTAMP timestamp = 0xffffffff, bool * underrun =
NULL, unsigned *RSSI = NULL);
/**
Write samples to the LMS.
@param buf Contains the data to be written.
@param len number of samples to write.
@param underrun Set if LMS does not have data to transmit, e.g. data not being sent fast enough
@param timestamp The timestamp of the first sample of the data buffer.
@param isControl Set if data is a control packet, e.g. a ping command
@return The number of samples actually written
*/
int writeSamples(std::vector < short *>&bufs, int len, bool * underrun,
TIMESTAMP timestamp = 0xffffffff, bool isControl =
false);
/** Update the alignment between the read and write timestamps */
bool updateAlignment(TIMESTAMP timestamp);
/** Set the transmitter frequency */
bool setTxFreq(double wFreq, size_t chan = 0);
/** Set the receiver frequency */
bool setRxFreq(double wFreq, size_t chan = 0);
/** Returns the starting write Timestamp*/
TIMESTAMP initialWriteTimestamp(void) {
return ts_initial;
}
/** Returns the starting read Timestamp*/
TIMESTAMP initialReadTimestamp(void) {
return ts_initial;
}
/** returns the full-scale transmit amplitude **/
double fullScaleInputValue() {
return(double) SHRT_MAX * LIMESDR_TX_AMPL;
}
/** returns the full-scale receive amplitude **/
double fullScaleOutputValue() {
return (double) SHRT_MAX;
}
/** sets the receive chan gain, returns the gain setting **/
double setRxGain(double dB, size_t chan = 0);
/** get the current receive gain */
double getRxGain(size_t chan = 0) {
return rxGain;
}
/** return maximum Rx Gain **/
double maxRxGain(void);
/** return minimum Rx Gain **/
double minRxGain(void);
/** sets the transmit chan gain, returns the gain setting **/
double setTxGain(double dB, size_t chan = 0);
/** return maximum Tx Gain **/
double maxTxGain(void);
/** return minimum Rx Gain **/
double minTxGain(void);
/** sets the RX path to use, returns true if successful and false otherwise */
bool setRxAntenna(const std::string & ant, size_t chan = 0);
/* return the used RX path */
std::string getRxAntenna(size_t chan = 0);
/** sets the RX path to use, returns true if successful and false otherwise */
bool setTxAntenna(const std::string & ant, size_t chan = 0);
/* return the used RX path */
std::string getTxAntenna(size_t chan = 0);
/** return whether user drives synchronization of Tx/Rx of USRP */
bool requiresRadioAlign();
/** return whether user drives synchronization of Tx/Rx of USRP */
virtual GSM::Time minLatency();
/** Return internal status values */
inline double getTxFreq(size_t chan = 0) {
return 0;
}
inline double getRxFreq(size_t chan = 0) {
return 0;
}
inline double getSampleRate() {
return actualSampleRate;
}
};
#endif // _LMS_DEVICE_H_