uhd: separate USRPDevice and create virtual device interface
Move essential interface components into an abstract Device class and create a factory method for instantiating compile-time specified derived types (USRP1 or UHD). The radioInterface has a device specific type conversion call to the USRP1 driver, so push that behind the Device interface too. Signed-off-by: Thomas Tsou <ttsou@vt.edu>
This commit is contained in:
parent
5a969569c5
commit
9c091dc7a9
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* This software is distributed under the terms of the GNU Affero Public License.
|
||||
* See the COPYING file in the main directory for details.
|
||||
*
|
||||
* This use of this software may be subject to additional restrictions.
|
||||
* See the LEGAL file in the main directory for details.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _DEVICE_H_
|
||||
#define _DEVICE_H_
|
||||
|
||||
/** a 64-bit virtual timestamp for device data */
|
||||
typedef unsigned long long TIMESTAMP;
|
||||
|
||||
class Device {
|
||||
public:
|
||||
/** Factory method */
|
||||
static Device *make(double desiredSampleRate, bool skipRx = false);
|
||||
|
||||
/** Open, start, and stop the device
|
||||
@return success or fail
|
||||
*/
|
||||
virtual bool open() = 0;
|
||||
virtual bool start() = 0;
|
||||
virtual bool stop() = 0;
|
||||
|
||||
/** Read samples from the USRP.
|
||||
@param buf preallocated buf to contain read result
|
||||
@param len number of samples desired
|
||||
@param overrun set if read buffer has been overrun
|
||||
@param timestamp time of the first samples to be read
|
||||
@param underrun set if USRP does not have data to transmit
|
||||
@param RSSI received signal strength of the read result
|
||||
@return number of samples actually read
|
||||
*/
|
||||
virtual int readSamples(short *buf, int len, bool *overrun,
|
||||
TIMESTAMP timestamp = 0xffffffff,
|
||||
bool *underrun = 0,
|
||||
unsigned *RSSI = 0) = 0;
|
||||
|
||||
/** Write samples to the USRP.
|
||||
@param buf contains the data to be written
|
||||
@param len number of samples to write
|
||||
@param underrun set if USRP does not have data to transmit
|
||||
@param timestamp time of the first sample of the data buffer
|
||||
@param isControl set if data is a control packet
|
||||
@return number of samples actually written
|
||||
*/
|
||||
virtual int writeSamples(short *buf, int len, bool *underrun,
|
||||
TIMESTAMP timestamp = 0xffffffff,
|
||||
bool isControl = false) = 0;
|
||||
|
||||
/** Update the alignment between the read and write timestamps
|
||||
@return success or fail
|
||||
*/
|
||||
virtual bool updateAlignment(TIMESTAMP timestamp) = 0;
|
||||
|
||||
/** Set transmit and receive frequencies
|
||||
@param freq desired frequency
|
||||
@return success or fail
|
||||
*/
|
||||
virtual bool setTxFreq(double freq) = 0;
|
||||
virtual bool setRxFreq(double freq) = 0;
|
||||
|
||||
/** Return internal status values */
|
||||
virtual double getSampleRate() = 0;
|
||||
virtual double numberRead() = 0;
|
||||
virtual double numberWritten() = 0;
|
||||
|
||||
/** Virtual destructor */
|
||||
virtual ~Device() { }
|
||||
|
||||
/** Type conversions if necessary */
|
||||
static short convertHostDeviceShort(short value);
|
||||
static short convertDeviceHostShort(short value);
|
||||
};
|
||||
|
||||
#endif // _DEVICE_H_
|
|
@ -137,7 +137,8 @@ bool USRPDevice::rx_setFreq(double freq, double *actual_freq)
|
|||
}
|
||||
|
||||
|
||||
USRPDevice::USRPDevice (double _desiredSampleRate)
|
||||
USRPDevice::USRPDevice (double _desiredSampleRate, bool wSkipRx)
|
||||
: skipRx(wSkipRx)
|
||||
{
|
||||
LOG(INFO) << "creating USRP device...";
|
||||
decimRate = (unsigned int) round(masterClockRate/_desiredSampleRate);
|
||||
|
@ -151,11 +152,9 @@ USRPDevice::USRPDevice (double _desiredSampleRate)
|
|||
#endif
|
||||
}
|
||||
|
||||
bool USRPDevice::make(bool wSkipRx)
|
||||
bool USRPDevice::open()
|
||||
{
|
||||
skipRx = wSkipRx;
|
||||
|
||||
LOG(INFO) << "making USRP device..";
|
||||
LOG(INFO) << "opening USRP device...";
|
||||
#ifndef SWLOOPBACK
|
||||
string rbf = "std_inband.rbf";
|
||||
//string rbf = "inband_1rxhb_1tx.rbf";
|
||||
|
@ -215,7 +214,7 @@ bool USRPDevice::make(bool wSkipRx)
|
|||
samplesRead = 0;
|
||||
samplesWritten = 0;
|
||||
started = false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -546,3 +545,21 @@ bool USRPDevice::setRxFreq(double wFreq) {
|
|||
bool USRPDevice::setTxFreq(double wFreq) { return true;};
|
||||
bool USRPDevice::setRxFreq(double wFreq) { return true;};
|
||||
#endif
|
||||
|
||||
|
||||
Device *Device::make(double desiredSampleRate, bool skipRx)
|
||||
{
|
||||
return new USRPDevice(desiredSampleRate, skipRx);
|
||||
}
|
||||
|
||||
|
||||
short Device::convertHostDeviceShort(short value)
|
||||
{
|
||||
return host_to_usrp_short(value);
|
||||
}
|
||||
|
||||
|
||||
short Device::convertDeviceHostShort(short value)
|
||||
{
|
||||
return usrp_to_host_short(value);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <math.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "Device.h"
|
||||
|
||||
|
||||
/** Define types which are not defined in libusrp-3.1 */
|
||||
|
@ -51,11 +52,9 @@ typedef boost::shared_ptr<usrp_standard_tx> usrp_standard_tx_sptr;
|
|||
typedef boost::shared_ptr<usrp_standard_rx> usrp_standard_rx_sptr;
|
||||
#endif // HAVE_LIBUSRP_3_2
|
||||
|
||||
/** a 64-bit virtual timestamp for USRP data */
|
||||
typedef unsigned long long TIMESTAMP;
|
||||
|
||||
/** A class to handle a USRP rev 4, with a two RFX900 daughterboards */
|
||||
class USRPDevice {
|
||||
class USRPDevice : public Device {
|
||||
|
||||
private:
|
||||
|
||||
|
@ -175,10 +174,10 @@ private:
|
|||
public:
|
||||
|
||||
/** Object constructor */
|
||||
USRPDevice (double _desiredSampleRate);
|
||||
USRPDevice (double _desiredSampleRate, bool skipRx);
|
||||
|
||||
/** Instantiate the USRP */
|
||||
bool make(bool skipRx = false);
|
||||
bool open();
|
||||
|
||||
/** Start the USRP */
|
||||
bool start();
|
||||
|
|
|
@ -41,9 +41,8 @@ int main(int argc, char *argv[]) {
|
|||
else gLogInit("INFO");
|
||||
if (argc>2) gSetLogFile(argv[2]);
|
||||
|
||||
USRPDevice *usrp = new USRPDevice(400e3);
|
||||
|
||||
usrp->make();
|
||||
Device *usrp = Device::make(400e3);
|
||||
usrp->open();
|
||||
|
||||
TIMESTAMP timestamp;
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ GSM::Time VectorQueue::nextTime() const
|
|||
return retVal;
|
||||
}
|
||||
|
||||
RadioInterface::RadioInterface(USRPDevice *wUsrp,
|
||||
RadioInterface::RadioInterface(Device *wUsrp,
|
||||
int wReceiveOffset,
|
||||
int wSamplesPerSymbol,
|
||||
GSM::Time wStartTime)
|
||||
|
@ -79,8 +79,8 @@ short *RadioInterface::USRPifyVector(signalVector &wVector)
|
|||
signalVector::iterator itr = wVector.begin();
|
||||
short *shortItr = retVector;
|
||||
while (itr < wVector.end()) {
|
||||
*shortItr++ = (short) host_to_usrp_short((short)itr->real());
|
||||
*shortItr++ = (short) host_to_usrp_short((short)itr->imag());
|
||||
*shortItr++ = usrp->convertHostDeviceShort(itr->real());
|
||||
*shortItr++ = usrp->convertHostDeviceShort(itr->imag());
|
||||
itr++;
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,8 @@ signalVector *RadioInterface::unUSRPifyVector(short *shortVector, int numSamples
|
|||
#endif
|
||||
|
||||
while (itr < newVector->end()) {
|
||||
*itr++ = Complex<float>(usrp_to_host_short(*(shortItr+FLIP_IQ)),
|
||||
usrp_to_host_short(*(shortItr+1-FLIP_IQ)));
|
||||
//LOG(DEEPDEBUG) << (*(itr-1));
|
||||
*itr++ = Complex<float>(usrp->convertDeviceHostShort(*(shortItr+FLIP_IQ)),
|
||||
usrp->convertDeviceHostShort(*(shortItr+1-FLIP_IQ)));
|
||||
shortItr += 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
|
||||
#include "sigProcLib.h"
|
||||
#include "USRPDevice.h"
|
||||
#include "Device.h"
|
||||
#include "GSMCommon.h"
|
||||
#include "Interthread.h"
|
||||
|
||||
|
@ -119,7 +119,7 @@ private:
|
|||
signalVector* sendHistory; ///< block of previous transmitted samples
|
||||
signalVector* rcvHistory; ///< block of previous received samples
|
||||
|
||||
USRPDevice *usrp; ///< the USRP object
|
||||
Device *usrp; ///< the USRP object
|
||||
|
||||
signalVector* sendBuffer; ///< block of samples to be transmitted
|
||||
signalVector* rcvBuffer; ///< block of received samples to be processed
|
||||
|
@ -160,7 +160,7 @@ public:
|
|||
void start();
|
||||
|
||||
/** constructor */
|
||||
RadioInterface(USRPDevice* wUsrp = NULL,
|
||||
RadioInterface(Device* wUsrp = NULL,
|
||||
int receiveOffset = 3,
|
||||
int wSamplesPerSymbol = SAMPSPERSYM,
|
||||
GSM::Time wStartTime = GSM::Time(0));
|
||||
|
@ -172,7 +172,7 @@ public:
|
|||
bool isUnderrun() { bool retVal = underrun; underrun = false; return retVal;}
|
||||
|
||||
/** attach an existing USRP to this interface */
|
||||
void attach(USRPDevice *wUsrp) {if (!mOn) usrp = wUsrp;}
|
||||
void attach(Device *wUsrp) {if (!mOn) usrp = wUsrp;}
|
||||
|
||||
/** return the transmit FIFO */
|
||||
VectorFIFO* transmitFIFO() { return &mTransmitFIFO;}
|
||||
|
|
|
@ -49,8 +49,8 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
srandom(time(NULL));
|
||||
|
||||
USRPDevice *usrp = new USRPDevice(400.0e3); //533.333333333e3); //400e3);
|
||||
usrp->make();
|
||||
Device *usrp = Device::make(400.0e3);
|
||||
usrp->open();
|
||||
RadioInterface* radio = new RadioInterface(usrp,3);
|
||||
Transceiver *trx = new Transceiver(5700,"127.0.0.1",SAMPSPERSYM,GSM::Time(2,0),radio);
|
||||
trx->transmitFIFO(radio->transmitFIFO());
|
||||
|
|
Reference in New Issue