blob: 182e188014efa43ec6ce8b4da5a63dc13e6e80aa [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"
Thomas Tsoue90a42b2013-11-13 23:38:09 -050023#include "Resampler.h"
dburgessb3a0ca42011-10-12 07:44:40 +000024
Alexander Chemerisd734e2d2013-06-16 14:30:58 +040025static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
26
dburgessb3a0ca42011-10-12 07:44:40 +000027/** class to interface the transceiver with the USRP */
28class RadioInterface {
29
Thomas Tsoucb69f082013-04-08 14:18:26 -040030protected:
dburgessb3a0ca42011-10-12 07:44:40 +000031
32 Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
33
Thomas Tsou204a9f12013-10-29 18:34:16 -040034 std::vector<VectorFIFO> mReceiveFIFO; ///< FIFO that holds receive bursts
dburgessb3a0ca42011-10-12 07:44:40 +000035
36 RadioDevice *mRadio; ///< the USRP object
Thomas Tsouc1f7c422013-10-11 13:49:55 -040037
Thomas Tsou204a9f12013-10-29 18:34:16 -040038 size_t mSPSTx;
39 size_t mSPSRx;
40 size_t mChans;
Thomas Tsoue90a42b2013-11-13 23:38:09 -050041 size_t mMIMO;
42
Thomas Tsou204a9f12013-10-29 18:34:16 -040043 std::vector<signalVector *> sendBuffer;
44 std::vector<signalVector *> recvBuffer;
dburgessb3a0ca42011-10-12 07:44:40 +000045 unsigned sendCursor;
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040046 unsigned recvCursor;
dburgessb3a0ca42011-10-12 07:44:40 +000047
Thomas Tsou204a9f12013-10-29 18:34:16 -040048 std::vector<short *> convertRecvBuffer;
49 std::vector<short *> convertSendBuffer;
Thomas Tsoucb269a32013-11-15 14:15:47 -050050 std::vector<float> powerScaling;
dburgessb3a0ca42011-10-12 07:44:40 +000051 bool underrun; ///< indicates writes to USRP are too slow
52 bool overrun; ///< indicates reads from USRP are too slow
53 TIMESTAMP writeTimestamp; ///< sample timestamp of next packet written to USRP
54 TIMESTAMP readTimestamp; ///< sample timestamp of next packet read from USRP
Alexander Chemerisf28d7222015-07-11 12:51:37 -040055 TIMESTAMP configureTimestamp; ///< sample timestamp of next burst to configure
dburgessb3a0ca42011-10-12 07:44:40 +000056
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
dburgessb3a0ca42011-10-12 07:44:40 +000065 /** format samples to USRP */
kurtis.heimerl9b557832011-11-26 03:18:34 +000066 int radioifyVector(signalVector &wVector,
67 float *floatVector,
kurtis.heimerl9b557832011-11-26 03:18:34 +000068 bool zero);
dburgessb3a0ca42011-10-12 07:44:40 +000069
70 /** format samples from USRP */
kurtis.heimerl9b557832011-11-26 03:18:34 +000071 int unRadioifyVector(float *floatVector, signalVector &wVector);
dburgessb3a0ca42011-10-12 07:44:40 +000072
73 /** push GSM bursts into the transmit buffer */
Thomas Tsoucb69f082013-04-08 14:18:26 -040074 virtual void pushBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000075
76 /** pull GSM bursts from the receive buffer */
Thomas Tsoucb69f082013-04-08 14:18:26 -040077 virtual void pullBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000078
79public:
80
81 /** start the interface */
Tom Tsoueb54bdd2014-11-25 16:06:32 -080082 bool start();
83 bool stop();
dburgessb3a0ca42011-10-12 07:44:40 +000084
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040085 /** intialization */
Thomas Tsoufe269fe2013-10-14 23:56:51 -040086 virtual bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040087 virtual void close();
88
dburgessb3a0ca42011-10-12 07:44:40 +000089 /** constructor */
90 RadioInterface(RadioDevice* wRadio = NULL,
Thomas Tsoue90a42b2013-11-13 23:38:09 -050091 size_t sps = 4, size_t chans = 1, size_t diversity = 1,
92 int receiveOffset = 3, GSM::Time wStartTime = GSM::Time(0));
Thomas Tsou204a9f12013-10-29 18:34:16 -040093
dburgessb3a0ca42011-10-12 07:44:40 +000094 /** destructor */
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040095 virtual ~RadioInterface();
dburgessb3a0ca42011-10-12 07:44:40 +000096
dburgessb3a0ca42011-10-12 07:44:40 +000097 /** check for underrun, resets underrun value */
kurtis.heimerle724d6d2011-11-26 03:18:46 +000098 bool isUnderrun();
dburgessb3a0ca42011-10-12 07:44:40 +000099
100 /** return the receive FIFO */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400101 VectorFIFO* receiveFIFO(size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000102
103 /** return the basestation clock */
104 RadioClock* getClock(void) { return &mClock;};
105
dburgessb3a0ca42011-10-12 07:44:40 +0000106 /** set transmit frequency */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400107 bool tuneTx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000108
109 /** set receive frequency */
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500110 virtual bool tuneRx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000111
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000112 /** set receive gain */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400113 double setRxGain(double dB, size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000114
115 /** get receive gain */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400116 double getRxGain(size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000117
dburgessb3a0ca42011-10-12 07:44:40 +0000118 /** drive transmission of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400119 void driveTransmitRadio(std::vector<signalVector *> &bursts,
120 std::vector<bool> &zeros);
dburgessb3a0ca42011-10-12 07:44:40 +0000121
122 /** drive reception of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400123 bool driveReceiveRadio();
dburgessb3a0ca42011-10-12 07:44:40 +0000124
Tom Tsoua4d1a412014-11-25 15:46:56 -0800125 int setPowerAttenuation(int atten, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000126
127 /** returns the full-scale transmit amplitude **/
128 double fullScaleInputValue();
129
130 /** returns the full-scale receive amplitude **/
131 double fullScaleOutputValue();
132
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000133 /** set thread priority on current thread */
Thomas Tsou7553aa92013-11-08 12:50:03 -0500134 void setPriority(float prio = 0.5) { mRadio->setPriority(prio); }
dburgessb3a0ca42011-10-12 07:44:40 +0000135
Thomas Tsou02d88d12013-04-05 15:36:30 -0400136 /** get transport window type of attached device */
137 enum RadioDevice::TxWindowType getWindowType() { return mRadio->getWindowType(); }
kurtis.heimerle380af32011-11-26 03:18:55 +0000138
Alexander Chemerisf28d7222015-07-11 12:51:37 -0400139 /** update diversity switch and other reception of GSM bursts */
140 void updateBurstRxParameters(const GSM::Time &gsmTime, size_t chan);
141
Thomas Tsouf2293b82013-04-08 13:35:36 -0400142#if USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000143protected:
144
145 /** drive synchronization of Tx/Rx of USRP */
146 void alignRadio();
147
dburgessb3a0ca42011-10-12 07:44:40 +0000148 friend void *AlignRadioServiceLoopAdapter(RadioInterface*);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400149#endif
dburgessb3a0ca42011-10-12 07:44:40 +0000150};
151
Thomas Tsouf2293b82013-04-08 13:35:36 -0400152#if USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000153/** synchronization thread loop */
154void *AlignRadioServiceLoopAdapter(RadioInterface*);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400155#endif
Thomas Tsoucb69f082013-04-08 14:18:26 -0400156
157class RadioInterfaceResamp : public RadioInterface {
158
159private:
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400160 signalVector *innerSendBuffer;
161 signalVector *outerSendBuffer;
162 signalVector *innerRecvBuffer;
163 signalVector *outerRecvBuffer;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400164
165 void pushBuffer();
166 void pullBuffer();
167
168public:
169
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500170 RadioInterfaceResamp(RadioDevice* wRadio, size_t wSPS = 4, size_t chans = 1);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400171
172 ~RadioInterfaceResamp();
173
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400174 bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400175 void close();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400176};
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500177
178class RadioInterfaceDiversity : public RadioInterface {
179public:
180 RadioInterfaceDiversity(RadioDevice* wRadio,
181 size_t sps = 4, size_t chans = 2);
182
183 ~RadioInterfaceDiversity();
184
185 bool init(int type);
186 void close();
187 bool tuneRx(double freq, size_t chan);
188
189private:
190 std::vector<Resampler *> dnsamplers;
191 std::vector<float> phases;
192 signalVector *outerRecvBuffer;
193
194 bool mDiversity;
195 double mFreqSpacing;
196
197 bool setupDiversityChannels();
198 void pullBuffer();
199};