diff options
Diffstat (limited to 'usrp/host/lib/legacy/db_flexrf.cc')
-rw-r--r-- | usrp/host/lib/legacy/db_flexrf.cc | 1148 |
1 files changed, 1148 insertions, 0 deletions
diff --git a/usrp/host/lib/legacy/db_flexrf.cc b/usrp/host/lib/legacy/db_flexrf.cc new file mode 100644 index 000000000..662d9095c --- /dev/null +++ b/usrp/host/lib/legacy/db_flexrf.cc @@ -0,0 +1,1148 @@ +// +// Copyright 2008 Free Software Foundation, Inc. +// +// This file is part of GNU Radio +// +// GNU Radio is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either asversion 3, or (at your option) +// any later version. +// +// GNU Radio is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with GNU Radio; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, +// Boston, MA 02110-1301, USA. + +#include <db_flexrf.h> +#include <db_base_impl.h> + +// d'board i/o pin defs +// Tx and Rx have shared defs, but different i/o regs +#define AUX_RXAGC (1 << 8) +#define POWER_UP (1 << 7) // enables power supply +#define RX_TXN (1 << 6) // Tx only: T/R antenna switch for TX/RX port +#define RX2_RX1N (1 << 6) // Rx only: antenna switch between RX2 and TX/RX port +#define ENABLE (1 << 5) // enables mixer +#define AUX_SEN (1 << 4) +#define AUX_SCLK (1 << 3) +#define PLL_LOCK_DETECT (1 << 2) +#define AUX_SDO (1 << 1) +#define CLOCK_OUT (1 << 0) + +flexrf_base::flexrf_base(usrp_basic_sptr _usrp, int which, int _power_on) + : db_base(_usrp, which), d_power_on(_power_on) +{ + /* + @param usrp: instance of usrp.source_c + @param which: which side: 0 or 1 corresponding to side A or B respectively + @type which: int + */ + + d_first = true; + d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; + + usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs + _enable_refclk(false); // disable refclk + + set_auto_tr(false); +} + +flexrf_base::~flexrf_base() +{ + delete d_common; +} + +void +flexrf_base::_write_all(int R, int control, int N) +{ + /* + Write R counter latch, control latch and N counter latch to VCO. + + Adds 10ms delay between writing control and N if this is first call. + This is the required power-up sequence. + + @param R: 24-bit R counter latch + @type R: int + @param control: 24-bit control latch + @type control: int + @param N: 24-bit N counter latch + @type N: int + */ + timespec t; + t.tv_sec = 0; + t.tv_nsec = 10000000; + + _write_R(R); + _write_control(control); + if(d_first) { + //time.sleep(0.010); + nanosleep(&t, NULL); + d_first = false; + } + _write_N(N); +} + +void +flexrf_base::_write_control(int control) +{ + _write_it((control & ~0x3) | 0); +} + +void +flexrf_base::_write_R(int R) +{ + _write_it((R & ~0x3) | 1); +} + +void +flexrf_base::_write_N(int N) +{ + _write_it((N & ~0x3) | 2); +} + +void +flexrf_base::_write_it(int v) +{ + char s[3]; + s[0] = (char)((v >> 16) & 0xff); + s[1] = (char)((v >> 8) & 0xff); + s[2] = (char)(v & 0xff); + std::string str(s, 3); + usrp()->_write_spi(0, d_spi_enable, d_spi_format, str); +} + +bool +flexrf_base::_lock_detect() +{ + /* + @returns: the value of the VCO/PLL lock detect bit. + @rtype: 0 or 1 + */ + if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) { + return true; + } + else { // Give it a second chance + // FIXME: make portable sleep + timespec t; + t.tv_sec = 0; + t.tv_nsec = 100000000; + nanosleep(&t, NULL); + + if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) { + return true; + } + else { + return false; + } + } +} + +bool +flexrf_base::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + /* + Determine values of R, control, and N registers, along with actual freq. + + @param freq: target frequency in Hz + @type freq: float + @returns: (R, control, N, actual_freq) + @rtype: tuple(int, int, int, float) + + Override this in derived classes. + */ + + //raise NotImplementedError; + throw std::runtime_error("_compute_regs called from flexrf_base\n"); +} + +int +flexrf_base::_compute_control_reg() +{ + return d_common->_compute_control_reg(); +} + +int +flexrf_base::_refclk_divisor() +{ + return d_common->_refclk_divisor(); +} + +double +flexrf_base::_refclk_freq() +{ + return 64e6/_refclk_divisor(); +} + +struct freq_result_t +flexrf_base::set_freq(double freq) +{ + /* + @returns (ok, actual_baseband_freq) where: + ok is True or False and indicates success or failure, + actual_baseband_freq is the RF frequency that corresponds to DC in the IF. + */ + + struct freq_result_t args = {false, 0}; + + // Offsetting the LO helps get the Tx carrier leakage out of the way. + // This also ensures that on Rx, we're not getting hosed by the + // FPGA's DC removal loop's time constant. We were seeing a + // problem when running with discontinuous transmission. + // Offsetting the LO made the problem go away. + freq += d_lo_offset; + + int R, control, N; + double actual_freq; + _compute_regs(freq, R, control, N, actual_freq); + + if(R==0) { + return args; + } + + _write_all(R, control, N); + args.ok = _lock_detect(); + args.baseband_freq = actual_freq; + return args; +} + +bool +flexrf_base::_set_pga(float pga_gain) +{ + if(d_which == 0) { + usrp()->set_pga(0, pga_gain); + usrp()->set_pga(1, pga_gain); + } + else { + usrp()->set_pga(2, pga_gain); + usrp()->set_pga(3, pga_gain); + } + return true; +} + +bool +flexrf_base::is_quadrature() +{ + /* + Return True if this board requires both I & Q analog channels. + + This bit of info is useful when setting up the USRP Rx mux register. + */ + return true; +} + +double +flexrf_base::freq_min() +{ + return d_common->freq_min(); +} + +double +flexrf_base::freq_max() +{ + return d_common->freq_max(); +} + +// ---------------------------------------------------------------- + +flexrf_base_tx::flexrf_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) + : flexrf_base(_usrp, which, _power_on) +{ + /* + @param usrp: instance of usrp.sink_c + @param which: 0 or 1 corresponding to side TX_A or TX_B respectively. + */ + + if(which == 0) { + d_spi_enable = SPI_ENABLE_TX_A; + } + else { + d_spi_enable = SPI_ENABLE_TX_B; + } + + // power up the transmit side, but don't enable the mixer + usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff); + usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE)); + set_lo_offset(4e6); + + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain +} + +flexrf_base_tx::~flexrf_base_tx() +{ + shutdown(); +} + + +void +flexrf_base_tx::shutdown() +{ + // fprintf(stderr, "flexrf_base_tx::shutdown d_is_shutdown = %d\n", d_is_shutdown); + + if (!d_is_shutdown){ + d_is_shutdown = true; + // do whatever there is to do to shutdown + + // Power down and leave the T/R switch in the R position + usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE)); + + // Power down VCO/PLL + d_PD = 3; + + _write_control(_compute_control_reg()); + _enable_refclk(false); // turn off refclk + set_auto_tr(false); + } +} + +bool +flexrf_base_tx::set_auto_tr(bool on) +{ + bool ok = true; + if(on) { + ok &= set_atr_mask (RX_TXN | ENABLE); + ok &= set_atr_txval(0 | ENABLE); + ok &= set_atr_rxval(RX_TXN | 0); + } + else { + ok &= set_atr_mask (0); + ok &= set_atr_txval(0); + ok &= set_atr_rxval(0); + } + return ok; +} + +bool +flexrf_base_tx::set_enable(bool on) +{ + /* + Enable transmitter if on is true + */ + + int v; + int mask = RX_TXN | ENABLE; + if(on) { + v = ENABLE; + } + else { + v = RX_TXN; + } + return usrp()->write_io(d_which, v, mask); +} + +float +flexrf_base_tx::gain_min() +{ + return usrp()->pga_max(); +} + +float +flexrf_base_tx::gain_max() +{ + return usrp()->pga_max(); +} + +float +flexrf_base_tx::gain_db_per_step() +{ + return 1; +} + +bool +flexrf_base_tx::set_gain(float gain) +{ + /* + Set the gain. + + @param gain: gain in decibels + @returns True/False + */ + return _set_pga(usrp()->pga_max()); +} + + +/**************************************************************************/ + + +flexrf_base_rx::flexrf_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) + : flexrf_base(_usrp, which, _power_on) +{ + /* + @param usrp: instance of usrp.source_c + @param which: 0 or 1 corresponding to side RX_A or RX_B respectively. + */ + + if(which == 0) { + d_spi_enable = SPI_ENABLE_RX_A; + } + else { + d_spi_enable = SPI_ENABLE_RX_B; + } + + usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff); + usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE), + (POWER_UP|RX2_RX1N|ENABLE)); + + // set up for RX on TX/RX port + select_rx_antenna("TX/RX"); + + bypass_adc_buffers(true); + + set_lo_offset(-4e6); +} + +flexrf_base_rx::~flexrf_base_rx() +{ + shutdown(); +} + +void +flexrf_base_rx::shutdown() +{ + // fprintf(stderr, "flexrf_base_rx::shutdown d_is_shutdown = %d\n", d_is_shutdown); + + if (!d_is_shutdown){ + d_is_shutdown = true; + // do whatever there is to do to shutdown + + // Power down + usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE)); + + // Power down VCO/PLL + d_PD = 3; + + + // fprintf(stderr, "flexrf_base_rx::shutdown before _write_control\n"); + _write_control(_compute_control_reg()); + + // fprintf(stderr, "flexrf_base_rx::shutdown before _enable_refclk\n"); + _enable_refclk(false); // turn off refclk + + // fprintf(stderr, "flexrf_base_rx::shutdown before set_auto_tr\n"); + set_auto_tr(false); + + // fprintf(stderr, "flexrf_base_rx::shutdown after set_auto_tr\n"); + } +} + +bool +flexrf_base_rx::set_auto_tr(bool on) +{ + bool ok = true; + if(on) { + ok &= set_atr_mask (ENABLE); + ok &= set_atr_txval( 0); + ok &= set_atr_rxval(ENABLE); + } + else { + ok &= set_atr_mask (0); + ok &= set_atr_txval(0); + ok &= set_atr_rxval(0); + } + return true; +} + +bool +flexrf_base_rx::select_rx_antenna(int which_antenna) +{ + /* + Specify which antenna port to use for reception. + @param which_antenna: either 'TX/RX' or 'RX2' + */ + + if(which_antenna == 0) { + usrp()->write_io(d_which, 0,RX2_RX1N); + } + else if(which_antenna == 1) { + usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N); + } + else { + return false; + // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n"); + } + return true; +} + +bool +flexrf_base_rx::select_rx_antenna(const std::string &which_antenna) +{ + /* + Specify which antenna port to use for reception. + @param which_antenna: either 'TX/RX' or 'RX2' + */ + + if(which_antenna == "TX/RX") { + usrp()->write_io(d_which, 0, RX2_RX1N); + } + else if(which_antenna == "RX2") { + usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N); + } + else { + // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n"); + return false; + } + return true; +} + +bool +flexrf_base_rx::set_gain(float gain) +{ + /* + Set the gain. + + @param gain: gain in decibels + @returns True/False + */ + + // clamp gain + gain = std::max(gain_min(), std::min(gain, gain_max())); + + float pga_gain, agc_gain; + float V_maxgain, V_mingain, V_fullscale, dac_value; + + float maxgain = gain_max() - usrp()->pga_max(); + float mingain = gain_min(); + if(gain > maxgain) { + pga_gain = gain-maxgain; + assert(pga_gain <= usrp()->pga_max()); + agc_gain = maxgain; + } + else { + pga_gain = 0; + agc_gain = gain; + } + + V_maxgain = .2; + V_mingain = 1.2; + V_fullscale = 3.3; + dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale; + + assert(dac_value>=0 && dac_value<4096); + + return (usrp()->write_aux_dac(d_which, 0, int(dac_value)) + && _set_pga(int(pga_gain))); +} + +// ---------------------------------------------------------------- + + +_AD4360_common::_AD4360_common() +{ + // R-Register Common Values + d_R_RSV = 0; // bits 23,22 + d_BSC = 3; // bits 21,20 Div by 8 to be safe + d_TEST = 0; // bit 19 + d_LDP = 1; // bit 18 + d_ABP = 0; // bit 17,16 3ns + + // N-Register Common Values + d_N_RSV = 0; // bit 7 + + // Control Register Common Values + d_PD = 0; // bits 21,20 Normal operation + d_PL = 0; // bits 13,12 11mA + d_MTLD = 1; // bit 11 enabled + d_CPG = 0; // bit 10 CP setting 1 + d_CP3S = 0; // bit 9 Normal + d_PDP = 1; // bit 8 Positive + d_MUXOUT = 1; // bits 7:5 Digital Lock Detect + d_CR = 0; // bit 4 Normal + d_PC = 1; // bits 3,2 Core power 10mA +} + +_AD4360_common::~_AD4360_common() +{ +} + +bool +_AD4360_common::_compute_regs(double refclk_freq, double freq, int &retR, + int &retcontrol, int &retN, double &retfreq) +{ + /* + Determine values of R, control, and N registers, along with actual freq. + + @param freq: target frequency in Hz + @type freq: float + @returns: (R, control, N, actual_freq) + @rtype: tuple(int, int, int, float) + */ + + // Band-specific N-Register Values + //float phdet_freq = _refclk_freq()/d_R_DIV; + double phdet_freq = refclk_freq/d_R_DIV; + double desired_n = round(freq*d_freq_mult/phdet_freq); + double actual_freq = desired_n * phdet_freq; + int B = floor(desired_n/_prescaler()); + int A = desired_n - _prescaler()*B; + d_B_DIV = int(B); // bits 20:8 + d_A_DIV = int(A); // bit 6:2 + + //assert db_B_DIV >= db_A_DIV + if(d_B_DIV < d_A_DIV) { + retR = 0; + retcontrol = 0; + retN = 0; + retfreq = 0; + return false; + } + + int R = (d_R_RSV<<22) | (d_BSC<<20) | (d_TEST<<19) | + (d_LDP<<18) | (d_ABP<<16) | (d_R_DIV<<2); + + int control = _compute_control_reg(); + + int N = (d_DIVSEL<<23) | (d_DIV2<<22) | (d_CPGAIN<<21) | + (d_B_DIV<<8) | (d_N_RSV<<7) | (d_A_DIV<<2); + + retR = R; + retcontrol = control; + retN = N; + retfreq = actual_freq/d_freq_mult; + return true; +} + +int +_AD4360_common::_compute_control_reg() +{ + int control = (d_P<<22) | (d_PD<<20) | (d_CP2<<17) | (d_CP1<<14) + | (d_PL<<12) | (d_MTLD<<11) | (d_CPG<<10) | (d_CP3S<<9) | (d_PDP<<8) + | (d_MUXOUT<<5) | (d_CR<<4) | (d_PC<<2); + + return control; +} + +int +_AD4360_common::_refclk_divisor() +{ + /* + Return value to stick in REFCLK_DIVISOR register + */ + return 1; +} + +int +_AD4360_common::_prescaler() +{ + if(d_P == 0) { + return 8; + } + else if(d_P == 1) { + return 16; + } + else { + return 32; + } +} + +//---------------------------------------------------------------------- + +_2400_common::_2400_common() + : _AD4360_common() +{ + // Band-specific R-Register Values + d_R_DIV = 16; // bits 15:2 + + // Band-specific C-Register values + d_P = 1; // bits 23,22 Div by 16/17 + d_CP2 = 7; // bits 19:17 + d_CP1 = 7; // bits 16:14 + + // Band specifc N-Register Values + d_DIVSEL = 0; // bit 23 + d_DIV2 = 0; // bit 22 + d_CPGAIN = 0; // bit 21 + d_freq_mult = 1; +} + +double +_2400_common::freq_min() +{ + return 2300e6; +} + +double +_2400_common::freq_max() +{ + return 2700e6; +} + +//---------------------------------------------------------------------- + +_1200_common::_1200_common() + : _AD4360_common() +{ + // Band-specific R-Register Values + d_R_DIV = 16; // bits 15:2 DIV by 16 for a 1 MHz phase detector freq + + // Band-specific C-Register values + d_P = 1; // bits 23,22 Div by 16/17 + d_CP2 = 7; // bits 19:17 1.25 mA + d_CP1 = 7; // bits 16:14 1.25 mA + + // Band specifc N-Register Values + d_DIVSEL = 0; // bit 23 + d_DIV2 = 1; // bit 22 + d_CPGAIN = 0; // bit 21 + d_freq_mult = 2; +} + +double +_1200_common::freq_min() +{ + return 1150e6; +} + +double +_1200_common::freq_max() +{ + return 1350e6; +} + +//------------------------------------------------------------------------- + +_1800_common::_1800_common() + : _AD4360_common() +{ + // Band-specific R-Register Values + d_R_DIV = 16; // bits 15:2 DIV by 16 for a 1 MHz phase detector freq + + // Band-specific C-Register values + d_P = 1; // bits 23,22 Div by 16/17 + d_CP2 = 7; // bits 19:17 1.25 mA + d_CP1 = 7; // bits 16:14 1.25 mA + + // Band specifc N-Register Values + d_DIVSEL = 0; // bit 23 + d_DIV2 = 0; // bit 22 + d_freq_mult = 1; + d_CPGAIN = 0; // bit 21 +} + +double +_1800_common::freq_min() +{ + return 1600e6; +} + +double +_1800_common::freq_max() +{ + return 2000e6; +} + +//------------------------------------------------------------------------- + +_900_common::_900_common() + : _AD4360_common() +{ + // Band-specific R-Register Values + d_R_DIV = 16; // bits 15:2 DIV by 16 for a 1 MHz phase detector freq + + // Band-specific C-Register values + d_P = 1; // bits 23,22 Div by 16/17 + d_CP2 = 7; // bits 19:17 1.25 mA + d_CP1 = 7; // bits 16:14 1.25 mA + + // Band specifc N-Register Values + d_DIVSEL = 0; // bit 23 + d_DIV2 = 1; // bit 22 + d_freq_mult = 2; + d_CPGAIN = 0; // bit 21 +} + +double +_900_common::freq_min() +{ + return 800e6; +} + +double +_900_common::freq_max() +{ + return 1000e6; +} + +//------------------------------------------------------------------------- + +_400_common::_400_common() + : _AD4360_common() +{ + // Band-specific R-Register Values + d_R_DIV = 16; // bits 15:2 + + // Band-specific C-Register values + d_P = 0; // bits 23,22 Div by 8/9 + d_CP2 = 7; // bits 19:17 1.25 mA + d_CP1 = 7; // bits 16:14 1.25 mA + + // Band specifc N-Register Values These are different for TX/RX + d_DIVSEL = 0; // bit 23 + d_freq_mult = 2; + + d_CPGAIN = 0; // bit 21 +} + +double +_400_common::freq_min() +{ + return 400e6; +} + +double +_400_common::freq_max() +{ + return 500e6; +} + +_400_tx::_400_tx() + : _400_common() +{ + d_DIV2 = 1; // bit 22 +} + +_400_rx::_400_rx() + : _400_common() +{ + d_DIV2 = 0; // bit 22 // RX side has built-in DIV2 in AD8348 +} + +//------------------------------------------------------------ + +db_flexrf_2400_tx::db_flexrf_2400_tx(usrp_basic_sptr usrp, int which) + : flexrf_base_tx(usrp, which) +{ + d_common = new _2400_common(); +} + +db_flexrf_2400_tx::~db_flexrf_2400_tx() +{ +} + +bool +db_flexrf_2400_tx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + + +db_flexrf_2400_rx::db_flexrf_2400_rx(usrp_basic_sptr usrp, int which) + : flexrf_base_rx(usrp, which) +{ + d_common = new _2400_common(); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain +} + +db_flexrf_2400_rx::~db_flexrf_2400_rx() +{ +} + +float +db_flexrf_2400_rx::gain_min() +{ + return usrp()->pga_min(); +} + +float +db_flexrf_2400_rx::gain_max() +{ + return usrp()->pga_max()+70; +} + +float +db_flexrf_2400_rx::gain_db_per_step() +{ + return 0.05; +} + + +bool +db_flexrf_2400_rx::i_and_q_swapped() +{ + return true; +} + +bool +db_flexrf_2400_rx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + +//------------------------------------------------------------ + + +db_flexrf_1200_tx::db_flexrf_1200_tx(usrp_basic_sptr usrp, int which) + : flexrf_base_tx(usrp, which) +{ + d_common = new _1200_common(); +} + +db_flexrf_1200_tx::~db_flexrf_1200_tx() +{ +} + +bool +db_flexrf_1200_tx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + + + +db_flexrf_1200_rx::db_flexrf_1200_rx(usrp_basic_sptr usrp, int which) + : flexrf_base_rx(usrp, which) +{ + d_common = new _1200_common(); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain +} + +db_flexrf_1200_rx::~db_flexrf_1200_rx() +{ +} + +float +db_flexrf_1200_rx::gain_min() +{ + return usrp()->pga_min(); +} + +float +db_flexrf_1200_rx::gain_max() +{ + return usrp()->pga_max()+70; +} + +float +db_flexrf_1200_rx::gain_db_per_step() +{ + return 0.05; +} + +bool +db_flexrf_1200_rx::i_and_q_swapped() +{ + return true; +} + +bool +db_flexrf_1200_rx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + +//------------------------------------------------------------ + + +db_flexrf_1800_tx::db_flexrf_1800_tx(usrp_basic_sptr usrp, int which) + : flexrf_base_tx(usrp, which) +{ + d_common = new _1800_common(); +} + +db_flexrf_1800_tx::~db_flexrf_1800_tx() +{ +} + +bool +db_flexrf_1800_tx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + + +db_flexrf_1800_rx::db_flexrf_1800_rx(usrp_basic_sptr usrp, int which) + : flexrf_base_rx(usrp, which) +{ + d_common = new _1800_common(); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain +} + +db_flexrf_1800_rx::~db_flexrf_1800_rx() +{ +} + + +float +db_flexrf_1800_rx::gain_min() +{ + return usrp()->pga_min(); +} + +float +db_flexrf_1800_rx::gain_max() +{ + return usrp()->pga_max()+70; +} + +float +db_flexrf_1800_rx::gain_db_per_step() +{ + return 0.05; +} + +bool +db_flexrf_1800_rx::i_and_q_swapped() +{ + return true; +} + +bool +db_flexrf_1800_rx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + +//------------------------------------------------------------ + + +db_flexrf_900_tx::db_flexrf_900_tx(usrp_basic_sptr usrp, int which) + : flexrf_base_tx(usrp, which) +{ + d_common = new _900_common(); +} + +db_flexrf_900_tx::~db_flexrf_900_tx() +{ +} + +bool +db_flexrf_900_tx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + +db_flexrf_900_rx::db_flexrf_900_rx(usrp_basic_sptr usrp, int which) + : flexrf_base_rx(usrp, which) +{ + d_common = new _900_common(); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain +} + +db_flexrf_900_rx::~db_flexrf_900_rx() +{ +} + +float +db_flexrf_900_rx::gain_min() +{ + return usrp()->pga_min(); +} + +float +db_flexrf_900_rx::gain_max() +{ + return usrp()->pga_max()+70; +} + +float +db_flexrf_900_rx::gain_db_per_step() +{ + return 0.05; +} + +bool +db_flexrf_900_rx::i_and_q_swapped() +{ + return true; +} + +bool +db_flexrf_900_rx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + +//------------------------------------------------------------ + + +db_flexrf_400_tx::db_flexrf_400_tx(usrp_basic_sptr usrp, int which) + : flexrf_base_tx(usrp, which, POWER_UP) +{ + d_common = new _400_tx(); +} + +db_flexrf_400_tx::~db_flexrf_400_tx() +{ +} + +bool +db_flexrf_400_tx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + + + +db_flexrf_400_rx::db_flexrf_400_rx(usrp_basic_sptr usrp, int which) + : flexrf_base_rx(usrp, which, POWER_UP) +{ + d_common = new _400_rx(); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain +} + +db_flexrf_400_rx::~db_flexrf_400_rx() +{ +} + +float +db_flexrf_400_rx::gain_min() +{ + return usrp()->pga_min(); +} + +float +db_flexrf_400_rx::gain_max() +{ + return usrp()->pga_max()+45; +} + +float + +db_flexrf_400_rx::gain_db_per_step() +{ + return 0.035; +} + + +bool +db_flexrf_400_rx::i_and_q_swapped() +{ + return true; +} + +bool +db_flexrf_400_rx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); +} + |