From bf383dd3ff216268361247915cc2e197277e649b Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Wed, 22 Dec 2010 03:15:17 -0500 Subject: [PATCH 1/2] Transceiver: 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; The gains are currently not configurable through the device API and default to midpoint for the installed daughterboard(s). Signed-off-by: Thomas Tsou --- public-trunk/Transceiver/USRPDevice.cpp | 236 ++++++++------------ public-trunk/Transceiver/USRPDevice.h | 76 +------ public-trunk/Transceiver/radioInterface.cpp | 11 +- 3 files changed, 96 insertions(+), 227 deletions(-) diff --git a/public-trunk/Transceiver/USRPDevice.cpp b/public-trunk/Transceiver/USRPDevice.cpp index 578b5b8..d1eca57 100644 --- a/public-trunk/Transceiver/USRPDevice.cpp +++ b/public-trunk/Transceiver/USRPDevice.cpp @@ -41,101 +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) 64.0e6; - -bool USRPDevice::compute_regs(double freq, - unsigned *R, - unsigned *control, - unsigned *N, - double *actual_freq) -{ - - float phdet_freq = 64.0e6/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; - - 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)); - - 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; - - 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)); - - - 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 = 64.0e6; USRPDevice::USRPDevice (double _desiredSampleRate) { @@ -212,6 +126,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; @@ -229,36 +175,17 @@ bool USRPDevice::start() if (!skipRx) m_uRx->stop(); m_uTx->stop(); - // 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,ENABLE,(POWER_UP|RX_TXN|ENABLE)); /* POWER_UP inverted */ - 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); + // Transmit settings - gain at midpoint + m_dbTx->set_gain((m_dbRx->gain_min() + m_dbRx->gain_max()) / 2); + m_dbTx->set_enable(true); + m_uTx->set_mux(m_uTx->determine_tx_mux_value(txSubdevSpec)); - if (!skipRx) { - 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,(RX_TXN|ENABLE),(POWER_UP|RX_TXN|ENABLE)); /* POWER_UP inverted */ - //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_pga(2,m_uRx->pga_max()); // should be 20dB - m_uRx->set_pga(3,m_uRx->pga_max()); - m_uRx->set_mux(0x00000032); - m_uRx->write_aux_dac(1,0,(int) ceil(0.2*4096.0/3.3)); // set to maximum gain - } + // Receive settings - gain at max, antenna RX2 (if available) + m_dbRx->set_gain(m_dbRx->gain_max()); + m_uRx->set_mux(m_uRx->determine_rx_mux_value(rxSubdevSpec)); + + if (!m_dbRx->select_rx_antenna(1)) + m_dbRx->select_rx_antenna(0); data = new short[currDataSize]; dataStart = 0; @@ -271,7 +198,6 @@ bool USRPDevice::start() hi32Timestamp = 0; isAligned = false; - if (!skipRx) started = (m_uRx->start() && m_uTx->start()); else @@ -289,10 +215,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()); @@ -519,27 +441,45 @@ 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+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; - 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/public-trunk/Transceiver/USRPDevice.h b/public-trunk/Transceiver/USRPDevice.h index b8385ca..1ab5a8a 100644 --- a/public-trunk/Transceiver/USRPDevice.h +++ b/public-trunk/Transceiver/USRPDevice.h @@ -63,7 +63,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 @@ -103,75 +108,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; - static const unsigned DIV2 = 1; - static const unsigned freq_mult = 2; - static const unsigned CPGAIN = 0; - static const float minFreq = 800e6; - static const float maxFreq = 1000e6; - static const float freqRes = 4e6; - - // 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); - - /** Set the receiver frequency */ - bool rx_setFreq(double freq, double *actual_freq); - public: /** Object constructor */ diff --git a/public-trunk/Transceiver/radioInterface.cpp b/public-trunk/Transceiver/radioInterface.cpp index 69e2687..559daa9 100644 --- a/public-trunk/Transceiver/radioInterface.cpp +++ b/public-trunk/Transceiver/radioInterface.cpp @@ -97,16 +97,9 @@ signalVector *RadioInterface::unUSRPifyVector(short *shortVector, int numSamples signalVector::iterator itr = newVector->begin(); short *shortItr = shortVector; -// need to flip I and Q from USRP -#ifndef SWLOOPBACK -#define FLIP_IQ 1 -#else -#define FLIP_IQ 0 -#endif - while (itr < newVector->end()) { - *itr++ = Complex(usrp_to_host_short(*(shortItr+FLIP_IQ)), - usrp_to_host_short(*(shortItr+1-FLIP_IQ))); + *itr++ = Complex(usrp_to_host_short(*(shortItr)), + usrp_to_host_short(*(shortItr+1))); //LOG(DEEPDEBUG) << (*(itr-1)); shortItr += 2; } From dff752739d639a513f29f75fed53cda4657bf904 Mon Sep 17 00:00:00 2001 From: Thomas Tsou Date: Wed, 22 Dec 2010 02:53:25 -0500 Subject: [PATCH 2/2] 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 --- public-trunk/Transceiver52M/USRPDevice.cpp | 309 ++++++++------------- public-trunk/Transceiver52M/USRPDevice.h | 75 +---- 2 files changed, 127 insertions(+), 257 deletions(-) diff --git a/public-trunk/Transceiver52M/USRPDevice.cpp b/public-trunk/Transceiver52M/USRPDevice.cpp index 21b66b4..56bc2b3 100644 --- a/public-trunk/Transceiver52M/USRPDevice.cpp +++ b/public-trunk/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,39 +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,ENABLE,(POWER_UP|RX_TXN|ENABLE)); /* POWER_UP inverted */ - 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,(RX_TXN|ENABLE),(POWER_UP|RX_TXN|ENABLE)); /* POWER_UP inverted */ - //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_pga(2,m_uRx->pga_max()); // should be 20dB - m_uRx->set_pga(3,m_uRx->pga_max()); - 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; @@ -310,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()); @@ -323,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(); @@ -346,30 +276,14 @@ double USRPDevice::setRxGain(double dB) { if (dB > maxRxGain()) dB = maxRxGain(); if (dB < minRxGain()) dB = minRxGain(); - double dBret = dB; + LOG(NOTICE) << "Setting TX gain to " << dB << " 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; - + if (!m_dbRx->set_gain(dB)) + LOG(ERROR) << "Error setting RX gain"; + writeLock.unlock(); - return dBret; + return dB; } @@ -485,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 @@ -603,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+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/public-trunk/Transceiver52M/USRPDevice.h b/public-trunk/Transceiver52M/USRPDevice.h index 3428676..1be0191 100644 --- a/public-trunk/Transceiver52M/USRPDevice.h +++ b/public-trunk/Transceiver52M/USRPDevice.h @@ -64,7 +64,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 @@ -108,66 +113,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); @@ -243,19 +188,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 */