blob: 1f225a222d0b17962eb6b876ba61971485a50696 [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"
dburgessb3a0ca42011-10-12 07:44:40 +000025
Alexander Chemerisd734e2d2013-06-16 14:30:58 +040026static const unsigned gSlotLen = 148; ///< number of symbols per slot, not counting guard periods
27
dburgessb3a0ca42011-10-12 07:44:40 +000028/** class to interface the transceiver with the USRP */
29class RadioInterface {
30
Thomas Tsoucb69f082013-04-08 14:18:26 -040031protected:
dburgessb3a0ca42011-10-12 07:44:40 +000032
33 Thread mAlignRadioServiceLoopThread; ///< thread that synchronizes transmit and receive sections
34
Thomas Tsou204a9f12013-10-29 18:34:16 -040035 std::vector<VectorFIFO> mReceiveFIFO; ///< FIFO that holds receive bursts
dburgessb3a0ca42011-10-12 07:44:40 +000036
37 RadioDevice *mRadio; ///< the USRP object
Thomas Tsouc1f7c422013-10-11 13:49:55 -040038
Thomas Tsou204a9f12013-10-29 18:34:16 -040039 size_t mSPSTx;
40 size_t mSPSRx;
41 size_t mChans;
Thomas Tsoue90a42b2013-11-13 23:38:09 -050042 size_t mMIMO;
43
Tom Tsou28670fb2015-08-21 19:32:58 -070044 std::vector<RadioBuffer *> sendBuffer;
45 std::vector<RadioBuffer *> recvBuffer;
dburgessb3a0ca42011-10-12 07:44:40 +000046
Thomas Tsou204a9f12013-10-29 18:34:16 -040047 std::vector<short *> convertRecvBuffer;
48 std::vector<short *> convertSendBuffer;
Thomas Tsoucb269a32013-11-15 14:15:47 -050049 std::vector<float> powerScaling;
dburgessb3a0ca42011-10-12 07:44:40 +000050 bool underrun; ///< indicates writes to USRP are too slow
51 bool overrun; ///< indicates reads from USRP are too slow
52 TIMESTAMP writeTimestamp; ///< sample timestamp of next packet written to USRP
53 TIMESTAMP readTimestamp; ///< sample timestamp of next packet read from USRP
54
55 RadioClock mClock; ///< the basestation clock!
56
dburgessb3a0ca42011-10-12 07:44:40 +000057 int receiveOffset; ///< offset b/w transmit and receive GSM timestamps, in timeslots
dburgessb3a0ca42011-10-12 07:44:40 +000058
59 bool mOn; ///< indicates radio is on
60
Thomas Tsoucb69f082013-04-08 14:18:26 -040061private:
62
Tom Tsou28670fb2015-08-21 19:32:58 -070063 /** format samples to USRP */
64 int radioifyVector(signalVector &wVector, size_t chan, bool zero);
dburgessb3a0ca42011-10-12 07:44:40 +000065
66 /** format samples from USRP */
Tom Tsou28670fb2015-08-21 19:32:58 -070067 int unRadioifyVector(signalVector *wVector, size_t chan);
dburgessb3a0ca42011-10-12 07:44:40 +000068
69 /** push GSM bursts into the transmit buffer */
Tom Tsou28670fb2015-08-21 19:32:58 -070070 virtual bool pushBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000071
72 /** pull GSM bursts from the receive buffer */
Thomas Tsoucb69f082013-04-08 14:18:26 -040073 virtual void pullBuffer(void);
dburgessb3a0ca42011-10-12 07:44:40 +000074
75public:
76
77 /** start the interface */
Tom Tsoueb54bdd2014-11-25 16:06:32 -080078 bool start();
79 bool stop();
dburgessb3a0ca42011-10-12 07:44:40 +000080
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040081 /** intialization */
Thomas Tsoufe269fe2013-10-14 23:56:51 -040082 virtual bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040083 virtual void close();
84
dburgessb3a0ca42011-10-12 07:44:40 +000085 /** constructor */
86 RadioInterface(RadioDevice* wRadio = NULL,
Tom Tsou5cd70dc2016-03-06 01:28:40 -080087 size_t tx_sps = 4, size_t rx_sps = 1,
88 size_t chans = 1, size_t diversity = 1,
Thomas Tsoue90a42b2013-11-13 23:38:09 -050089 int receiveOffset = 3, GSM::Time wStartTime = GSM::Time(0));
Thomas Tsou204a9f12013-10-29 18:34:16 -040090
dburgessb3a0ca42011-10-12 07:44:40 +000091 /** destructor */
Thomas Tsou03e6ecf2013-08-20 20:54:54 -040092 virtual ~RadioInterface();
dburgessb3a0ca42011-10-12 07:44:40 +000093
dburgessb3a0ca42011-10-12 07:44:40 +000094 /** check for underrun, resets underrun value */
kurtis.heimerle724d6d2011-11-26 03:18:46 +000095 bool isUnderrun();
dburgessb3a0ca42011-10-12 07:44:40 +000096
97 /** return the receive FIFO */
Thomas Tsou204a9f12013-10-29 18:34:16 -040098 VectorFIFO* receiveFIFO(size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +000099
100 /** return the basestation clock */
101 RadioClock* getClock(void) { return &mClock;};
102
dburgessb3a0ca42011-10-12 07:44:40 +0000103 /** set transmit frequency */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400104 bool tuneTx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000105
106 /** set receive frequency */
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500107 virtual bool tuneRx(double freq, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000108
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000109 /** set receive gain */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400110 double setRxGain(double dB, size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000111
112 /** get receive gain */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400113 double getRxGain(size_t chan = 0);
kurtis.heimerle724d6d2011-11-26 03:18:46 +0000114
dburgessb3a0ca42011-10-12 07:44:40 +0000115 /** drive transmission of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400116 void driveTransmitRadio(std::vector<signalVector *> &bursts,
117 std::vector<bool> &zeros);
dburgessb3a0ca42011-10-12 07:44:40 +0000118
119 /** drive reception of GSM bursts */
Thomas Tsou204a9f12013-10-29 18:34:16 -0400120 bool driveReceiveRadio();
dburgessb3a0ca42011-10-12 07:44:40 +0000121
Tom Tsoua4d1a412014-11-25 15:46:56 -0800122 int setPowerAttenuation(int atten, size_t chan = 0);
dburgessb3a0ca42011-10-12 07:44:40 +0000123
124 /** returns the full-scale transmit amplitude **/
125 double fullScaleInputValue();
126
127 /** returns the full-scale receive amplitude **/
128 double fullScaleOutputValue();
129
kurtis.heimerl6b495a52011-11-26 03:17:21 +0000130 /** set thread priority on current thread */
Thomas Tsou7553aa92013-11-08 12:50:03 -0500131 void setPriority(float prio = 0.5) { mRadio->setPriority(prio); }
dburgessb3a0ca42011-10-12 07:44:40 +0000132
Thomas Tsou02d88d12013-04-05 15:36:30 -0400133 /** get transport window type of attached device */
134 enum RadioDevice::TxWindowType getWindowType() { return mRadio->getWindowType(); }
kurtis.heimerle380af32011-11-26 03:18:55 +0000135
Thomas Tsouf2293b82013-04-08 13:35:36 -0400136#if USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000137protected:
138
139 /** drive synchronization of Tx/Rx of USRP */
140 void alignRadio();
141
dburgessb3a0ca42011-10-12 07:44:40 +0000142 friend void *AlignRadioServiceLoopAdapter(RadioInterface*);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400143#endif
dburgessb3a0ca42011-10-12 07:44:40 +0000144};
145
Thomas Tsouf2293b82013-04-08 13:35:36 -0400146#if USRP1
dburgessb3a0ca42011-10-12 07:44:40 +0000147/** synchronization thread loop */
148void *AlignRadioServiceLoopAdapter(RadioInterface*);
Thomas Tsouf2293b82013-04-08 13:35:36 -0400149#endif
Thomas Tsoucb69f082013-04-08 14:18:26 -0400150
151class RadioInterfaceResamp : public RadioInterface {
Thomas Tsoucb69f082013-04-08 14:18:26 -0400152private:
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400153 signalVector *outerSendBuffer;
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400154 signalVector *outerRecvBuffer;
Thomas Tsoucb69f082013-04-08 14:18:26 -0400155
Tom Tsou28670fb2015-08-21 19:32:58 -0700156 bool pushBuffer();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400157 void pullBuffer();
158
159public:
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500160 RadioInterfaceResamp(RadioDevice* wRadio, size_t wSPS = 4, size_t chans = 1);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400161 ~RadioInterfaceResamp();
162
Thomas Tsoufe269fe2013-10-14 23:56:51 -0400163 bool init(int type);
Thomas Tsou03e6ecf2013-08-20 20:54:54 -0400164 void close();
Thomas Tsoucb69f082013-04-08 14:18:26 -0400165};
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500166
167class RadioInterfaceDiversity : public RadioInterface {
168public:
169 RadioInterfaceDiversity(RadioDevice* wRadio,
170 size_t sps = 4, size_t chans = 2);
171
172 ~RadioInterfaceDiversity();
173
174 bool init(int type);
175 void close();
176 bool tuneRx(double freq, size_t chan);
177
178private:
Tom Tsou28670fb2015-08-21 19:32:58 -0700179 Resampler *dnsampler;
Thomas Tsoue90a42b2013-11-13 23:38:09 -0500180 std::vector<float> phases;
181 signalVector *outerRecvBuffer;
182
183 bool mDiversity;
184 double mFreqSpacing;
185
186 bool setupDiversityChannels();
187 void pullBuffer();
188};