blob: f77cf9ea7529deab9143363ad5e7ca36e1f7d2a9 [file] [log] [blame]
dburgessb3a0ca42011-10-12 07:44:40 +00001/*
2* Copyright 2008 Free Software Foundation, Inc.
3*
4* This software is distributed under multiple licenses; see the COPYING file in the main directory for licensing information for this specific distribuion.
5*
6* This use of this software may be subject to additional restrictions.
7* See the LEGAL file in the main directory for details.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13*/
14
15
16
17#include "sigProcLib.h"
18#include "GSMCommon.h"
19#include "LinkedLists.h"
20#include "radioDevice.h"
kurtis.heimerl8aea56e2011-11-26 03:18:30 +000021#include "radioVector.h"
22#include "radioClock.h"
Tom Tsou28670fb2015-08-21 19:32:58 -070023#include "radioBuffer.h"
Thomas Tsoue90a42b2013-11-13 23:38:09 -050024#include "Resampler.h"
Tom Tsou76764272016-06-24 14:25:39 -070025#include "Channelizer.h"
26#include "Synthesis.h"
dburgessb3a0ca42011-10-12 07:44:40 +000027
Alexander Chemerisd734e2d2013-06-16 14:30:58 +040028static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
29
dburgessb3a0ca42011-10-12 07:44:40 +000030/** class to interface the transceiver with the USRP */
31class RadioInterface {
32
Thomas Tsoucb69f082013-04-08 14:18:26 -040033protected:
dburgessb3a0ca42011-10-12 07:44:40 +000034
35 Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
36
Thomas Tsou204a9f12013-10-29 18:34:16 -040037 std::vector<VectorFIFO> mReceiveFIFO; ///< FIFO that holds receive bursts
dburgessb3a0ca42011-10-12 07:44:40 +000038
39 RadioDevice *mRadio; ///< the USRP object
Thomas Tsouc1f7c422013-10-11 13:49:55 -040040
Thomas Tsou204a9f12013-10-29 18:34:16 -040041 size_t mSPSTx;
42 size_t mSPSRx;
43 size_t mChans;
Thomas Tsoue90a42b2013-11-13 23:38:09 -050044 size_t mMIMO;
45
Tom Tsou28670fb2015-08-21 19:32:58 -070046 std::vector<RadioBuffer *> sendBuffer;
47 std::vector<RadioBuffer *> recvBuffer;
dburgessb3a0ca42011-10-12 07:44:40 +000048
Thomas Tsou204a9f12013-10-29 18:34:16 -040049 std::vector<short *> convertRecvBuffer;
50 std::vector<short *> convertSendBuffer;
Thomas Tsoucb269a32013-11-15 14:15:47 -050051 std::vector<float> powerScaling;
dburgessb3a0ca42011-10-12 07:44:40 +000052 bool underrun; ///< indicates writes to USRP are too slow
53 bool overrun; ///< indicates reads from USRP are too slow
54 TIMESTAMP writeTimestamp; ///< sample timestamp of next packet written to USRP
55 TIMESTAMP readTimestamp; ///< sample timestamp of next packet read from USRP
56
57 RadioClock mClock; ///< the basestation clock!
58
dburgessb3a0ca42011-10-12 07:44:40 +000059 int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
dburgessb3a0ca42011-10-12 07:44:40 +000060
61 bool mOn; ///< indicates radio is on
62
Thomas Tsoucb69f082013-04-08 14:18:26 -040063private:
64
Tom Tsou28670fb2015-08-21 19:32:58 -070065 /** format samples to USRP */
66 int radioifyVector(signalVector &wVector, size_t chan, bool zero);
dburgessb3a0ca42011-10-12 07:44:40 +000067
68 /** format samples from USRP */
Tom Tsou28670fb2015-08-21 19:32:58 -070069 int unRadioifyVector(signalVector *wVector, size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +000070
71 /** push GSM bursts into the transmit buffer */
Tom Tsou28670fb2015-08-21 19:32:58 -070072 virtual bool pushBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000073
74 /** pull GSM bursts from the receive buffer */
Thomas Tsoucb69f082013-04-08 14:18:26 -040075 virtual void pullBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000076
77public:
78
79 /** start the interface */
Tom Tsoueb54bdd2014-11-25 16:06:32 -080080 bool start();
81 bool stop();
dburgessb3a0ca42011-10-12 07:44:40 +000082
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040083 /** intialization */
Thomas Tsoufe269fe2013-10-14 23:56:51 -040084 virtual bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040085 virtual void close();
86
dburgessb3a0ca42011-10-12 07:44:40 +000087 /** constructor */
Tom Tsou8f0ccf62016-07-20 16:35:03 -070088 RadioInterface(RadioDevice* wRadio, size_t tx_sps, size_t rx_sps,
Tom Tsou5cd70dc2016-03-06 01:28:40 -080089 size_t chans = 1, size_t diversity = 1,
Thomas Tsoue90a42b2013-11-13 23:38:09 -050090 int receiveOffset = 3, GSM::Time wStartTime = GSM::Time(0));
Thomas Tsou204a9f12013-10-29 18:34:16 -040091
dburgessb3a0ca42011-10-12 07:44:40 +000092 /** destructor */
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040093 virtual ~RadioInterface();
dburgessb3a0ca42011-10-12 07:44:40 +000094
dburgessb3a0ca42011-10-12 07:44:40 +000095 /** check for underrun, resets underrun value */
kurtis.heimerle724d6d2011-11-26 03:18:46 +000096 bool isUnderrun();
dburgessb3a0ca42011-10-12 07:44:40 +000097
98 /** return the receive FIFO */
Thomas Tsou204a9f12013-10-29 18:34:16 -040099 VectorFIFO* receiveFIFO(size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000100
101 /** return the basestation clock */
102 RadioClock* getClock(void) { return &mClock;};
103
dburgessb3a0ca42011-10-12 07:44:40 +0000104 /** set transmit frequency */
Tom Tsou76764272016-06-24 14:25:39 -0700105 virtual bool tuneTx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000106
107 /** set receive frequency */
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500108 virtual bool tuneRx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000109
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000110 /** set receive gain */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400111 double setRxGain(double dB, size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000112
113 /** get receive gain */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400114 double getRxGain(size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000115
dburgessb3a0ca42011-10-12 07:44:40 +0000116 /** drive transmission of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400117 void driveTransmitRadio(std::vector<signalVector *> &bursts,
118 std::vector<bool> &zeros);
dburgessb3a0ca42011-10-12 07:44:40 +0000119
120 /** drive reception of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400121 bool driveReceiveRadio();
dburgessb3a0ca42011-10-12 07:44:40 +0000122
Tom Tsoua4d1a412014-11-25 15:46:56 -0800123 int setPowerAttenuation(int atten, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000124
125 /** returns the full-scale transmit amplitude **/
126 double fullScaleInputValue();
127
128 /** returns the full-scale receive amplitude **/
129 double fullScaleOutputValue();
130
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000131 /** set thread priority on current thread */
Thomas Tsou7553aa92013-11-08 12:50:03 -0500132 void setPriority(float prio = 0.5) { mRadio->setPriority(prio); }
dburgessb3a0ca42011-10-12 07:44:40 +0000133
Thomas Tsou02d88d12013-04-05 15:36:30 -0400134 /** get transport window type of attached device */
135 enum RadioDevice::TxWindowType getWindowType() { return mRadio->getWindowType(); }
kurtis.heimerle380af32011-11-26 03:18:55 +0000136
Thomas Tsouf2293b82013-04-08 13:35:36 -0400137#if USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000138protected:
139
140 /** drive synchronization of Tx/Rx of USRP */
141 void alignRadio();
142
dburgessb3a0ca42011-10-12 07:44:40 +0000143 friend void *AlignRadioServiceLoopAdapter(RadioInterface*);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400144#endif
dburgessb3a0ca42011-10-12 07:44:40 +0000145};
146
Thomas Tsouf2293b82013-04-08 13:35:36 -0400147#if USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000148/** synchronization thread loop */
149void *AlignRadioServiceLoopAdapter(RadioInterface*);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400150#endif
Thomas Tsoucb69f082013-04-08 14:18:26 -0400151
152class RadioInterfaceResamp : public RadioInterface {
Thomas Tsoucb69f082013-04-08 14:18:26 -0400153private:
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400154 signalVector *outerSendBuffer;
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400155 signalVector *outerRecvBuffer;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400156
Tom Tsou28670fb2015-08-21 19:32:58 -0700157 bool pushBuffer();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400158 void pullBuffer();
159
160public:
Tom Tsou8f0ccf62016-07-20 16:35:03 -0700161 RadioInterfaceResamp(RadioDevice* wRadio, size_t tx_sps, size_t rx_sps);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400162 ~RadioInterfaceResamp();
163
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400164 bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400165 void close();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400166};
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500167
Tom Tsou76764272016-06-24 14:25:39 -0700168class RadioInterfaceMulti : public RadioInterface {
169private:
170 bool pushBuffer();
171 void pullBuffer();
172
173 signalVector *outerSendBuffer;
174 signalVector *outerRecvBuffer;
175 std::vector<signalVector *> history;
176 std::vector<bool> active;
177
178 Resampler *dnsampler;
179 Resampler *upsampler;
180 Channelizer *channelizer;
181 Synthesis *synthesis;
182
183public:
184 RadioInterfaceMulti(RadioDevice* radio, size_t tx_sps,
185 size_t rx_sps, size_t chans = 1);
186 ~RadioInterfaceMulti();
187
188 bool init(int type);
189 void close();
190
191 bool tuneTx(double freq, size_t chan);
192 bool tuneRx(double freq, size_t chan);
193 double setRxGain(double dB, size_t chan);
194};
195
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500196class RadioInterfaceDiversity : public RadioInterface {
197public:
Tom Tsou8f0ccf62016-07-20 16:35:03 -0700198 RadioInterfaceDiversity(RadioDevice* wRadio, size_t tx_sps, size_t chans);
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500199
200 ~RadioInterfaceDiversity();
201
202 bool init(int type);
203 void close();
204 bool tuneRx(double freq, size_t chan);
205
206private:
Tom Tsou28670fb2015-08-21 19:32:58 -0700207 Resampler *dnsampler;
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500208 std::vector<float> phases;
209 signalVector *outerRecvBuffer;
210
211 bool mDiversity;
212 double mFreqSpacing;
213
214 bool setupDiversityChannels();
215 void pullBuffer();
216};