aboutsummaryrefslogtreecommitdiffstats
path: root/Transceiver52M
diff options
context:
space:
mode:
authorkurtis.heimerl <kurtis.heimerl@19bc5d8c-e614-43d4-8b26-e1612bc8e597>2011-11-26 03:16:48 +0000
committerkurtis.heimerl <kurtis.heimerl@19bc5d8c-e614-43d4-8b26-e1612bc8e597>2011-11-26 03:16:48 +0000
commit79e71c925e61c42ec6b4b6f9d6591b9c3b70677f (patch)
treed8226dd5858d6834de508670e0fedab08c715c37 /Transceiver52M
parentf5eef205a75edc228912f77d5a1163c2828cf66a (diff)
Transceiver52M: add WBX, DBSRX, and single board support
Remove all RFX specific parts and control daughterboard functionality using the base API. The tuning is now set to a non-inverted image so remove the I/Q swap as well. Daughterboard configuration is set through an enum variable. Currently, there is no auto-configuration and the default is Tx/RX on sides A/B respectively. For transceiver boards the receive antenna is set to RX2. enum dboardConfigType { TXA_RXB, TXB_RXA, TXA_RXA, TXB_RXB }; const dboardConfigType dboardConfig = TXA_RXB; Signed-off-by: Thomas Tsou <ttsou@vt.edu> git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@2632 19bc5d8c-e614-43d4-8b26-e1612bc8e597
Diffstat (limited to 'Transceiver52M')
-rw-r--r--Transceiver52M/USRPDevice.cpp310
-rw-r--r--Transceiver52M/USRPDevice.h75
2 files changed, 128 insertions, 257 deletions
diff --git a/Transceiver52M/USRPDevice.cpp b/Transceiver52M/USRPDevice.cpp
index 7644cc7..8455a15 100644
--- a/Transceiver52M/USRPDevice.cpp
+++ b/Transceiver52M/USRPDevice.cpp
@@ -41,112 +41,15 @@
using namespace std;
-string write_it(unsigned v) {
- string s = " ";
- s[0] = (v>>16) & 0x0ff;
- s[1] = (v>>8) & 0x0ff;
- s[2] = (v) & 0x0ff;
- return s;
-}
-
-
-const float USRPDevice::LO_OFFSET = 4.0e6;
-const double USRPDevice::masterClockRate = (double) 52.0e6;
-
-bool USRPDevice::compute_regs(double freq,
- unsigned *R,
- unsigned *control,
- unsigned *N,
- double *actual_freq)
-{
- if (freq < 1.2e9) {
- DIV2 = 1;
- freq_mult = 2;
- }
- else {
- DIV2 = 0;
- freq_mult = 1;
- }
-
- float phdet_freq = masterClockRate/R_DIV;
- int desired_n = (int) round(freq*freq_mult/phdet_freq);
- *actual_freq = desired_n * phdet_freq/freq_mult;
- float B = floor(desired_n/16);
- float A = desired_n - 16*B;
- unsigned B_DIV = int(B);
- unsigned A_DIV = int(A);
- if (B < A) return false;
- *R = (R_RSV<<22) |
- (BSC << 20) |
- (TEST << 19) |
- (LDP << 18) |
- (ABP << 16) |
- (R_DIV << 2);
- *control = (P<<22) |
- (PD<<20) |
- (CP2 << 17) |
- (CP1 << 14) |
- (PL << 12) |
- (MTLD << 11) |
- (CPG << 10) |
- (CP3S << 9) |
- (PDP << 8) |
- (MUXOUT << 5) |
- (CR << 4) |
- (PC << 2);
- *N = (DIVSEL<<23) |
- (DIV2<<22) |
- (CPGAIN<<21) |
- (B_DIV<<8) |
- (N_RSV<<7) |
- (A_DIV<<2);
- return true;
-}
-
-
-bool USRPDevice::tx_setFreq(double freq, double *actual_freq)
-{
- unsigned R, control, N;
- if (!compute_regs(freq, &R, &control, &N, actual_freq)) return false;
- if (R==0) return false;
-
- writeLock.lock();
- m_uTx->_write_spi(0,SPI_ENABLE_TX_A,SPI_FMT_MSB | SPI_FMT_HDR_0,
- write_it((R & ~0x3) | 1));
- m_uTx->_write_spi(0,SPI_ENABLE_TX_A,SPI_FMT_MSB | SPI_FMT_HDR_0,
- write_it((control & ~0x3) | 0));
- usleep(10000);
- m_uTx->_write_spi(0,SPI_ENABLE_TX_A,SPI_FMT_MSB | SPI_FMT_HDR_0,
- write_it((N & ~0x3) | 2));
- writeLock.unlock();
-
- if (m_uTx->read_io(0) & PLL_LOCK_DETECT) return true;
- if (m_uTx->read_io(0) & PLL_LOCK_DETECT) return true;
- return false;
-}
-
-
-bool USRPDevice::rx_setFreq(double freq, double *actual_freq)
-{
- unsigned R, control, N;
- if (!compute_regs(freq, &R, &control, &N, actual_freq)) return false;
- if (R==0) return false;
-
- writeLock.lock();
- m_uRx->_write_spi(0,SPI_ENABLE_RX_B,SPI_FMT_MSB | SPI_FMT_HDR_0,
- write_it((R & ~0x3) | 1));
- m_uRx->_write_spi(0,SPI_ENABLE_RX_B,SPI_FMT_MSB | SPI_FMT_HDR_0,
- write_it((control & ~0x3) | 0));
- usleep(10000);
- m_uRx->_write_spi(0,SPI_ENABLE_RX_B,SPI_FMT_MSB | SPI_FMT_HDR_0,
- write_it((N & ~0x3) | 2));
- writeLock.unlock();
-
- if (m_uRx->read_io(1) & PLL_LOCK_DETECT) return true;
- if (m_uRx->read_io(1) & PLL_LOCK_DETECT) return true;
- return false;
-}
+enum dboardConfigType {
+ TXA_RXB,
+ TXB_RXA,
+ TXA_RXA,
+ TXB_RXB
+};
+const dboardConfigType dboardConfig = TXA_RXB;
+const double USRPDevice::masterClockRate = 52.0e6;
USRPDevice::USRPDevice (double _desiredSampleRate)
{
@@ -226,6 +129,38 @@ bool USRPDevice::make(bool wSkipRx)
#endif
+ switch (dboardConfig) {
+ case TXA_RXB:
+ m_dbTx = m_uTx->db(0)[0];
+ m_dbRx = m_uRx->db(1)[0];
+ txSubdevSpec = usrp_subdev_spec(0,0);
+ rxSubdevSpec = usrp_subdev_spec(1,0);
+ break;
+ case TXB_RXA:
+ m_dbTx = m_uTx->db(1)[0];
+ m_dbRx = m_uRx->db(0)[0];
+ txSubdevSpec = usrp_subdev_spec(1,0);
+ rxSubdevSpec = usrp_subdev_spec(0,0);
+ break;
+ case TXA_RXA:
+ m_dbTx = m_uTx->db(0)[0];
+ m_dbRx = m_uRx->db(0)[0];
+ txSubdevSpec = usrp_subdev_spec(0,0);
+ rxSubdevSpec = usrp_subdev_spec(0,0);
+ break;
+ case TXB_RXB:
+ m_dbTx = m_uTx->db(1)[0];
+ m_dbRx = m_uRx->db(1)[0];
+ txSubdevSpec = usrp_subdev_spec(1,0);
+ rxSubdevSpec = usrp_subdev_spec(1,0);
+ break;
+ default:
+ m_dbTx = m_uTx->db(0)[0];
+ m_dbRx = m_uRx->db(1)[0];
+ txSubdevSpec = usrp_subdev_spec(0,0);
+ rxSubdevSpec = usrp_subdev_spec(1,0);
+ }
+
samplesRead = 0;
samplesWritten = 0;
started = false;
@@ -247,38 +182,18 @@ bool USRPDevice::start()
writeLock.lock();
// power up and configure daughterboards
- m_uTx->_write_oe(0,0,0xffff);
- m_uTx->_write_oe(0,(POWER_UP|RX_TXN|ENABLE), 0xffff);
- m_uTx->write_io(0,(~POWER_UP|RX_TXN),(POWER_UP|RX_TXN|ENABLE));
- m_uTx->write_io(0,ENABLE,(RX_TXN | ENABLE));
- m_uTx->_write_fpga_reg(FR_ATR_MASK_0 ,0);//RX_TXN|ENABLE);
- m_uTx->_write_fpga_reg(FR_ATR_TXVAL_0,0);//,0 |ENABLE);
- m_uTx->_write_fpga_reg(FR_ATR_RXVAL_0,0);//,RX_TXN|0);
- m_uTx->_write_fpga_reg(40,0);
- m_uTx->_write_fpga_reg(42,0);
- m_uTx->set_pga(0,m_uTx->pga_max()); // should be 20dB
- m_uTx->set_pga(1,m_uTx->pga_max());
- m_uTx->set_mux(0x00000098);
- LOG(INFO) << "TX pgas: " << m_uTx->pga(0) << ", " << m_uTx->pga(1);
+ m_dbTx->set_enable(true);
+ m_uTx->set_mux(m_uTx->determine_tx_mux_value(txSubdevSpec));
+ m_uRx->set_mux(m_uRx->determine_rx_mux_value(rxSubdevSpec));
+
+ if (!m_dbRx->select_rx_antenna(1))
+ m_dbRx->select_rx_antenna(0);
+
writeLock.unlock();
- if (!skipRx) {
- writeLock.lock();
- m_uRx->_write_fpga_reg(FR_ATR_MASK_0 + 3*3,0);
- m_uRx->_write_fpga_reg(FR_ATR_TXVAL_0 + 3*3,0);
- m_uRx->_write_fpga_reg(FR_ATR_RXVAL_0 + 3*3,0);
- m_uRx->_write_fpga_reg(43,0);
- m_uRx->_write_oe(1,(POWER_UP|RX_TXN|ENABLE), 0xffff);
- m_uRx->write_io(1,(~POWER_UP|RX_TXN|ENABLE),(POWER_UP|RX_TXN|ENABLE));
- //m_uRx->write_io(1,0,RX2_RX1N); // using Tx/Rx/
- m_uRx->write_io(1,RX2_RX1N,RX2_RX1N); // using Rx2
- m_uRx->set_adc_buffer_bypass(2,true);
- m_uRx->set_adc_buffer_bypass(3,true);
- m_uRx->set_mux(0x00000032);
- writeLock.unlock();
- // FIXME -- This should be configurable.
- setRxGain(47); //maxRxGain());
- }
+ // Set gains to midpoint
+ setTxGain((minTxGain() + maxTxGain()) / 2);
+ setRxGain((minRxGain() + maxRxGain()) / 2);
data = new short[currDataSize];
dataStart = 0;
@@ -309,10 +224,6 @@ bool USRPDevice::stop()
if (!m_uRx) return false;
if (!m_uTx) return false;
- // power down
- m_uTx->write_io(0,(~POWER_UP|RX_TXN),(POWER_UP|RX_TXN|ENABLE));
- m_uRx->write_io(1,~POWER_UP,(POWER_UP|ENABLE));
-
delete[] currData;
started = !(m_uRx->stop() && m_uTx->stop());
@@ -322,16 +233,36 @@ bool USRPDevice::stop()
#endif
}
+double USRPDevice::maxTxGain()
+{
+ return m_dbTx->gain_max();
+}
+
+double USRPDevice::minTxGain()
+{
+ return m_dbTx->gain_min();
+}
+
+double USRPDevice::maxRxGain()
+{
+ return m_dbRx->gain_max();
+}
+
+double USRPDevice::minRxGain()
+{
+ return m_dbRx->gain_min();
+}
+
double USRPDevice::setTxGain(double dB) {
writeLock.lock();
if (dB > maxTxGain()) dB = maxTxGain();
if (dB < minTxGain()) dB = minTxGain();
- m_uTx->set_pga(0,dB);
- m_uTx->set_pga(1,dB);
+ LOG(NOTICE) << "Setting TX gain to " << dB << " dB.";
- LOG(NOTICE) << "Setting TX PGA to " << dB << " dB.";
+ if (!m_dbRx->set_gain(dB))
+ LOG(ERROR) << "Error setting TX gain";
writeLock.unlock();
@@ -345,30 +276,14 @@ double USRPDevice::setRxGain(double dB) {
if (dB > maxRxGain()) dB = maxRxGain();
if (dB < minRxGain()) dB = minRxGain();
- double dBret = dB;
-
- dB = dB - minRxGain();
-
- double rfMax = 70.0;
- if (dB > rfMax) {
- m_uRx->set_pga(2,dB-rfMax);
- m_uRx->set_pga(3,dB-rfMax);
- dB = rfMax;
- }
- else {
- m_uRx->set_pga(2,0);
- m_uRx->set_pga(3,0);
- }
- m_uRx->write_aux_dac(1,0,
- (int) ceil((1.2 + 0.02 - (dB/rfMax))*4096.0/3.3));
-
- LOG(DEBUG) << "Setting DAC voltage to " << (1.2+0.02 - (dB/rfMax)) << " " << (int) ceil((1.2 + 0.02 - (dB/rfMax))*4096.0/3.3);
-
- rxGain = dBret;
-
+ LOG(NOTICE) << "Setting TX gain to " << dB << " dB.";
+
+ if (!m_dbRx->set_gain(dB))
+ LOG(ERROR) << "Error setting RX gain";
+
writeLock.unlock();
- return dBret;
+ return dB;
}
@@ -484,13 +399,6 @@ int USRPDevice::readSamples(short *buf, int len, bool *overrun,
dataStart = (bufStart + len) % (currDataSize/2);
timeStart = timestamp + len;
- // do IQ swap here
- for (int i = 0; i < len; i++) {
- short tmp = usrp_to_host_short(buf[2*i]);
- buf[2*i] = usrp_to_host_short(buf[2*i+1]);
- buf[2*i+1] = tmp;
- }
-
return len;
#else
@@ -602,28 +510,46 @@ bool USRPDevice::updateAlignment(TIMESTAMP timestamp)
}
#ifndef SWLOOPBACK
-bool USRPDevice::setTxFreq(double wFreq) {
- // Tune to wFreq+LO_OFFSET, to prevent LO bleedthrough from interfering with transmitted signal.
- double actFreq;
- if (!tx_setFreq(wFreq+1*LO_OFFSET,&actFreq)) return false;
- bool retVal = m_uTx->set_tx_freq(0,(wFreq-actFreq));
- LOG(INFO) << "set TX: " << wFreq-actFreq << " actual TX: " << m_uTx->tx_freq(0);
- return retVal;
-};
+bool USRPDevice::setTxFreq(double wFreq)
+{
+ usrp_tune_result result;
-bool USRPDevice::setRxFreq(double wFreq) {
- // Tune to wFreq-2*LO_OFFSET, to
- // 1) prevent LO bleedthrough (as with the setTxFreq method above)
- // 2) The extra LO_OFFSET pushes potential transmitter energy (GSM BS->MS transmissions
- // are 45Mhz above MS->BS transmissions) into a notch of the baseband lowpass filter
- // in front of the ADC. This possibly gives us an extra 10-20dB Tx/Rx isolation.
- double actFreq;
- // FIXME -- This should bo configurable.
- if (!rx_setFreq(wFreq-2*LO_OFFSET,&actFreq)) return false;
- bool retVal = m_uRx->set_rx_freq(0,(wFreq-actFreq));
- LOG(DEBUG) << "set RX: " << wFreq-actFreq << " actual RX: " << m_uRx->rx_freq(0);
- return retVal;
-};
+ if (m_uTx->tune(0, m_dbTx, wFreq, &result)) {
+ LOG(INFO) << "set TX: " << wFreq << std::endl
+ << " baseband freq: " << result.baseband_freq << std::endl
+ << " DDC freq: " << result.dxc_freq << std::endl
+ << " residual freq: " << result.residual_freq;
+ return true;
+ }
+ else {
+ LOG(ERROR) << "set TX: " << wFreq << "failed" << std::endl
+ << " baseband freq: " << result.baseband_freq << std::endl
+ << " DDC freq: " << result.dxc_freq << std::endl
+ << " residual freq: " << result.residual_freq;
+ return false;
+ }
+}
+
+bool USRPDevice::setRxFreq(double wFreq)
+{
+ usrp_tune_result result;
+
+ if (m_uRx->tune(0, m_dbRx, wFreq, &result)) {
+ LOG(INFO) << "set RX: " << wFreq << std::endl
+ << " baseband freq: " << result.baseband_freq << std::endl
+ << " DDC freq: " << result.dxc_freq << std::endl
+ << " residual freq: " << result.residual_freq;
+ return true;
+ }
+ else {
+ LOG(ERROR) << "set RX: " << wFreq << "failed" << std::endl
+ << " baseband freq: " << result.baseband_freq << std::endl
+ << " DDC freq: " << result.dxc_freq << std::endl
+ << " residual freq: " << result.residual_freq;
+ return false;
+ }
+
+}
#else
bool USRPDevice::setTxFreq(double wFreq) { return true;};
diff --git a/Transceiver52M/USRPDevice.h b/Transceiver52M/USRPDevice.h
index 19aa043..588ab0c 100644
--- a/Transceiver52M/USRPDevice.h
+++ b/Transceiver52M/USRPDevice.h
@@ -54,7 +54,12 @@ private:
double desiredSampleRate; ///< the desired sampling rate
usrp_standard_rx_sptr m_uRx; ///< the USRP receiver
usrp_standard_tx_sptr m_uTx; ///< the USRP transmitter
-
+
+ db_base_sptr m_dbRx; ///< rx daughterboard
+ db_base_sptr m_dbTx; ///< tx daughterboard
+ usrp_subdev_spec rxSubdevSpec;
+ usrp_subdev_spec txSubdevSpec;
+
double actualSampleRate; ///< the actual USRP sampling rate
unsigned int decimRate; ///< the USRP decimation rate
@@ -98,66 +103,6 @@ private:
bool firstRead;
#endif
- /** Mess of constants used to control various hardware on the USRP */
- static const unsigned POWER_UP = (1 << 7);
- static const unsigned RX_TXN = (1 << 6);
- static const unsigned RX2_RX1N = (1 << 6);
- static const unsigned ENABLE = (1 << 5);
- static const unsigned PLL_LOCK_DETECT = (1 << 2);
-
- static const unsigned SPI_ENABLE_TX_A = 0x10;
- static const unsigned SPI_ENABLE_RX_A = 0x20;
- static const unsigned SPI_ENABLE_TX_B = 0x40;
- static const unsigned SPI_ENABLE_RX_B = 0x80;
-
- static const unsigned SPI_FMT_MSB = (0 << 7);
- static const unsigned SPI_FMT_HDR_0 = (0 << 5);
-
- static const float LO_OFFSET;
- //static const float LO_OFFSET = 4.0e6;
-
- static const unsigned R_DIV = 16;
- static const unsigned P = 1;
- static const unsigned CP2 = 7;
- static const unsigned CP1 = 7;
- static const unsigned DIVSEL = 0;
- unsigned DIV2; // changes with GSM band
- unsigned freq_mult; // changes with GSM band
- static const unsigned CPGAIN = 0;
-
- // R-Register Common Values
- static const unsigned R_RSV = 0; // bits 23,22
- static const unsigned BSC = 3; // bits 21,20 Div by 8 to be safe
- static const unsigned TEST = 0; // bit 19
- static const unsigned LDP = 1; // bit 18
- static const unsigned ABP = 0; // bit 17,16 3ns
-
- // N-Register Common Values
- static const unsigned N_RSV = 0; // bit 7
-
- // Control Register Common Values
- static const unsigned PD = 0; // bits 21,20 Normal operation
- static const unsigned PL = 0; // bits 13,12 11mA
- static const unsigned MTLD = 1; // bit 11 enabled
- static const unsigned CPG = 0; // bit 10 CP setting 1
- static const unsigned CP3S = 0; // bit 9 Normal
- static const unsigned PDP = 1; // bit 8 Positive
- static const unsigned MUXOUT = 1;// bits 7:5 Digital Lock Detect
- static const unsigned CR = 0; // bit 4 Normal
- static const unsigned PC = 1; // bits 3,2 Core power 10mA
-
- // ATR register value
- static const int FR_ATR_MASK_0 = 20;
- static const int FR_ATR_TXVAL_0 = 21;
- static const int FR_ATR_RXVAL_0 = 22;
-
- /** Compute register values to tune daughterboard to desired frequency */
- bool compute_regs(double freq,
- unsigned *R,
- unsigned *control,
- unsigned *N,
- double *actual_freq);
-
/** Set the transmission frequency */
bool tx_setFreq(double freq, double *actual_freq);
@@ -233,19 +178,19 @@ private:
double getRxGain(void) {return rxGain;}
/** return maximum Rx Gain **/
- double maxRxGain(void) {return 97.0;}
+ double maxRxGain(void);
/** return minimum Rx Gain **/
- double minRxGain(void) {return 7.0;}
+ double minRxGain(void);
/** sets the transmit chan gain, returns the gain setting **/
double setTxGain(double dB);
/** return maximum Tx Gain **/
- double maxTxGain(void) {return 0.0;}
+ double maxTxGain(void);
/** return minimum Rx Gain **/
- double minTxGain(void) {return -20.0;}
+ double minTxGain(void);
/** Return internal status values */