From 052e7a2c880edbc0dd55dc05d2758d3730cf9cb8 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Mon, 17 Aug 2009 23:30:01 -0700 Subject: Initial compile of wbxng, properly sets db IDs --- usrp/host/apps/burn-db-eeprom | 1 + usrp/host/include/usrp/Makefile.am | 1 + usrp/host/include/usrp/db_wbxng.h | 92 +++++ usrp/host/lib/Makefile.am | 1 + usrp/host/lib/db_boards.cc | 8 + usrp/host/lib/db_wbxng.cc | 809 +++++++++++++++++++++++++++++++++++++ usrp/host/lib/usrp_dbid.dat | 3 + 7 files changed, 915 insertions(+) create mode 100644 usrp/host/include/usrp/db_wbxng.h create mode 100644 usrp/host/lib/db_wbxng.cc (limited to 'usrp') diff --git a/usrp/host/apps/burn-db-eeprom b/usrp/host/apps/burn-db-eeprom index 34f4c7015..195c4e897 100755 --- a/usrp/host/apps/burn-db-eeprom +++ b/usrp/host/apps/burn-db-eeprom @@ -69,6 +69,7 @@ daughterboards = { 'lftx' : ((LF_TX, 0x0000), None), 'lfrx' : (None, (LF_RX, 0x0000)), 'wbx_lo' : ((WBX_LO_TX, 0x0000), (WBX_LO_RX, 0x0000)), + 'wbx_ng' : ((WBX_NG_TX, 0x0000), (WBX_NG_RX, 0x0000)), 'xcvr2450' : ((XCVR2450_TX, 0x0000), (XCVR2450_RX, 0x0000)), 'experimental_tx' : ((EXPERIMENTAL_TX, 0x0000), None), 'experimental_rx' : (None, (EXPERIMENTAL_RX, 0x0000)), diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am index 769acc774..83e86da7e 100644 --- a/usrp/host/include/usrp/Makefile.am +++ b/usrp/host/include/usrp/Makefile.am @@ -33,6 +33,7 @@ usrpinclude_HEADERS = \ db_flexrf_mimo.h \ db_tv_rx.h \ db_tv_rx_mimo.h \ + db_wbxng.h \ db_xcvr2450.h \ libusb_types.h \ usrp_basic.h \ diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h new file mode 100644 index 000000000..b255cf91c --- /dev/null +++ b/usrp/host/include/usrp/db_wbxng.h @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +// +// Copyright 2008,2009 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. + +#ifndef DB_WBXNG_H +#define DB_WBXNG_H + +#include <usrp/db_base.h> +#include <boost/shared_ptr.hpp> + +class wbxng; +typedef boost::shared_ptr<wbxng> wbxng_sptr; + + +/******************************************************************************/ + + +class db_wbxng_base: public db_base +{ + /* + * Abstract base class for all wbxng boards. + * + * Derive board specific subclasses from db_wbxng_base_{tx,rx} + */ +public: + db_wbxng_base(usrp_basic_sptr usrp, int which); + ~db_wbxng_base(); + struct freq_result_t set_freq(double target_freq); + bool is_quadrature(); + double freq_min(); + double freq_max(); + +protected: + wbxng_sptr d_wbxng; + void shutdown_common(); +}; + + +/******************************************************************************/ + + +class db_wbxng_tx : public db_wbxng_base +{ +protected: + void shutdown(); + +public: + db_wbxng_tx(usrp_basic_sptr usrp, int which); + ~db_wbxng_tx(); + + float gain_min(); + float gain_max(); + float gain_db_per_step(); + bool set_gain(float gain); + bool i_and_q_swapped(); +}; + +class db_wbxng_rx : public db_wbxng_base +{ +protected: + void shutdown(); + +public: + db_wbxng_rx(usrp_basic_sptr usrp, int which); + ~db_wbxng_rx(); + + float gain_min(); + float gain_max(); + float gain_db_per_step(); + bool set_gain(float gain); +}; + + + +#endif diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am index 2f8cbe6de..4b889993b 100644 --- a/usrp/host/lib/Makefile.am +++ b/usrp/host/lib/Makefile.am @@ -130,6 +130,7 @@ libusrp_la_common_SOURCES = \ db_flexrf.cc \ db_flexrf_mimo.cc \ db_dbs_rx.cc \ + db_wbxng.cc \ db_xcvr2450.cc \ db_dtt754.cc \ db_dtt768.cc \ diff --git a/usrp/host/lib/db_boards.cc b/usrp/host/lib/db_boards.cc index 8ef5bac8b..53304bd1a 100644 --- a/usrp/host/lib/db_boards.cc +++ b/usrp/host/lib/db_boards.cc @@ -32,6 +32,7 @@ #include <usrp/db_dbs_rx.h> #include <usrp/db_flexrf.h> #include <usrp/db_flexrf_mimo.h> +#include <usrp/db_wbxng.h> #include <usrp/db_xcvr2450.h> #include <usrp/db_dtt754.h> #include <usrp/db_dtt768.h> @@ -194,6 +195,13 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side) break; #endif + case(USRP_DBID_WBX_NG_TX): + db.push_back(db_base_sptr(new db_wbxng_tx(usrp, which_side))); + break; + case(USRP_DBID_WBX_NG_RX): + db.push_back(db_base_sptr(new db_wbxng_rx(usrp, which_side))); + break; + case(USRP_DBID_DTT754): db.push_back(db_base_sptr(new db_dtt754(usrp, which_side))); break; diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc new file mode 100644 index 000000000..53ec27afc --- /dev/null +++ b/usrp/host/lib/db_wbxng.cc @@ -0,0 +1,809 @@ +// +// Copyright 2008,2009 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 <usrp/db_wbxng.h> +#include <db_base_impl.h> +#include <cmath> +#include <boost/thread.hpp> +#include <boost/weak_ptr.hpp> +#include <cstdio> + +#if 0 +#define LO_OFFSET 4.25e6 +#else +#define LO_OFFSET 0 +#define NO_LO_OFFSET +#endif + + +/* ------------------------------------------------------------------------ + * **** TODO **** + * Fix the comment below to reflect WBX NG + */ + +/* ------------------------------------------------------------------------ + * A few comments about the XCVR2450: + * + * It is half-duplex. I.e., transmit and receive are mutually exclusive. + * There is a single LO for both the Tx and Rx sides. + * For our purposes the board is always either receiving or transmitting. + * + * Each board is uniquely identified by the *USRP hardware* instance and side + * This dictionary holds a weak reference to existing board controller so it + * can be created or retrieved as needed. + */ + + + +// TX IO Pins +#define HB_PA_OFF (1 << 15) // 5GHz PA, 1 = off, 0 = on +#define LB_PA_OFF (1 << 14) // 2.4GHz PA, 1 = off, 0 = on +#define ANTSEL_TX1_RX2 (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX +#define ANTSEL_TX2_RX1 (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX +#define TX_EN (1 << 11) // 1 = TX on, 0 = TX off +#define AD9515DIV (1 << 4) // 1 = Div by 3, 0 = Div by 2 + +#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV +#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV + +// RX IO Pins +#define LOCKDET (1 << 15) // This is an INPUT!!! +#define EN (1 << 14) +#define RX_EN (1 << 13) // 1 = RX on, 0 = RX off +#define RX_HP (1 << 12) +#define RX_OE_MASK EN|RX_EN|RX_HP +#define RX_SAFE_IO EN + +struct wbxng_key { + std::string serial_no; + int which; + + bool operator==(const wbxng_key &x){ + return x.serial_no ==serial_no && x.which == which; + } +}; + +class wbxng +{ +private: + usrp_basic *d_raw_usrp; + int d_which; + + bool d_is_shutdown; + int d_spi_format, d_spi_enable; + + int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig; + int d_cp_current, d_ref_div, d_rssi_hbw; + int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser; + int d_rssi_range, d_rssi_mode, d_rssi_mux; + int d_rx_hp_pin, d_rx_hpf, d_rx_ant; + int d_tx_ant, d_txvga_ser, d_tx_driver_lin; + int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain; + int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain; + int d_rx_rf_gain, d_rx_bb_gain; + + int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll; + int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain; + int d_reg_pabias, d_reg_rxgain, d_reg_txgain; + + int d_ad9515_div; + + void _set_rfagc(float gain); + void _set_ifagc(float gain); + void _set_pga(float pga_gain); + +public: + usrp_basic *usrp(){ + return d_raw_usrp; + } + + wbxng(usrp_basic_sptr usrp, int which); + ~wbxng(); + void shutdown(); + + void set_reg_standby(); + + // Integer-Divider Ratio (3) + void set_reg_int_divider(); + + // Fractional-Divider Ratio (4) + void set_reg_frac_divider(); + + // Band Select and PLL (5) + void set_reg_bandselpll(); + + // Calibration (6) + void set_reg_cal(); + + // Lowpass Filter (7) + void set_reg_lpf(); + + // Rx Control/RSSI (8) + void set_reg_rxrssi_ctrl(); + + // Tx Linearity/Baseband Gain (9) + void set_reg_txlin_gain(); + + // PA Bias DAC (10) + void set_reg_pabias(); + + // Rx Gain (11) + void set_reg_rxgain(); + + // Tx Gain (12) + void set_reg_txgain(); + + // Send register write to SPI + void send_reg(int v); + + void set_gpio(); + bool lock_detect(); + bool set_rx_gain(float gain); + bool set_tx_gain(float gain); + + struct freq_result_t set_freq(double target_freq); +}; + + +/*****************************************************************************/ + + +wbxng::wbxng(usrp_basic_sptr _usrp, int which) + : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false) +{ + // Handler for WBX NG daughterboards. + // + // @param usrp: instance of usrp.source_c + // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively + + // Use MSB with no header + d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; + + if(which == 0) { + d_spi_enable = SPI_ENABLE_RX_A; + } + else { + d_spi_enable = SPI_ENABLE_RX_B; + } + + // Sane defaults + d_mimo = 1; // 0 = OFF, 1 = ON + d_int_div = 192; // 128 = min, 255 = max + d_frac_div = 0; // 0 = min, 65535 = max + d_highband = 0; // 0 = freq <= 5.4e9, 1 = freq > 5.4e9 + d_five_gig = 0; // 0 = freq <= 3.e9, 1 = freq > 3e9 + d_cp_current = 1; // 0 = 2mA, 1 = 4mA + d_ref_div = 1; // 1 to 7 + d_rssi_hbw = 0; // 0 = 2 MHz, 1 = 6 MHz + d_txlpf_bw = 1; // 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz + d_rxlpf_bw = 1; // 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz + d_rxlpf_fine = 2; // 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110% + d_rxvga_ser = 1; // 0 = RXVGA controlled by B7:1, 1=controlled serially + d_rssi_range = 1; // 0 = low range (datasheet typo), 1=high range (0.5V - 2.0V) + d_rssi_mode = 1; // 0 = enable follows RXHP, 1 = enabled + d_rssi_mux = 0; // 0 = RSSI, 1 = TEMP + d_rx_hp_pin = 0; // 0 = Fc set by rx_hpf, 1 = 600 KHz + d_rx_hpf = 0; // 0 = 100Hz, 1 = 30KHz + d_rx_ant = 0; // 0 = Ant. #1, 1 = Ant. #2 + d_tx_ant = 0; // 0 = Ant. #1, 1 = Ant. #2 + d_txvga_ser = 1; // 0 = TXVGA controlled by B6:1, 1=controlled serially + d_tx_driver_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin) + d_tx_vga_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin) + d_tx_upconv_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin) + d_tx_bb_gain = 3; // 0=maxgain-5dB, 1=max-3dB, 2=max-1.5dB, 3=max + d_pabias_delay = 15; // 0 = 0, 15 = 7uS + d_pabias = 0; // 0 = 0 uA, 63 = 315uA + d_rx_rf_gain = 0; // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB + d_rx_bb_gain = 16; // 0 = min, 31 = max (0 - 62 dB) + + d_txgain = 63; // 0 = min, 63 = max + + /* + // Initialize GPIO and ATR + usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK); + usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff); + usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO); + usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO); + usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK); + + usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK); + usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff); + usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO); + usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO); + usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK); + + // Initialize chipset + // TODO: perform reset sequence to ensure power up defaults + set_reg_standby(); + set_reg_bandselpll(); + set_reg_cal(); + set_reg_lpf(); + set_reg_rxrssi_ctrl(); + set_reg_txlin_gain(); + set_reg_pabias(); + set_reg_rxgain(); + set_reg_txgain(); + //FIXME: set_freq(2.45e9); + */ +} + +wbxng::~wbxng() +{ + //printf("wbxng::destructor\n"); + shutdown(); +} + +void +wbxng::shutdown() +{ + if (!d_is_shutdown){ + d_is_shutdown = true; + /* + usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO); + usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO); + usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO); + usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO); + */ + } +} + + +void +wbxng::set_reg_standby() +{ + d_reg_standby = ((d_mimo<<17) | + (1<<16) | + (1<<6) | + (1<<5) | + (1<<4) | 2); + //send_reg(d_reg_standby); +} + +void +wbxng::set_reg_int_divider() +{ + d_reg_int_divider = (((d_frac_div & 0x03)<<16) | + (d_int_div<<4) | 3); + //send_reg(d_reg_int_divider); +} + +void +wbxng::set_reg_frac_divider() +{ + d_reg_frac_divider = ((d_frac_div & 0xfffc)<<2) | 4; + //send_reg(d_reg_frac_divider); +} + +void +wbxng::set_reg_bandselpll() +{ + d_reg_bandselpll = ((d_mimo<<17) | + (1<<16) | + (1<<15) | + (0<<11) | + (d_highband<<10) | + (d_cp_current<<9) | + (d_ref_div<<5) | + (d_five_gig<<4) | 5); + //send_reg(d_reg_bandselpll); + d_reg_bandselpll = ((d_mimo<<17) | + (1<<16) | + (1<<15) | + (1<<11) | + (d_highband<<10) | + (d_cp_current<<9) | + (d_ref_div<<5) | + (d_five_gig<<4) | 5); + //send_reg(d_reg_bandselpll); +} + +void +wbxng::set_reg_cal() +{ + // FIXME do calibration + d_reg_cal = (1<<14)|6; + //send_reg(d_reg_cal); +} + +void +wbxng::set_reg_lpf() +{ + d_reg_lpf = ( + (d_rssi_hbw<<15) | + (d_txlpf_bw<<10) | + (d_rxlpf_bw<<9) | + (d_rxlpf_fine<<4) | 7); + //send_reg(d_reg_lpf); +} + +void +wbxng::set_reg_rxrssi_ctrl() +{ + d_reg_rxrssi_ctrl = ((d_rxvga_ser<<16) | + (d_rssi_range<<15) | + (d_rssi_mode<<14) | + (d_rssi_mux<<12) | + (1<<9) | + (d_rx_hpf<<6) | + (1<<4) | 8); + //send_reg(d_reg_rxrssi_ctrl); +} + +void +wbxng::set_reg_txlin_gain() +{ + d_reg_txlin_gain = ((d_txvga_ser<<14) | + (d_tx_driver_lin<<12) | + (d_tx_vga_lin<<10) | + (d_tx_upconv_lin<<6) | + (d_tx_bb_gain<<4) | 9); + //send_reg(d_reg_txlin_gain); +} + +void +wbxng::set_reg_pabias() +{ + d_reg_pabias = ( + (d_pabias_delay<<10) | + (d_pabias<<4) | 10); + //send_reg(d_reg_pabias); +} + +void +wbxng::set_reg_rxgain() +{ + d_reg_rxgain = ( + (d_rx_rf_gain<<9) | + (d_rx_bb_gain<<4) | 11); + //send_reg(d_reg_rxgain); +} + +void +wbxng::set_reg_txgain() +{ + d_reg_txgain = (d_txgain<<4) | 12; + //send_reg(d_reg_txgain); +} + +void +wbxng::send_reg(int v) +{ + // Send 24 bits, it keeps last 18 clocked in + char c[3]; + c[0] = (char)((v >> 16) & 0xff); + c[1] = (char)((v >> 8) & 0xff); + c[2] = (char)((v & 0xff)); + std::string s(c, 3); + + //usrp()->_write_spi(0, d_spi_enable, d_spi_format, s); + //printf("wbxng: Setting reg %d to %X\n", (v&15), v); +} + +// ---------------------------------------------------------------- + +void +wbxng::set_gpio() +{ + // We calculate four values: + // + // io_rx_while_rx: what to drive onto io_rx_* when receiving + // io_rx_while_tx: what to drive onto io_rx_* when transmitting + // io_tx_while_rx: what to drive onto io_tx_* when receiving + // io_tx_while_tx: what to drive onto io_tx_* when transmitting + // + // B1-B7 is ignored as gain is set serially for now. + + int rx_hp, tx_antsel, rx_antsel, tx_pa_sel; + if(d_rx_hp_pin) + rx_hp = RX_HP; + else + rx_hp = 0; + + if(d_tx_ant) + tx_antsel = ANTSEL_TX2_RX1; + else + tx_antsel = ANTSEL_TX1_RX2; + + if(d_rx_ant) + rx_antsel = ANTSEL_TX2_RX1; + else + rx_antsel = ANTSEL_TX1_RX2; + + if(d_five_gig) + tx_pa_sel = LB_PA_OFF; + else + tx_pa_sel = HB_PA_OFF; + + /* + // Reset GPIO and ATR + // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings + usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK); + usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff); + usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV); + usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV); + usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK); + + usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK); + usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff); + usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp); + usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN); + usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK); + */ + + //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n", + // io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx); +} + + +struct freq_result_t +wbxng::set_freq(double target_freq) +{ + struct freq_result_t args = {false, 0}; + + double scaler; + + if(target_freq > 3e9) { + d_five_gig = 1; + d_ad9515_div = 3; + scaler = 4.0/5.0; + } + else { + d_five_gig = 0; + d_ad9515_div = 3; + scaler = 4.0/3.0; + } + + if(target_freq > 5.408e9) { + d_highband = 1; + } + else { + d_highband = 0; + } + + double vco_freq = target_freq*scaler; + double sys_clk = usrp()->fpga_master_clock_freq(); // Usually 64e6 + double ref_clk = sys_clk / d_ad9515_div; + + double phdet_freq = ref_clk/d_ref_div; + double div = vco_freq/phdet_freq; + d_int_div = int(floor(div)); + d_frac_div = int((div-d_int_div)*65536.0); + // double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler; + + //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f\n", + // target_freq, vco_freq, d_ref_div, phdet_freq, + // div, d_int_div, d_frac_div, actual_freq); + + args.ok = lock_detect(); + + /* + set_gpio(); + set_reg_int_divider(); + set_reg_frac_divider(); + set_reg_bandselpll(); + + args.ok = lock_detect(); +#ifdef NO_LO_OFFSET + args.baseband_freq = target_freq; +#else + args.baseband_freq = actual_freq; +#endif + */ + + if(!args.ok){ + printf("Fail %f\n", target_freq); + } + return args; +} + +bool +wbxng::lock_detect() +{ + /* + @returns: the value of the VCO/PLL lock detect bit. + @rtype: 0 or 1 + */ + /* + if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) { + return true; + } + else { // Give it a second chance + if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) + return true; + else + return false; + } + */ + return true; +} + +bool +wbxng::set_rx_gain(float gain) +{ + if(gain < 0.0) + gain = 0.0; + if(gain > 92.0) + gain = 92.0; + + // Split the gain between RF and baseband + // This is experimental, not prescribed + if(gain < 31.0) { + d_rx_rf_gain = 0; // 0 dB RF gain + rx_bb_gain = int(gain/2.0); + } + + if(gain >= 30.0 and gain < 60.5) { + d_rx_rf_gain = 2; // 15 dB RF gain + d_rx_bb_gain = int((gain-15.0)/2.0); + } + + if(gain >= 60.5) { + d_rx_rf_gain = 3; // 30.5 dB RF gain + d_rx_bb_gain = int((gain-30.5)/2.0); + } + + //set_reg_rxgain(); + + return true; +} + +bool +wbxng::set_tx_gain(float gain) +{ + if(gain < 0.0) { + gain = 0.0; + } + if(gain > 30.0) { + gain = 30.0; + } + + d_txgain = int((gain/30.0)*63); + //set_reg_txgain(); + + return true; +} + + +/*****************************************************************************/ + + +struct wbxng_table_entry { + wbxng_key key; + boost::weak_ptr<wbxng> value; + + wbxng_table_entry(const wbxng_key &_key, boost::weak_ptr<wbxng> _value) + : key(_key), value(_value) {} +}; + +typedef std::vector<wbxng_table_entry> wbxng_table; + +static boost::mutex s_table_mutex; +static wbxng_table s_table; + +static wbxng_sptr +_get_or_make_wbxng(usrp_basic_sptr usrp, int which) +{ + wbxng_key key = {usrp->serial_number(), which}; + + boost::mutex::scoped_lock guard(s_table_mutex); + + for (wbxng_table::iterator p = s_table.begin(); p != s_table.end();){ + if (p->value.expired()) // weak pointer is now dead + p = s_table.erase(p); // erase it + else { + if (key == p->key){ // found it + return wbxng_sptr(p->value); + } + else + ++p; // keep looking + } + } + + // We don't have the wbxng we're looking for + + // create a new one and stick it in the table. + wbxng_sptr r(new wbxng(usrp, which)); + wbxng_table_entry t(key, r); + s_table.push_back(t); + + return r; +} + + +/*****************************************************************************/ + + +db_wbxng_base::db_wbxng_base(usrp_basic_sptr usrp, int which) + : db_base(usrp, which) +{ + /* + * Abstract base class for all wbxng boards. + * + * Derive board specific subclasses from db_wbxng_base_{tx,rx} + * + * @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_wbxng = _get_or_make_wbxng(usrp, which); +} + +db_wbxng_base::~db_wbxng_base() +{ +} + +void +db_wbxng_base::shutdown_common() +{ + // If the usrp_basic in the wbxng is the same as the usrp_basic + // in the daughterboard, shutdown the wbxng now (when only one of Tx + // and Rx is open, this is always true). + + if (d_wbxng->usrp() == usrp()){ + //std::cerr << "db_wbxng_base::shutdown_common: same -> shutting down\n"; + d_wbxng->shutdown(); + } + else { + //std::cerr << "db_wbxng_base::shutdown_common: different -> ignoring\n"; + } +} + +struct freq_result_t +db_wbxng_base::set_freq(double target_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. + */ + return d_wbxng->set_freq(target_freq+d_lo_offset); +} + +bool +db_wbxng_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 +db_wbxng_base::freq_min() +{ + return 2.4e9; +} + +double +db_wbxng_base::freq_max() +{ + return 6.0e9; +} + + +/******************************************************************************/ + + +db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which) + : db_wbxng_base(usrp, which) +{ + set_lo_offset(LO_OFFSET); + //printf("db_wbxng_tx::db_wbxng_tx\n"); +} + +db_wbxng_tx::~db_wbxng_tx() +{ + shutdown(); +} + +void +db_wbxng_tx::shutdown() +{ + if (!d_is_shutdown){ + d_is_shutdown = true; + shutdown_common(); + } +} + +float +db_wbxng_tx::gain_min() +{ + return 0; +} + +float +db_wbxng_tx::gain_max() +{ + return 30; +} + +float +db_wbxng_tx::gain_db_per_step() +{ + return (30.0/63.0); +} + +bool +db_wbxng_tx::set_gain(float gain) +{ + return d_wbxng->set_tx_gain(gain); +} + +bool +db_wbxng_tx::i_and_q_swapped() +{ + return true; +} + + +/******************************************************************************/ + + +db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which) + : db_wbxng_base(usrp, which) +{ + /* + * @param usrp: instance of usrp.source_c + * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively. + */ + set_lo_offset(LO_OFFSET); + //printf("db_wbxng_rx:d_wbxng_rx\n"); +} + +db_wbxng_rx::~db_wbxng_rx() +{ + shutdown(); +} + +void +db_wbxng_rx::shutdown() +{ + if (!d_is_shutdown){ + d_is_shutdown = true; + shutdown_common(); + } +} + +float +db_wbxng_rx::gain_min() +{ + return 0.0; +} + +float +db_wbxng_rx::gain_max() +{ + return 92.0; +} + +float +db_wbxng_rx::gain_db_per_step() +{ + return 1; +} + +bool +db_wbxng_rx::set_gain(float gain) +{ + return d_wbxng->set_rx_gain(gain); +} diff --git a/usrp/host/lib/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat index 6bad9a298..1df28802e 100644 --- a/usrp/host/lib/usrp_dbid.dat +++ b/usrp/host/lib/usrp_dbid.dat @@ -78,6 +78,9 @@ "WBX LO TX" 0x0050 "WBX LO RX" 0x0051 +"WBX NG TX" 0x0052 +"WBX NG RX" 0x0053 + "XCVR2450 Tx" 0x0060 "XCVR2450 Rx" 0x0061 -- cgit From ba4f8351cc3b74895f3f0a880ad25f51652cd94b Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Fri, 21 Aug 2009 10:08:44 -0700 Subject: Clean build --- usrp/host/include/usrp/Makefile.am | 2 + usrp/host/include/usrp/db_wbxng.h | 108 ++- usrp/host/include/usrp/db_wbxng_adf4350.h | 37 + usrp/host/include/usrp/db_wbxng_adf4350_regs.h | 65 ++ usrp/host/lib/Makefile.am | 2 + usrp/host/lib/db_wbxng.cc | 1061 ++++++++++-------------- usrp/host/lib/db_wbxng_adf4350.cc | 156 ++++ usrp/host/lib/db_wbxng_adf4350_regs.cc | 106 +++ 8 files changed, 888 insertions(+), 649 deletions(-) create mode 100644 usrp/host/include/usrp/db_wbxng_adf4350.h create mode 100644 usrp/host/include/usrp/db_wbxng_adf4350_regs.h create mode 100644 usrp/host/lib/db_wbxng_adf4350.cc create mode 100644 usrp/host/lib/db_wbxng_adf4350_regs.cc (limited to 'usrp') diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am index 83e86da7e..7c868e061 100644 --- a/usrp/host/include/usrp/Makefile.am +++ b/usrp/host/include/usrp/Makefile.am @@ -33,6 +33,8 @@ usrpinclude_HEADERS = \ db_flexrf_mimo.h \ db_tv_rx.h \ db_tv_rx_mimo.h \ + db_wbxng_adf4350.h \ + db_wbxng_adf4350_regs.h \ db_wbxng.h \ db_xcvr2450.h \ libusb_types.h \ diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h index b255cf91c..1ded1b5dc 100644 --- a/usrp/host/include/usrp/db_wbxng.h +++ b/usrp/host/include/usrp/db_wbxng.h @@ -23,70 +23,118 @@ #define DB_WBXNG_H #include <usrp/db_base.h> -#include <boost/shared_ptr.hpp> +#include <cmath> -class wbxng; -typedef boost::shared_ptr<wbxng> wbxng_sptr; +//debug_using_gui = true // Must be set to True or False +#define debug_using_gui false // Must be set to True or False +class adf4350; -/******************************************************************************/ - - -class db_wbxng_base: public db_base +class wbxng_base : public db_base { - /* - * Abstract base class for all wbxng boards. - * - * Derive board specific subclasses from db_wbxng_base_{tx,rx} - */ public: - db_wbxng_base(usrp_basic_sptr usrp, int which); - ~db_wbxng_base(); - struct freq_result_t set_freq(double target_freq); - bool is_quadrature(); + wbxng_base(usrp_basic_sptr usrp, int which, int _power_on=0); + ~wbxng_base(); + + struct freq_result_t set_freq(double freq); + + bool is_quadrature(); double freq_min(); double freq_max(); protected: - wbxng_sptr d_wbxng; - void shutdown_common(); + void _write_all(int R, int control, int N); + void _write_control(int control); + void _write_R(int R); + void _write_N(int N); + void _write_it(int v); + bool _lock_detect(); + + virtual bool _compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq); + int _compute_control_reg(); + int _refclk_divisor(); + double _refclk_freq(); + + bool _set_pga(float pga_gain); + + int power_on() { return d_power_on; } + int power_off() { return 0; } + + bool d_first; + int d_spi_format; + int d_spi_enable; + int d_power_on; + int d_PD; + + adf4350 *d_common; }; +// ---------------------------------------------------------------- -/******************************************************************************/ - - -class db_wbxng_tx : public db_wbxng_base +class wbxng_base_tx : public wbxng_base { protected: void shutdown(); public: - db_wbxng_tx(usrp_basic_sptr usrp, int which); - ~db_wbxng_tx(); + wbxng_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0); + ~wbxng_base_tx(); + //*** TODO *** Fix comment + // All RFX tx d'boards have fixed gain float gain_min(); float gain_max(); float gain_db_per_step(); - bool set_gain(float gain); - bool i_and_q_swapped(); + + bool set_auto_tr(bool on); + bool set_enable(bool on); + bool set_gain(float gain); }; -class db_wbxng_rx : public db_wbxng_base +class wbxng_base_rx : public wbxng_base { protected: void shutdown(); +public: + wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0); + ~wbxng_base_rx(); + + bool set_auto_tr(bool on); + bool select_rx_antenna(int which_antenna); + bool select_rx_antenna(const std::string &which_antenna); + bool set_gain(float gain); + +}; + +// ---------------------------------------------------------------- + +class db_wbxng_tx : public wbxng_base_tx +{ + public: + db_wbxng_tx(usrp_basic_sptr usrp, int which); + ~db_wbxng_tx(); + + // Wrapper calls to d_common functions + bool _compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq); +}; + +class db_wbxng_rx : public wbxng_base_rx +{ public: db_wbxng_rx(usrp_basic_sptr usrp, int which); ~db_wbxng_rx(); - + float gain_min(); float gain_max(); float gain_db_per_step(); - bool set_gain(float gain); -}; + bool i_and_q_swapped(); + bool _compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq); +}; #endif diff --git a/usrp/host/include/usrp/db_wbxng_adf4350.h b/usrp/host/include/usrp/db_wbxng_adf4350.h new file mode 100644 index 000000000..a5ebe646e --- /dev/null +++ b/usrp/host/include/usrp/db_wbxng_adf4350.h @@ -0,0 +1,37 @@ +/* + * Copyright 2009 Ettus Research LLC + */ + +#ifndef ADF4350_H +#define ADF4350_H + +#include <usrp/db_wbxng_adf4350_regs.h> +#include <usrp/db_base.h> +#include <stdint.h> + +typedef uint32_t freq_t; +class adf4350_regs; + +class adf4350 +{ +public: + adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable); + ~adf4350(); + void _update(); + bool _get_locked(); + void _enable(bool enable); + void _write(uint8_t addr, uint32_t data); + bool _set_freq(freq_t freq); + freq_t _get_freq(); + freq_t _get_max_freq(); + freq_t _get_min_freq(); + +protected: + usrp_basic_sptr d_usrp; + int d_which; + int d_spi_enable; + int d_spi_format; + adf4350_regs *d_regs; +}; + +#endif /* ADF4350_H */ diff --git a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h new file mode 100644 index 000000000..ec78a9fa5 --- /dev/null +++ b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h @@ -0,0 +1,65 @@ +/* + * Copyright 2009 Ettus Research LLC + */ + +#ifndef ADF4350_REGS_H +#define ADF4350_REGS_H + +#include <usrp/db_wbxng_adf4350.h> +#include <usrp/db_base.h> +#include <stdint.h> + +class adf4350; + +class adf4350_regs +{ +public: + adf4350_regs(adf4350* _adf4350); + ~adf4350_regs(); + + adf4350* d_adf4350; + + uint32_t _reg_shift(uint32_t data, uint32_t shift); + void _load_register(uint8_t addr); + + /* reg 0 */ + uint16_t _int; + uint16_t _frac; + /* reg 1 */ + static uint8_t _prescaler; + static uint16_t _phase; + uint16_t _mod; + /* reg 2 */ + static uint8_t _low_noise_and_low_spur_modes; + static uint8_t _muxout; + static uint8_t _reference_doubler; + static uint8_t _rdiv2; + uint16_t _10_bit_r_counter; + static uint8_t _double_buff; + static uint8_t _charge_pump_setting; + static uint8_t _ldf; + static uint8_t _ldp; + static uint8_t _pd_polarity; + static uint8_t _power_down; + static uint8_t _cp_three_state; + static uint8_t _counter_reset; + /* reg 3 */ + static uint8_t _csr; + static uint8_t _clk_div_mode; + static uint16_t _12_bit_clock_divider_value; + /* reg 4 */ + static uint8_t _feedback_select; + uint8_t _divider_select; + uint8_t _8_bit_band_select_clock_divider_value; + static uint8_t _vco_power_down; + static uint8_t _mtld; + static uint8_t _aux_output_select; + static uint8_t _aux_output_enable; + static uint8_t _aux_output_power; + static uint8_t _rf_output_enable; + static uint8_t _output_power; + /* reg 5 */ + static uint8_t _ld_pin_mode; +}; + +#endif /* ADF4350_REGS_H */ diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am index 4b889993b..13f25d69b 100644 --- a/usrp/host/lib/Makefile.am +++ b/usrp/host/lib/Makefile.am @@ -122,6 +122,8 @@ libusrp_la_common_SOURCES = \ usrp_local_sighandler.cc \ usrp_prims_common.cc \ usrp_standard.cc \ + db_wbxng_adf4350.cc \ + db_wbxng_adf4350_regs.cc \ db_boards.cc \ db_base.cc \ db_basic.cc \ diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index 53ec27afc..e911c9d03 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -1,5 +1,5 @@ // -// Copyright 2008,2009 Free Software Foundation, Inc. +// Copyright 2008 Free Software Foundation, Inc. // // This file is part of GNU Radio // @@ -19,791 +19,614 @@ // Boston, MA 02110-1301, USA. #include <usrp/db_wbxng.h> +#include <usrp/db_wbxng_adf4350.h> #include <db_base_impl.h> -#include <cmath> -#include <boost/thread.hpp> -#include <boost/weak_ptr.hpp> -#include <cstdio> - -#if 0 -#define LO_OFFSET 4.25e6 -#else -#define LO_OFFSET 0 -#define NO_LO_OFFSET -#endif - - -/* ------------------------------------------------------------------------ - * **** TODO **** - * Fix the comment below to reflect WBX NG - */ - -/* ------------------------------------------------------------------------ - * A few comments about the XCVR2450: - * - * It is half-duplex. I.e., transmit and receive are mutually exclusive. - * There is a single LO for both the Tx and Rx sides. - * For our purposes the board is always either receiving or transmitting. - * - * Each board is uniquely identified by the *USRP hardware* instance and side - * This dictionary holds a weak reference to existing board controller so it - * can be created or retrieved as needed. - */ - - - -// TX IO Pins -#define HB_PA_OFF (1 << 15) // 5GHz PA, 1 = off, 0 = on -#define LB_PA_OFF (1 << 14) // 2.4GHz PA, 1 = off, 0 = on -#define ANTSEL_TX1_RX2 (1 << 13) // 1 = Ant 1 to TX, Ant 2 to RX -#define ANTSEL_TX2_RX1 (1 << 12) // 1 = Ant 2 to TX, Ant 1 to RX -#define TX_EN (1 << 11) // 1 = TX on, 0 = TX off -#define AD9515DIV (1 << 4) // 1 = Div by 3, 0 = Div by 2 - -#define TX_OE_MASK HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|ANTSEL_TX2_RX1|TX_EN|AD9515DIV -#define TX_SAFE_IO HB_PA_OFF|LB_PA_OFF|ANTSEL_TX1_RX2|AD9515DIV - -// RX IO Pins -#define LOCKDET (1 << 15) // This is an INPUT!!! -#define EN (1 << 14) -#define RX_EN (1 << 13) // 1 = RX on, 0 = RX off -#define RX_HP (1 << 12) -#define RX_OE_MASK EN|RX_EN|RX_HP -#define RX_SAFE_IO EN - -struct wbxng_key { - std::string serial_no; - int which; - - bool operator==(const wbxng_key &x){ - return x.serial_no ==serial_no && x.which == which; - } -}; - -class wbxng -{ -private: - usrp_basic *d_raw_usrp; - int d_which; - - bool d_is_shutdown; - int d_spi_format, d_spi_enable; - - int d_mimo, d_int_div, d_frac_div, d_highband, d_five_gig; - int d_cp_current, d_ref_div, d_rssi_hbw; - int d_txlpf_bw, d_rxlpf_bw, d_rxlpf_fine, d_rxvga_ser; - int d_rssi_range, d_rssi_mode, d_rssi_mux; - int d_rx_hp_pin, d_rx_hpf, d_rx_ant; - int d_tx_ant, d_txvga_ser, d_tx_driver_lin; - int d_tx_vga_lin, d_tx_upconv_lin, d_tx_bb_gain; - int d_pabias_delay, d_pabias, rx_rf_gain, rx_bb_gain, d_txgain; - int d_rx_rf_gain, d_rx_bb_gain; - - int d_reg_standby, d_reg_int_divider, d_reg_frac_divider, d_reg_bandselpll; - int d_reg_cal, dsend_reg, d_reg_lpf, d_reg_rxrssi_ctrl, d_reg_txlin_gain; - int d_reg_pabias, d_reg_rxgain, d_reg_txgain; - - int d_ad9515_div; - - void _set_rfagc(float gain); - void _set_ifagc(float gain); - void _set_pga(float pga_gain); - -public: - usrp_basic *usrp(){ - return d_raw_usrp; - } - - wbxng(usrp_basic_sptr usrp, int which); - ~wbxng(); - void shutdown(); - - void set_reg_standby(); - - // Integer-Divider Ratio (3) - void set_reg_int_divider(); - - // Fractional-Divider Ratio (4) - void set_reg_frac_divider(); - - // Band Select and PLL (5) - void set_reg_bandselpll(); - - // Calibration (6) - void set_reg_cal(); - - // Lowpass Filter (7) - void set_reg_lpf(); - - // Rx Control/RSSI (8) - void set_reg_rxrssi_ctrl(); - - // Tx Linearity/Baseband Gain (9) - void set_reg_txlin_gain(); - - // PA Bias DAC (10) - void set_reg_pabias(); - - // Rx Gain (11) - void set_reg_rxgain(); - - // Tx Gain (12) - void set_reg_txgain(); - - // Send register write to SPI - void send_reg(int v); - - void set_gpio(); - bool lock_detect(); - bool set_rx_gain(float gain); - bool set_tx_gain(float gain); - - struct freq_result_t set_freq(double target_freq); -}; - - -/*****************************************************************************/ - -wbxng::wbxng(usrp_basic_sptr _usrp, int which) - : d_raw_usrp(_usrp.get()), d_which(which), d_is_shutdown(false) +// d'board i/o pin defs +// Tx and Rx have shared defs, but different i/o regs +#define ENABLE_5 (1 << 7) // enables 5.0V power supply +#define ENABLE_33 (1 << 6) // enables 3.3V supply +#define RX_TXN (1 << 5) // Tx only: T/R antenna switch for TX/RX port +#define RX2_RX1N (1 << 5) // Rx only: antenna switch between RX2 and TX/RX port +#define BBAMP_EN (1 << 4) +#define PLL_CE (1 << 3) +#define PLL_PDBRF (1 << 2) +#define PLL_MUXOUT (1 << 1) +#define PLL_LOCK_DETECT (1 << 0) + +wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on) + : db_base(_usrp, which), d_power_on(_power_on) { - // Handler for WBX NG daughterboards. - // - // @param usrp: instance of usrp.source_c - // @param which: which side: 0, 1 corresponding to RX_A or RX_B respectively + /* + @param usrp: instance of usrp.source_c + @param which: which side: 0 or 1 corresponding to side A or B respectively + @type which: int + */ - // Use MSB with no header + d_first = true; d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; - if(which == 0) { - d_spi_enable = SPI_ENABLE_RX_A; - } - else { - d_spi_enable = SPI_ENABLE_RX_B; - } - - // Sane defaults - d_mimo = 1; // 0 = OFF, 1 = ON - d_int_div = 192; // 128 = min, 255 = max - d_frac_div = 0; // 0 = min, 65535 = max - d_highband = 0; // 0 = freq <= 5.4e9, 1 = freq > 5.4e9 - d_five_gig = 0; // 0 = freq <= 3.e9, 1 = freq > 3e9 - d_cp_current = 1; // 0 = 2mA, 1 = 4mA - d_ref_div = 1; // 1 to 7 - d_rssi_hbw = 0; // 0 = 2 MHz, 1 = 6 MHz - d_txlpf_bw = 1; // 1 = 12 MHz, 2 = 18 MHz, 3 = 24 MHz - d_rxlpf_bw = 1; // 0 = 7.5 MHz, 1 = 9.5 MHz, 2 = 14 MHz, 3 = 18 MHz - d_rxlpf_fine = 2; // 0 = 90%, 1 = 95%, 2 = 100%, 3 = 105%, 4 = 110% - d_rxvga_ser = 1; // 0 = RXVGA controlled by B7:1, 1=controlled serially - d_rssi_range = 1; // 0 = low range (datasheet typo), 1=high range (0.5V - 2.0V) - d_rssi_mode = 1; // 0 = enable follows RXHP, 1 = enabled - d_rssi_mux = 0; // 0 = RSSI, 1 = TEMP - d_rx_hp_pin = 0; // 0 = Fc set by rx_hpf, 1 = 600 KHz - d_rx_hpf = 0; // 0 = 100Hz, 1 = 30KHz - d_rx_ant = 0; // 0 = Ant. #1, 1 = Ant. #2 - d_tx_ant = 0; // 0 = Ant. #1, 1 = Ant. #2 - d_txvga_ser = 1; // 0 = TXVGA controlled by B6:1, 1=controlled serially - d_tx_driver_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin) - d_tx_vga_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin) - d_tx_upconv_lin = 2; // 0=50% (worst linearity), 1=63%, 2=78%, 3=100% (best lin) - d_tx_bb_gain = 3; // 0=maxgain-5dB, 1=max-3dB, 2=max-1.5dB, 3=max - d_pabias_delay = 15; // 0 = 0, 15 = 7uS - d_pabias = 0; // 0 = 0 uA, 63 = 315uA - d_rx_rf_gain = 0; // 0 = 0dB, 1 = 0dB, 2 = 15dB, 3 = 30dB - d_rx_bb_gain = 16; // 0 = min, 31 = max (0 - 62 dB) - - d_txgain = 63; // 0 = min, 63 = max + usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs + _enable_refclk(false); // disable refclk - /* - // Initialize GPIO and ATR - usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK); - usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff); - usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO); - usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO); - usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK); - - usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK); - usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff); - usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO); - usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO); - usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK); - - // Initialize chipset - // TODO: perform reset sequence to ensure power up defaults - set_reg_standby(); - set_reg_bandselpll(); - set_reg_cal(); - set_reg_lpf(); - set_reg_rxrssi_ctrl(); - set_reg_txlin_gain(); - set_reg_pabias(); - set_reg_rxgain(); - set_reg_txgain(); - //FIXME: set_freq(2.45e9); - */ + set_auto_tr(false); } -wbxng::~wbxng() +wbxng_base::~wbxng_base() { - //printf("wbxng::destructor\n"); - shutdown(); + delete d_common; } void -wbxng::shutdown() +wbxng_base::_write_all(int R, int control, int N) { - if (!d_is_shutdown){ - d_is_shutdown = true; - /* - usrp()->common_write_atr_txval(C_TX, d_which, TX_SAFE_IO); - usrp()->common_write_atr_rxval(C_TX, d_which, TX_SAFE_IO); - usrp()->common_write_atr_txval(C_RX, d_which, RX_SAFE_IO); - usrp()->common_write_atr_rxval(C_RX, d_which, RX_SAFE_IO); - */ + /* + 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 -wbxng::set_reg_standby() +wbxng_base::_write_control(int control) { - d_reg_standby = ((d_mimo<<17) | - (1<<16) | - (1<<6) | - (1<<5) | - (1<<4) | 2); - //send_reg(d_reg_standby); + //_write_it((control & ~0x3) | 0); } void -wbxng::set_reg_int_divider() +wbxng_base::_write_R(int R) { - d_reg_int_divider = (((d_frac_div & 0x03)<<16) | - (d_int_div<<4) | 3); - //send_reg(d_reg_int_divider); + //_write_it((R & ~0x3) | 1); } void -wbxng::set_reg_frac_divider() -{ - d_reg_frac_divider = ((d_frac_div & 0xfffc)<<2) | 4; - //send_reg(d_reg_frac_divider); -} - -void -wbxng::set_reg_bandselpll() -{ - d_reg_bandselpll = ((d_mimo<<17) | - (1<<16) | - (1<<15) | - (0<<11) | - (d_highband<<10) | - (d_cp_current<<9) | - (d_ref_div<<5) | - (d_five_gig<<4) | 5); - //send_reg(d_reg_bandselpll); - d_reg_bandselpll = ((d_mimo<<17) | - (1<<16) | - (1<<15) | - (1<<11) | - (d_highband<<10) | - (d_cp_current<<9) | - (d_ref_div<<5) | - (d_five_gig<<4) | 5); - //send_reg(d_reg_bandselpll); -} - -void -wbxng::set_reg_cal() +wbxng_base::_write_N(int N) { - // FIXME do calibration - d_reg_cal = (1<<14)|6; - //send_reg(d_reg_cal); + //_write_it((N & ~0x3) | 2); } void -wbxng::set_reg_lpf() +wbxng_base::_write_it(int v) { - d_reg_lpf = ( - (d_rssi_hbw<<15) | - (d_txlpf_bw<<10) | - (d_rxlpf_bw<<9) | - (d_rxlpf_fine<<4) | 7); - //send_reg(d_reg_lpf); + 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); } - -void -wbxng::set_reg_rxrssi_ctrl() + +bool +wbxng_base::_lock_detect() { - d_reg_rxrssi_ctrl = ((d_rxvga_ser<<16) | - (d_rssi_range<<15) | - (d_rssi_mode<<14) | - (d_rssi_mux<<12) | - (1<<9) | - (d_rx_hpf<<6) | - (1<<4) | 8); - //send_reg(d_reg_rxrssi_ctrl); + /* + @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; + } + } + */ + throw std::runtime_error("_lock_detect called from wbxng_base\n"); } -void -wbxng::set_reg_txlin_gain() -{ - d_reg_txlin_gain = ((d_txvga_ser<<14) | - (d_tx_driver_lin<<12) | - (d_tx_vga_lin<<10) | - (d_tx_upconv_lin<<6) | - (d_tx_bb_gain<<4) | 9); - //send_reg(d_reg_txlin_gain); +/* +bool +wbxng_base::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) +{ + **COMMENT** + 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. + **COMMENT** + + //raise NotImplementedError; + throw std::runtime_error("_compute_regs called from wbxng_base\n"); } +*/ -void -wbxng::set_reg_pabias() +int +wbxng_base::_compute_control_reg() { - d_reg_pabias = ( - (d_pabias_delay<<10) | - (d_pabias<<4) | 10); - //send_reg(d_reg_pabias); + throw std::runtime_error("_compute_control_reg called from wbxng_base\n"); + //return d_common->_compute_control_reg(); } -void -wbxng::set_reg_rxgain() +int +wbxng_base::_refclk_divisor() { - d_reg_rxgain = ( - (d_rx_rf_gain<<9) | - (d_rx_bb_gain<<4) | 11); - //send_reg(d_reg_rxgain); + throw std::runtime_error("_refclk_divisor called from wbxng_base\n"); + //return d_common->_refclk_divisor(); } -void -wbxng::set_reg_txgain() +double +wbxng_base::_refclk_freq() { - d_reg_txgain = (d_txgain<<4) | 12; - //send_reg(d_reg_txgain); -} - -void -wbxng::send_reg(int v) -{ - // Send 24 bits, it keeps last 18 clocked in - char c[3]; - c[0] = (char)((v >> 16) & 0xff); - c[1] = (char)((v >> 8) & 0xff); - c[2] = (char)((v & 0xff)); - std::string s(c, 3); - - //usrp()->_write_spi(0, d_spi_enable, d_spi_format, s); - //printf("wbxng: Setting reg %d to %X\n", (v&15), v); + throw std::runtime_error("_refclk_divisor called from wbxng_base\n"); + // *** TODO *** Magic Number 64e6? + //return 64e6/_refclk_divisor(); } -// ---------------------------------------------------------------- - -void -wbxng::set_gpio() -{ - // We calculate four values: - // - // io_rx_while_rx: what to drive onto io_rx_* when receiving - // io_rx_while_tx: what to drive onto io_rx_* when transmitting - // io_tx_while_rx: what to drive onto io_tx_* when receiving - // io_tx_while_tx: what to drive onto io_tx_* when transmitting - // - // B1-B7 is ignored as gain is set serially for now. - - int rx_hp, tx_antsel, rx_antsel, tx_pa_sel; - if(d_rx_hp_pin) - rx_hp = RX_HP; - else - rx_hp = 0; - - if(d_tx_ant) - tx_antsel = ANTSEL_TX2_RX1; - else - tx_antsel = ANTSEL_TX1_RX2; - - if(d_rx_ant) - rx_antsel = ANTSEL_TX2_RX1; - else - rx_antsel = ANTSEL_TX1_RX2; - - if(d_five_gig) - tx_pa_sel = LB_PA_OFF; - else - tx_pa_sel = HB_PA_OFF; - +struct freq_result_t +wbxng_base::set_freq(double freq) +{ /* - // Reset GPIO and ATR - // FIXME: dont set io, oe, atr mask once basic code stops overriding our settings - usrp()->common_write_io(C_TX, d_which, TX_SAFE_IO, TX_OE_MASK); - usrp()->_common_write_oe(C_TX, d_which, TX_OE_MASK, 0xffff); - usrp()->common_write_atr_txval(C_TX, d_which, tx_pa_sel|tx_antsel|TX_EN|AD9515DIV); - usrp()->common_write_atr_rxval(C_TX, d_which, HB_PA_OFF|LB_PA_OFF|rx_antsel|AD9515DIV); - usrp()->common_write_atr_mask(C_TX, d_which, TX_OE_MASK); - - usrp()->common_write_io(C_RX, d_which, RX_SAFE_IO, RX_OE_MASK); - usrp()->_common_write_oe(C_RX, d_which, RX_OE_MASK, 0xffff); - usrp()->common_write_atr_txval(C_RX, d_which, EN|rx_hp); - usrp()->common_write_atr_rxval(C_RX, d_which, EN|rx_hp|RX_EN); - usrp()->common_write_atr_mask(C_RX, d_which, RX_OE_MASK); + @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. */ - //printf("GPIO: RXRX=%04X RXTX=%04X TXRX=%04X TXTX=%04X\n", - // io_rx_while_rx, io_rx_while_tx, io_tx_while_rx, io_tx_while_tx); -} - - -struct freq_result_t -wbxng::set_freq(double target_freq) -{ struct freq_result_t args = {false, 0}; - double scaler; - - if(target_freq > 3e9) { - d_five_gig = 1; - d_ad9515_div = 3; - scaler = 4.0/5.0; - } - else { - d_five_gig = 0; - d_ad9515_div = 3; - scaler = 4.0/3.0; - } - - if(target_freq > 5.408e9) { - d_highband = 1; - } - else { - d_highband = 0; - } - - double vco_freq = target_freq*scaler; - double sys_clk = usrp()->fpga_master_clock_freq(); // Usually 64e6 - double ref_clk = sys_clk / d_ad9515_div; - - double phdet_freq = ref_clk/d_ref_div; - double div = vco_freq/phdet_freq; - d_int_div = int(floor(div)); - d_frac_div = int((div-d_int_div)*65536.0); - // double actual_freq = phdet_freq*(d_int_div+(d_frac_div/65536.0))/scaler; + // 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; - //printf("RF=%f VCO=%f R=%d PHD=%f DIV=%3.5f I=%3d F=%5d ACT=%f\n", - // target_freq, vco_freq, d_ref_div, phdet_freq, - // div, d_int_div, d_frac_div, actual_freq); - - args.ok = lock_detect(); - - /* - set_gpio(); - set_reg_int_divider(); - set_reg_frac_divider(); - set_reg_bandselpll(); - - args.ok = lock_detect(); -#ifdef NO_LO_OFFSET - args.baseband_freq = target_freq; -#else - args.baseband_freq = actual_freq; -#endif - */ - - if(!args.ok){ - printf("Fail %f\n", target_freq); - } + //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 -wbxng::lock_detect() +wbxng_base::_set_pga(float pga_gain) { /* - @returns: the value of the VCO/PLL lock detect bit. - @rtype: 0 or 1 - */ - /* - if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) { - return true; + if(d_which == 0) { + usrp()->set_pga(0, pga_gain); + usrp()->set_pga(1, pga_gain); } - else { // Give it a second chance - if(usrp()->common_read_io(C_RX, d_which) & LOCKDET) - return true; - else - return false; + else { + usrp()->set_pga(2, pga_gain); + usrp()->set_pga(3, pga_gain); } */ return true; } bool -wbxng::set_rx_gain(float gain) -{ - if(gain < 0.0) - gain = 0.0; - if(gain > 92.0) - gain = 92.0; - - // Split the gain between RF and baseband - // This is experimental, not prescribed - if(gain < 31.0) { - d_rx_rf_gain = 0; // 0 dB RF gain - rx_bb_gain = int(gain/2.0); - } - - if(gain >= 30.0 and gain < 60.5) { - d_rx_rf_gain = 2; // 15 dB RF gain - d_rx_bb_gain = int((gain-15.0)/2.0); - } - - if(gain >= 60.5) { - d_rx_rf_gain = 3; // 30.5 dB RF gain - d_rx_bb_gain = int((gain-30.5)/2.0); - } - - //set_reg_rxgain(); - +wbxng_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; } -bool -wbxng::set_tx_gain(float gain) +double +wbxng_base::freq_min() { - if(gain < 0.0) { - gain = 0.0; - } - if(gain > 30.0) { - gain = 30.0; - } - - d_txgain = int((gain/30.0)*63); - //set_reg_txgain(); - - return true; + throw std::runtime_error("freq_min called from wbxng_base\n"); + //return d_common->freq_min(); } - -/*****************************************************************************/ - - -struct wbxng_table_entry { - wbxng_key key; - boost::weak_ptr<wbxng> value; - - wbxng_table_entry(const wbxng_key &_key, boost::weak_ptr<wbxng> _value) - : key(_key), value(_value) {} -}; - -typedef std::vector<wbxng_table_entry> wbxng_table; - -static boost::mutex s_table_mutex; -static wbxng_table s_table; - -static wbxng_sptr -_get_or_make_wbxng(usrp_basic_sptr usrp, int which) +double +wbxng_base::freq_max() { - wbxng_key key = {usrp->serial_number(), which}; + throw std::runtime_error("freq_max called from wbxng_base\n"); + //return d_common->freq_max(); +} - boost::mutex::scoped_lock guard(s_table_mutex); +// ---------------------------------------------------------------- - for (wbxng_table::iterator p = s_table.begin(); p != s_table.end();){ - if (p->value.expired()) // weak pointer is now dead - p = s_table.erase(p); // erase it - else { - if (key == p->key){ // found it - return wbxng_sptr(p->value); - } - else - ++p; // keep looking - } +wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) + : wbxng_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; } - // We don't have the wbxng we're looking for + d_common = new adf4350(_usrp, d_which, d_spi_enable); + + // 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); - // create a new one and stick it in the table. - wbxng_sptr r(new wbxng(usrp, which)); - wbxng_table_entry t(key, r); - s_table.push_back(t); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain + */ +} - return r; +wbxng_base_tx::~wbxng_base_tx() +{ + shutdown(); } -/*****************************************************************************/ +void +wbxng_base_tx::shutdown() +{ + // fprintf(stderr, "wbxng_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 -db_wbxng_base::db_wbxng_base(usrp_basic_sptr usrp, int which) - : db_base(usrp, which) -{ - /* - * Abstract base class for all wbxng boards. - * - * Derive board specific subclasses from db_wbxng_base_{tx,rx} - * - * @param usrp: instance of usrp.source_c - * @param which: which side: 0 or 1 corresponding to side A or B respectively - * @type which: int - */ + // 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; - d_wbxng = _get_or_make_wbxng(usrp, which); + _write_control(_compute_control_reg()); + _enable_refclk(false); // turn off refclk + set_auto_tr(false); + } } -db_wbxng_base::~db_wbxng_base() +bool +wbxng_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; } -void -db_wbxng_base::shutdown_common() +bool +wbxng_base_tx::set_enable(bool on) { - // If the usrp_basic in the wbxng is the same as the usrp_basic - // in the daughterboard, shutdown the wbxng now (when only one of Tx - // and Rx is open, this is always true). + /* + Enable transmitter if on is true + */ - if (d_wbxng->usrp() == usrp()){ - //std::cerr << "db_wbxng_base::shutdown_common: same -> shutting down\n"; - d_wbxng->shutdown(); + int v; + //int mask = RX_TXN | ENABLE_5 | ENABLE_33; + if(on) { + v = ENABLE_5 | ENABLE_33; } else { - //std::cerr << "db_wbxng_base::shutdown_common: different -> ignoring\n"; + v = RX_TXN; } + throw std::runtime_error("set_enable called from wbxng_base_tx\n"); + //return usrp()->write_io(d_which, v, mask); } -struct freq_result_t -db_wbxng_base::set_freq(double target_freq) +float +wbxng_base_tx::gain_min() { - /* - * @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. - */ - return d_wbxng->set_freq(target_freq+d_lo_offset); + return usrp()->pga_max(); } -bool -db_wbxng_base::is_quadrature() +float +wbxng_base_tx::gain_max() { - /* - * 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; + return usrp()->pga_max(); } -double -db_wbxng_base::freq_min() +float +wbxng_base_tx::gain_db_per_step() { - return 2.4e9; + return 1; } -double -db_wbxng_base::freq_max() +bool +wbxng_base_tx::set_gain(float gain) { - return 6.0e9; + /* + Set the gain. + + @param gain: gain in decibels + @returns True/False + */ + return _set_pga(usrp()->pga_max()); } -/******************************************************************************/ +/**************************************************************************/ -db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which) - : db_wbxng_base(usrp, which) +wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) + : wbxng_base(_usrp, which, _power_on) { - set_lo_offset(LO_OFFSET); - //printf("db_wbxng_tx::db_wbxng_tx\n"); + /* + @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; + } + + d_common = new adf4350(_usrp, d_which, d_spi_enable); + + /* + 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); + */ } -db_wbxng_tx::~db_wbxng_tx() +wbxng_base_rx::~wbxng_base_rx() { shutdown(); } void -db_wbxng_tx::shutdown() +wbxng_base_rx::shutdown() { + // fprintf(stderr, "wbxng_base_rx::shutdown d_is_shutdown = %d\n", d_is_shutdown); + if (!d_is_shutdown){ d_is_shutdown = true; - shutdown_common(); + // 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, "wbxng_base_rx::shutdown before _write_control\n"); + //_write_control(_compute_control_reg()); + + // fprintf(stderr, "wbxng_base_rx::shutdown before _enable_refclk\n"); + //_enable_refclk(false); // turn off refclk + + // fprintf(stderr, "wbxng_base_rx::shutdown before set_auto_tr\n"); + //set_auto_tr(false); + + // fprintf(stderr, "wbxng_base_rx::shutdown after set_auto_tr\n"); } } -float -db_wbxng_tx::gain_min() +bool +wbxng_base_rx::set_auto_tr(bool on) { - return 0; + //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; } -float -db_wbxng_tx::gain_max() +/* *** TODO *** Defined select_rx_antenna twice? +bool +wbxng_base_rx::select_rx_antenna(int which_antenna) { - return 30; -} + **COMMENT** + Specify which antenna port to use for reception. + @param which_antenna: either 'TX/RX' or 'RX2' + **COMMENT** -float -db_wbxng_tx::gain_db_per_step() -{ - return (30.0/63.0); + 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 -db_wbxng_tx::set_gain(float gain) +wbxng_base_rx::select_rx_antenna(const std::string &which_antenna) { - return d_wbxng->set_tx_gain(gain); + /* + 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 -db_wbxng_tx::i_and_q_swapped() +wbxng_base_rx::set_gain(float gain) { - return true; + /* + 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))); + */ + return false; } +// ---------------------------------------------------------------- -/******************************************************************************/ +db_wbxng_tx::db_wbxng_tx(usrp_basic_sptr usrp, int which) + : wbxng_base_tx(usrp, which) +{ +} +db_wbxng_tx::~db_wbxng_tx() +{ +} -db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which) - : db_wbxng_base(usrp, which) +/* +bool +db_wbxng_tx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) { - /* - * @param usrp: instance of usrp.source_c - * @param which: 0 or 1 corresponding to side RX_A or RX_B respectively. - */ - set_lo_offset(LO_OFFSET); - //printf("db_wbxng_rx:d_wbxng_rx\n"); + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); } +*/ -db_wbxng_rx::~db_wbxng_rx() + +db_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which) + : wbxng_base_rx(usrp, which) { - shutdown(); + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain } -void -db_wbxng_rx::shutdown() +db_wbxng_rx::~db_wbxng_rx() { - if (!d_is_shutdown){ - d_is_shutdown = true; - shutdown_common(); - } } float db_wbxng_rx::gain_min() { - return 0.0; + return usrp()->pga_min(); } float db_wbxng_rx::gain_max() { - return 92.0; + return usrp()->pga_max()+70; } float db_wbxng_rx::gain_db_per_step() { - return 1; + return 0.05; +} + + +bool +db_wbxng_rx::i_and_q_swapped() +{ + return true; } +/* bool -db_wbxng_rx::set_gain(float gain) +db_wbxng_rx::_compute_regs(double freq, int &retR, int &retcontrol, + int &retN, double &retfreq) { - return d_wbxng->set_rx_gain(gain); + return d_common->_compute_regs(_refclk_freq(), freq, retR, + retcontrol, retN, retfreq); } +*/ + diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc new file mode 100644 index 000000000..22262be33 --- /dev/null +++ b/usrp/host/lib/db_wbxng_adf4350.cc @@ -0,0 +1,156 @@ +/* + * Copyright 2009 Ettus Research LLC + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <usrp/db_wbxng_adf4350.h> +#include <usrp/db_wbxng_adf4350_regs.h> +#include <db_base_impl.h> +#include <stdio.h> +//#include "io.h" +//#include "spi.h" + +#define INPUT_REF_FREQ FREQ_C(10e6) +#define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom)) +#define FREQ_C(freq) ((uint32_t)DIV_ROUND(freq, (uint32_t)1000)) +#define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ) /* input ref freq with doubler turned on */ +#define MIN_INT_DIV uint16_t(23) /* minimum int divider, prescaler 4/5 only */ +#define MAX_RF_DIV uint8_t(16) /* max rf divider, divides rf output */ +#define MIN_VCO_FREQ FREQ_C(2.2e9) /* minimum vco freq */ +#define MAX_VCO_FREQ FREQ_C(4.4e9) /* minimum vco freq */ +#define MAX_FREQ MAX_VCO_FREQ /* upper bound freq (rf div = 1) */ +#define MIN_FREQ DIV_ROUND(MIN_VCO_FREQ, MAX_RF_DIV) /* calculated lower bound freq */ + +#define CE_PIN (1 << 3) +#define PDB_RF_PIN (1 << 2) +#define MUX_PIN (1 << 1) +#define LD_PIN (1 << 0) + +adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ + /* Initialize the pin directions. */ + + d_usrp = _usrp; + d_which = _which; + d_spi_enable = _spi_enable; + d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; + + d_regs = new adf4350_regs(this); + + /* Outputs */ + d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), 0xffff); + + /* Initialize the pin levels. */ + _enable(true); + /* Initialize the registers. */ + d_regs->_load_register(5); + d_regs->_load_register(4); + d_regs->_load_register(3); + d_regs->_load_register(2); + d_regs->_load_register(1); + d_regs->_load_register(0); +} + +adf4350::~adf4350(){ + delete d_regs; +} + +freq_t +adf4350::_get_max_freq(void){ + return MAX_FREQ; +} + +freq_t +adf4350::_get_min_freq(void){ + return MIN_FREQ; +} + +bool +adf4350::_get_locked(void){ + return d_usrp->read_io(d_which) & LD_PIN; +} + +void +adf4350::_enable(bool enable){ + if (enable){ /* chip enable */ + d_usrp->write_io(d_which, 1, CE_PIN); + }else{ + d_usrp->write_io(d_which, 0, CE_PIN); + } +} + +void +adf4350::_write(uint8_t addr, uint32_t data){ + data |= addr; + + // create str from data here + char s[4]; + s[0] = (char)((data >> 24) & 0xff); + s[1] = (char)((data >> 16) & 0xff); + s[2] = (char)((data >> 8) & 0xff); + s[3] = (char)(data & 0xff); + std::string str(s, 3); + + d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str); + /* pulse latch */ + //d_usrp->write_io(d_which, 1, LE_PIN); + //d_usrp->write_io(d_which, 0, LE_PIN); +} + +bool +adf4350::_set_freq(freq_t freq){ + /* Set the frequency by setting int, frac, mod, r, div */ + if (freq > MAX_FREQ || freq < MIN_FREQ) return false; + /* Ramp up the RF divider until the VCO is within range. */ + d_regs->_divider_select = 0; + while (freq < MIN_VCO_FREQ){ + freq <<= 1; //double the freq + d_regs->_divider_select++; //double the divider + } + /* Ramp up the R divider until the N divider is at least the minimum. */ + d_regs->_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq; + uint64_t n_mod; + do{ + d_regs->_10_bit_r_counter++; + n_mod = freq; + n_mod *= d_regs->_10_bit_r_counter; + n_mod *= d_regs->_mod; + n_mod /= INPUT_REF_FREQ_2X; + /* calculate int and frac */ + d_regs->_int = n_mod/d_regs->_mod; + d_regs->_frac = (n_mod - (freq_t)d_regs->_int*d_regs->_mod) & uint16_t(0xfff); + /*printf( + "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", + freq, d_regs->_int, d_regs->_frac, + d_regs->_mod, d_regs->_10_bit_r_counter, (1 << d_regs->_divider_select) + );*/ + }while(d_regs->_int < MIN_INT_DIV); + /* calculate the band select so PFD is under 125 KHz */ + d_regs->_8_bit_band_select_clock_divider_value = \ + INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->_10_bit_r_counter) + 1; + /* load involved registers */ + d_regs->_load_register(2); + d_regs->_load_register(4); + d_regs->_load_register(0); /* register 0 must be last */ + return true; +} + +freq_t +adf4350::_get_freq(void){ + /* Calculate the freq from int, frac, mod, ref, r, div: + * freq = (int + frac/mod) * (ref/r) + * Keep precision by doing multiplies first: + * freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div) + */ + uint64_t temp; + temp = d_regs->_int; + temp *= d_regs->_mod; + temp += d_regs->_frac; + temp *= INPUT_REF_FREQ_2X; + temp /= d_regs->_mod; + temp /= d_regs->_10_bit_r_counter; + temp /= (1 << d_regs->_divider_select); + return temp; +} diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc new file mode 100644 index 000000000..b320e8bbf --- /dev/null +++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc @@ -0,0 +1,106 @@ +/* + * Copyright 2009 Ettus Research LLC + */ + +#include <usrp/db_wbxng_adf4350_regs.h> +#include <usrp/db_wbxng_adf4350.h> +//#include "cal_div.h" + +adf4350_regs::adf4350_regs(adf4350* _adf4350){ + d_adf4350 = _adf4350; + + /* reg 0 */ + _int = uint16_t(100); + _frac = 0; + /* reg 1 */ + _prescaler = 1; /* 8/9 */ + _phase = 0; /* 0 */ + _mod = uint16_t(0xfff); /* max fractional accuracy */ + /* reg 2 */ + _low_noise_and_low_spur_modes = 0; /* low noise mode */ + _muxout = 6; /* digital lock detect */ + _reference_doubler = 1; /* enabled */ + _rdiv2 = 0; /* disabled */ + _10_bit_r_counter = uint16_t(1); + _double_buff = 0; /* disabled */ + _charge_pump_setting = 7; /* 2.50 mA */ + _ldf = 0; /* frac-n */ + _ldp = 0; /* 10 ns */ + _pd_polarity = 1; /* positive */ + _power_down = 0; /* disabled */ + _cp_three_state = 0; /* disabled */ + _counter_reset = 0; /* disabled */ + /* reg 3 */ + _csr = 0; /* disabled */ + _clk_div_mode = 0; /* clock divider off */ + _12_bit_clock_divider_value = 0; /* 0 */ + /* reg 4 */ + _feedback_select = 1; /* fundamental */ + _divider_select = 0; + _8_bit_band_select_clock_divider_value = 0; + _vco_power_down = 0; /* vco powered up */ + _mtld = 0; /* mute disabled */ + _aux_output_select = 0; /* divided output */ + _aux_output_enable = 0; /* disabled */ + _aux_output_power = 0; /* -4 */ + _rf_output_enable = 1; /* enabled */ + _output_power = 1; /* -1 */ + /* reg 5 */ + _ld_pin_mode = 1; /* digital lock detect */ +} + +adf4350_regs::~adf4350_regs(void){ +} + +uint32_t +adf4350_regs::_reg_shift(uint32_t data, uint32_t shift){ + return data << shift; + } + +void +adf4350_regs::_load_register(uint8_t addr){ + uint32_t data; + switch (addr){ + case 0: data = ( + _reg_shift(_int, 15) | + _reg_shift(_frac, 3)); break; + case 1: data = ( + _reg_shift(_prescaler, 27) | + _reg_shift(_phase, 15) | + _reg_shift(_mod, 3)); break; + case 2: data = ( + _reg_shift(_low_noise_and_low_spur_modes, 29) | + _reg_shift(_muxout, 26) | + _reg_shift(_reference_doubler, 25) | + _reg_shift(_rdiv2, 24) | + _reg_shift(_10_bit_r_counter, 14) | + _reg_shift(_double_buff, 13) | + _reg_shift(_charge_pump_setting, 9) | + _reg_shift(_ldf, 8) | + _reg_shift(_ldp, 7) | + _reg_shift(_pd_polarity, 6) | + _reg_shift(_power_down, 5) | + _reg_shift(_cp_three_state, 4) | + _reg_shift(_counter_reset, 3)); break; + case 3: data = ( + _reg_shift(_csr, 18) | + _reg_shift(_clk_div_mode, 15) | + _reg_shift(_12_bit_clock_divider_value, 3)); break; + case 4: data = ( + _reg_shift(_feedback_select, 23) | + _reg_shift(_divider_select, 20) | + _reg_shift(_8_bit_band_select_clock_divider_value, 12) | + _reg_shift(_vco_power_down, 11) | + _reg_shift(_mtld, 10) | + _reg_shift(_aux_output_select, 9) | + _reg_shift(_aux_output_enable, 8) | + _reg_shift(_aux_output_power, 6) | + _reg_shift(_rf_output_enable, 5) | + _reg_shift(_output_power, 3)); break; + case 5: data = ( + _reg_shift(_ld_pin_mode, 22)); break; + default: return; + } + /* write the data out to spi */ + d_adf4350->_write(addr, data); +} -- cgit From 16951928760f44b729f3f67e3c6c279c3fef28c1 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Fri, 21 Aug 2009 15:16:18 -0700 Subject: twiddling gpio successfully --- usrp/host/include/usrp/db_wbxng.h | 9 +- usrp/host/include/usrp/db_wbxng_adf4350.h | 2 +- usrp/host/include/usrp/db_wbxng_adf4350_regs.h | 64 ++++++------ usrp/host/lib/db_wbxng.cc | 75 +++++++------- usrp/host/lib/db_wbxng_adf4350.cc | 38 +++---- usrp/host/lib/db_wbxng_adf4350_regs.cc | 135 +++++++++++++------------ 6 files changed, 164 insertions(+), 159 deletions(-) (limited to 'usrp') diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h index 1ded1b5dc..0d03e4297 100644 --- a/usrp/host/include/usrp/db_wbxng.h +++ b/usrp/host/include/usrp/db_wbxng.h @@ -50,8 +50,7 @@ protected: void _write_it(int v); bool _lock_detect(); - virtual bool _compute_regs(double freq, int &retR, int &retcontrol, - int &retN, double &retfreq); + //virtual bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq); int _compute_control_reg(); int _refclk_divisor(); double _refclk_freq(); @@ -117,8 +116,7 @@ class db_wbxng_tx : public wbxng_base_tx ~db_wbxng_tx(); // Wrapper calls to d_common functions - bool _compute_regs(double freq, int &retR, int &retcontrol, - int &retN, double &retfreq); + //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq); }; class db_wbxng_rx : public wbxng_base_rx @@ -132,8 +130,7 @@ public: float gain_db_per_step(); bool i_and_q_swapped(); - bool _compute_regs(double freq, int &retR, int &retcontrol, - int &retN, double &retfreq); + //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq); }; diff --git a/usrp/host/include/usrp/db_wbxng_adf4350.h b/usrp/host/include/usrp/db_wbxng_adf4350.h index a5ebe646e..d7b8dd99b 100644 --- a/usrp/host/include/usrp/db_wbxng_adf4350.h +++ b/usrp/host/include/usrp/db_wbxng_adf4350.h @@ -9,7 +9,7 @@ #include <usrp/db_base.h> #include <stdint.h> -typedef uint32_t freq_t; +typedef uint64_t freq_t; class adf4350_regs; class adf4350 diff --git a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h index ec78a9fa5..6a5b77a4b 100644 --- a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h +++ b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h @@ -23,43 +23,43 @@ public: void _load_register(uint8_t addr); /* reg 0 */ - uint16_t _int; - uint16_t _frac; + uint16_t d_int; + uint16_t d_frac; /* reg 1 */ - static uint8_t _prescaler; - static uint16_t _phase; - uint16_t _mod; + static const uint8_t s_prescaler; + static const uint16_t s_phase; + uint16_t d_mod; /* reg 2 */ - static uint8_t _low_noise_and_low_spur_modes; - static uint8_t _muxout; - static uint8_t _reference_doubler; - static uint8_t _rdiv2; - uint16_t _10_bit_r_counter; - static uint8_t _double_buff; - static uint8_t _charge_pump_setting; - static uint8_t _ldf; - static uint8_t _ldp; - static uint8_t _pd_polarity; - static uint8_t _power_down; - static uint8_t _cp_three_state; - static uint8_t _counter_reset; + static const uint8_t s_low_noise_and_low_spur_modes; + static const uint8_t s_muxout; + static const uint8_t s_reference_doubler; + static const uint8_t s_rdiv2; + uint16_t d_10_bit_r_counter; + static const uint8_t s_double_buff; + static const uint8_t s_charge_pump_setting; + static const uint8_t s_ldf; + static const uint8_t s_ldp; + static const uint8_t s_pd_polarity; + static const uint8_t s_power_down; + static const uint8_t s_cp_three_state; + static const uint8_t s_counter_reset; /* reg 3 */ - static uint8_t _csr; - static uint8_t _clk_div_mode; - static uint16_t _12_bit_clock_divider_value; + static const uint8_t s_csr; + static const uint8_t s_clk_div_mode; + static const uint16_t s_12_bit_clock_divider_value; /* reg 4 */ - static uint8_t _feedback_select; - uint8_t _divider_select; - uint8_t _8_bit_band_select_clock_divider_value; - static uint8_t _vco_power_down; - static uint8_t _mtld; - static uint8_t _aux_output_select; - static uint8_t _aux_output_enable; - static uint8_t _aux_output_power; - static uint8_t _rf_output_enable; - static uint8_t _output_power; + static const uint8_t s_feedback_select; + uint8_t d_divider_select; + uint8_t d_8_bit_band_select_clock_divider_value; + static const uint8_t s_vco_power_down; + static const uint8_t s_mtld; + static const uint8_t s_aux_output_select; + static const uint8_t s_aux_output_enable; + static const uint8_t s_aux_output_power; + static const uint8_t s_rf_output_enable; + static const uint8_t s_output_power; /* reg 5 */ - static uint8_t _ld_pin_mode; + static const uint8_t s_ld_pin_mode; }; #endif /* ADF4350_REGS_H */ diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index e911c9d03..ccad3cb41 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -46,7 +46,7 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on) d_first = true; d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; - usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs + usrp()->_write_oe(d_which, 1, 0xffff); // turn off all outputs _enable_refclk(false); // disable refclk set_auto_tr(false); @@ -125,11 +125,13 @@ wbxng_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) { + + if(d_common->_get_locked()){ return true; } else { // Give it a second chance + return false; + /* // FIXME: make portable sleep timespec t; t.tv_sec = 0; @@ -142,8 +144,9 @@ wbxng_base::_lock_detect() else { return false; } + */ } - */ + throw std::runtime_error("_lock_detect called from wbxng_base\n"); } @@ -199,14 +202,17 @@ wbxng_base::set_freq(double freq) actual_baseband_freq is the RF frequency that corresponds to DC in the IF. */ - struct freq_result_t args = {false, 0}; + freq_t int_freq = (freq_t) freq; + bool ok = d_common->_set_freq(int_freq); + double freq_result = (double) d_common->_get_freq(); + struct freq_result_t args = {ok, freq_result}; // 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; + //freq += d_lo_offset; //int R, control, N; //double actual_freq; @@ -252,15 +258,13 @@ wbxng_base::is_quadrature() double wbxng_base::freq_min() { - throw std::runtime_error("freq_min called from wbxng_base\n"); - //return d_common->freq_min(); + return (double) d_common->_get_min_freq(); } double wbxng_base::freq_max() { - throw std::runtime_error("freq_max called from wbxng_base\n"); - //return d_common->freq_max(); + return (double) d_common->_get_max_freq(); } // ---------------------------------------------------------------- @@ -283,13 +287,11 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); // 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); + usrp()->_write_oe(d_which,(RX_TXN|ENABLE_33|ENABLE_5), 0xffff); + usrp()->write_io(d_which, (power_on()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5)); + //set_lo_offset(4e6); - set_gain((gain_min() + gain_max()) / 2.0); // initialize gain - */ + //set_gain((gain_min() + gain_max()) / 2.0); // initialize gain } wbxng_base_tx::~wbxng_base_tx() @@ -308,12 +310,14 @@ wbxng_base_tx::shutdown() // 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)); + usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5)); + /* // Power down VCO/PLL d_PD = 3; _write_control(_compute_control_reg()); + */ _enable_refclk(false); // turn off refclk set_auto_tr(false); } @@ -325,8 +329,8 @@ wbxng_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_mask (RX_TXN | ENABLE_33 | ENABLE_5); + ok &= set_atr_txval(0 | ENABLE_33 | ENABLE_5); ok &= set_atr_rxval(RX_TXN | 0); } else { @@ -346,15 +350,14 @@ wbxng_base_tx::set_enable(bool on) */ int v; - //int mask = RX_TXN | ENABLE_5 | ENABLE_33; + int mask = RX_TXN | ENABLE_5 | ENABLE_33; if(on) { v = ENABLE_5 | ENABLE_33; } else { v = RX_TXN; } - throw std::runtime_error("set_enable called from wbxng_base_tx\n"); - //return usrp()->write_io(d_which, v, mask); + return usrp()->write_io(d_which, v, mask); } float @@ -408,16 +411,16 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); - /* - 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)); + usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), 0xffff); + usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), + (RX2_RX1N|ENABLE_33|ENABLE_5)); // set up for RX on TX/RX port select_rx_antenna("TX/RX"); bypass_adc_buffers(true); + /* set_lo_offset(-4e6); */ } @@ -437,7 +440,7 @@ wbxng_base_rx::shutdown() // do whatever there is to do to shutdown // Power down - //usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE)); + usrp()->common_write_io(C_RX, d_which, power_off(), (ENABLE_33|ENABLE_5)); // Power down VCO/PLL d_PD = 3; @@ -447,10 +450,10 @@ wbxng_base_rx::shutdown() //_write_control(_compute_control_reg()); // fprintf(stderr, "wbxng_base_rx::shutdown before _enable_refclk\n"); - //_enable_refclk(false); // turn off refclk + _enable_refclk(false); // turn off refclk // fprintf(stderr, "wbxng_base_rx::shutdown before set_auto_tr\n"); - //set_auto_tr(false); + set_auto_tr(false); // fprintf(stderr, "wbxng_base_rx::shutdown after set_auto_tr\n"); } @@ -462,9 +465,9 @@ wbxng_base_rx::set_auto_tr(bool on) //bool ok = true; /* if(on) { - ok &= set_atr_mask (ENABLE); + ok &= set_atr_mask (ENABLE_33|ENABLE_5); ok &= set_atr_txval( 0); - ok &= set_atr_rxval(ENABLE); + ok &= set_atr_rxval(ENABLE_33|ENABLE_5); } else { ok &= set_atr_mask (0); @@ -475,14 +478,13 @@ wbxng_base_rx::set_auto_tr(bool on) return true; } -/* *** TODO *** Defined select_rx_antenna twice? bool wbxng_base_rx::select_rx_antenna(int which_antenna) { - **COMMENT** + /* Specify which antenna port to use for reception. @param which_antenna: either 'TX/RX' or 'RX2' - **COMMENT** + */ if(which_antenna == 0) { usrp()->write_io(d_which, 0,RX2_RX1N); @@ -496,7 +498,6 @@ wbxng_base_rx::select_rx_antenna(int which_antenna) } return true; } -*/ bool wbxng_base_rx::select_rx_antenna(const std::string &which_antenna) @@ -506,7 +507,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna) @param which_antenna: either 'TX/RX' or 'RX2' */ - /* + if(which_antenna == "TX/RX") { usrp()->write_io(d_which, 0, RX2_RX1N); } @@ -517,7 +518,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna) // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n"); return false; } - */ + return true; } diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc index 22262be33..a1f024b4f 100644 --- a/usrp/host/lib/db_wbxng_adf4350.cc +++ b/usrp/host/lib/db_wbxng_adf4350.cc @@ -104,32 +104,32 @@ adf4350::_set_freq(freq_t freq){ /* Set the frequency by setting int, frac, mod, r, div */ if (freq > MAX_FREQ || freq < MIN_FREQ) return false; /* Ramp up the RF divider until the VCO is within range. */ - d_regs->_divider_select = 0; + d_regs->d_divider_select = 0; while (freq < MIN_VCO_FREQ){ freq <<= 1; //double the freq - d_regs->_divider_select++; //double the divider + d_regs->d_divider_select++; //double the divider } /* Ramp up the R divider until the N divider is at least the minimum. */ - d_regs->_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq; + d_regs->d_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq; uint64_t n_mod; do{ - d_regs->_10_bit_r_counter++; + d_regs->d_10_bit_r_counter++; n_mod = freq; - n_mod *= d_regs->_10_bit_r_counter; - n_mod *= d_regs->_mod; + n_mod *= d_regs->d_10_bit_r_counter; + n_mod *= d_regs->d_mod; n_mod /= INPUT_REF_FREQ_2X; /* calculate int and frac */ - d_regs->_int = n_mod/d_regs->_mod; - d_regs->_frac = (n_mod - (freq_t)d_regs->_int*d_regs->_mod) & uint16_t(0xfff); + d_regs->d_int = n_mod/d_regs->d_mod; + d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff); /*printf( "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", - freq, d_regs->_int, d_regs->_frac, - d_regs->_mod, d_regs->_10_bit_r_counter, (1 << d_regs->_divider_select) + freq, d_regs->d_int, d_regs->d_frac, + d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select) );*/ - }while(d_regs->_int < MIN_INT_DIV); + }while(d_regs->d_int < MIN_INT_DIV); /* calculate the band select so PFD is under 125 KHz */ - d_regs->_8_bit_band_select_clock_divider_value = \ - INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->_10_bit_r_counter) + 1; + d_regs->d_8_bit_band_select_clock_divider_value = \ + INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1; /* load involved registers */ d_regs->_load_register(2); d_regs->_load_register(4); @@ -145,12 +145,12 @@ adf4350::_get_freq(void){ * freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div) */ uint64_t temp; - temp = d_regs->_int; - temp *= d_regs->_mod; - temp += d_regs->_frac; + temp = d_regs->d_int; + temp *= d_regs->d_mod; + temp += d_regs->d_frac; temp *= INPUT_REF_FREQ_2X; - temp /= d_regs->_mod; - temp /= d_regs->_10_bit_r_counter; - temp /= (1 << d_regs->_divider_select); + temp /= d_regs->d_mod; + temp /= d_regs->d_10_bit_r_counter; + temp /= (1 << d_regs->d_divider_select); return temp; } diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc index b320e8bbf..3452663c8 100644 --- a/usrp/host/lib/db_wbxng_adf4350_regs.cc +++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc @@ -6,47 +6,54 @@ #include <usrp/db_wbxng_adf4350.h> //#include "cal_div.h" +/* reg 0 */ +/* reg 1 */ +const uint8_t adf4350_regs::s_prescaler = 1; +const uint16_t adf4350_regs::s_phase = 0; +/* reg 2 */ +const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0; +const uint8_t adf4350_regs::s_muxout = 6; +const uint8_t adf4350_regs::s_reference_doubler = 1; +const uint8_t adf4350_regs::s_rdiv2 = 0; +const uint8_t adf4350_regs::s_double_buff = 0; +const uint8_t adf4350_regs::s_charge_pump_setting = 7; +const uint8_t adf4350_regs::s_ldf = 0; +const uint8_t adf4350_regs::s_ldp = 0; +const uint8_t adf4350_regs::s_pd_polarity = 1; +const uint8_t adf4350_regs::s_power_down = 0; +const uint8_t adf4350_regs::s_cp_three_state = 0; +const uint8_t adf4350_regs::s_counter_reset = 0; +/* reg 3 */ +const uint8_t adf4350_regs::s_csr = 0; +const uint8_t adf4350_regs::s_clk_div_mode = 0; +const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0; +/* reg 4 */ +const uint8_t adf4350_regs::s_feedback_select = 1; +const uint8_t adf4350_regs::s_vco_power_down = 0; +const uint8_t adf4350_regs::s_mtld = 0; +const uint8_t adf4350_regs::s_aux_output_select = 0; +const uint8_t adf4350_regs::s_aux_output_enable = 0; +const uint8_t adf4350_regs::s_aux_output_power = 0; +const uint8_t adf4350_regs::s_rf_output_enable = 1; +const uint8_t adf4350_regs::s_output_power = 1; +/* reg 5 */ +const uint8_t adf4350_regs::s_ld_pin_mode = 1; + adf4350_regs::adf4350_regs(adf4350* _adf4350){ d_adf4350 = _adf4350; /* reg 0 */ - _int = uint16_t(100); - _frac = 0; + d_int = uint16_t(100); + d_frac = 0; /* reg 1 */ - _prescaler = 1; /* 8/9 */ - _phase = 0; /* 0 */ - _mod = uint16_t(0xfff); /* max fractional accuracy */ + d_mod = uint16_t(0xfff); /* max fractional accuracy */ /* reg 2 */ - _low_noise_and_low_spur_modes = 0; /* low noise mode */ - _muxout = 6; /* digital lock detect */ - _reference_doubler = 1; /* enabled */ - _rdiv2 = 0; /* disabled */ - _10_bit_r_counter = uint16_t(1); - _double_buff = 0; /* disabled */ - _charge_pump_setting = 7; /* 2.50 mA */ - _ldf = 0; /* frac-n */ - _ldp = 0; /* 10 ns */ - _pd_polarity = 1; /* positive */ - _power_down = 0; /* disabled */ - _cp_three_state = 0; /* disabled */ - _counter_reset = 0; /* disabled */ + d_10_bit_r_counter = uint16_t(1); /* reg 3 */ - _csr = 0; /* disabled */ - _clk_div_mode = 0; /* clock divider off */ - _12_bit_clock_divider_value = 0; /* 0 */ /* reg 4 */ - _feedback_select = 1; /* fundamental */ - _divider_select = 0; - _8_bit_band_select_clock_divider_value = 0; - _vco_power_down = 0; /* vco powered up */ - _mtld = 0; /* mute disabled */ - _aux_output_select = 0; /* divided output */ - _aux_output_enable = 0; /* disabled */ - _aux_output_power = 0; /* -4 */ - _rf_output_enable = 1; /* enabled */ - _output_power = 1; /* -1 */ + d_divider_select = 0; + d_8_bit_band_select_clock_divider_value = 0; /* reg 5 */ - _ld_pin_mode = 1; /* digital lock detect */ } adf4350_regs::~adf4350_regs(void){ @@ -62,43 +69,43 @@ adf4350_regs::_load_register(uint8_t addr){ uint32_t data; switch (addr){ case 0: data = ( - _reg_shift(_int, 15) | - _reg_shift(_frac, 3)); break; + _reg_shift(d_int, 15) | + _reg_shift(d_frac, 3)); break; case 1: data = ( - _reg_shift(_prescaler, 27) | - _reg_shift(_phase, 15) | - _reg_shift(_mod, 3)); break; + _reg_shift(s_prescaler, 27) | + _reg_shift(s_phase, 15) | + _reg_shift(d_mod, 3)); break; case 2: data = ( - _reg_shift(_low_noise_and_low_spur_modes, 29) | - _reg_shift(_muxout, 26) | - _reg_shift(_reference_doubler, 25) | - _reg_shift(_rdiv2, 24) | - _reg_shift(_10_bit_r_counter, 14) | - _reg_shift(_double_buff, 13) | - _reg_shift(_charge_pump_setting, 9) | - _reg_shift(_ldf, 8) | - _reg_shift(_ldp, 7) | - _reg_shift(_pd_polarity, 6) | - _reg_shift(_power_down, 5) | - _reg_shift(_cp_three_state, 4) | - _reg_shift(_counter_reset, 3)); break; + _reg_shift(s_low_noise_and_low_spur_modes, 29) | + _reg_shift(s_muxout, 26) | + _reg_shift(s_reference_doubler, 25) | + _reg_shift(s_rdiv2, 24) | + _reg_shift(d_10_bit_r_counter, 14) | + _reg_shift(s_double_buff, 13) | + _reg_shift(s_charge_pump_setting, 9) | + _reg_shift(s_ldf, 8) | + _reg_shift(s_ldp, 7) | + _reg_shift(s_pd_polarity, 6) | + _reg_shift(s_power_down, 5) | + _reg_shift(s_cp_three_state, 4) | + _reg_shift(s_counter_reset, 3)); break; case 3: data = ( - _reg_shift(_csr, 18) | - _reg_shift(_clk_div_mode, 15) | - _reg_shift(_12_bit_clock_divider_value, 3)); break; + _reg_shift(s_csr, 18) | + _reg_shift(s_clk_div_mode, 15) | + _reg_shift(s_12_bit_clock_divider_value, 3)); break; case 4: data = ( - _reg_shift(_feedback_select, 23) | - _reg_shift(_divider_select, 20) | - _reg_shift(_8_bit_band_select_clock_divider_value, 12) | - _reg_shift(_vco_power_down, 11) | - _reg_shift(_mtld, 10) | - _reg_shift(_aux_output_select, 9) | - _reg_shift(_aux_output_enable, 8) | - _reg_shift(_aux_output_power, 6) | - _reg_shift(_rf_output_enable, 5) | - _reg_shift(_output_power, 3)); break; + _reg_shift(s_feedback_select, 23) | + _reg_shift(d_divider_select, 20) | + _reg_shift(d_8_bit_band_select_clock_divider_value, 12) | + _reg_shift(s_vco_power_down, 11) | + _reg_shift(s_mtld, 10) | + _reg_shift(s_aux_output_select, 9) | + _reg_shift(s_aux_output_enable, 8) | + _reg_shift(s_aux_output_power, 6) | + _reg_shift(s_rf_output_enable, 5) | + _reg_shift(s_output_power, 3)); break; case 5: data = ( - _reg_shift(_ld_pin_mode, 22)); break; + _reg_shift(s_ld_pin_mode, 22)); break; default: return; } /* write the data out to spi */ -- cgit From e4b5ce36f60652dba15ff4124b347c9a8b725d05 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Sun, 23 Aug 2009 17:40:43 -0700 Subject: Able to tune RX VCO, observe R and N divider output on MUXOUT --- usrp/host/lib/db_wbxng.cc | 23 ++++++++++--------- usrp/host/lib/db_wbxng_adf4350.cc | 40 ++++++++++++++++++++++------------ usrp/host/lib/db_wbxng_adf4350_regs.cc | 20 ++++++++--------- 3 files changed, 49 insertions(+), 34 deletions(-) (limited to 'usrp') diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index ccad3cb41..1c7b23265 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -43,10 +43,11 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on) @type which: int */ + usrp()->_write_oe(d_which, 0, 0xffff); // turn off all outputs + d_first = true; d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0; - usrp()->_write_oe(d_which, 1, 0xffff); // turn off all outputs _enable_refclk(false); // disable refclk set_auto_tr(false); @@ -202,11 +203,14 @@ wbxng_base::set_freq(double freq) actual_baseband_freq is the RF frequency that corresponds to DC in the IF. */ - freq_t int_freq = (freq_t) freq; + freq_t int_freq = (freq_t) (freq/1000); bool ok = d_common->_set_freq(int_freq); - double freq_result = (double) d_common->_get_freq(); + double freq_result = (double) d_common->_get_freq()*1000; struct freq_result_t args = {ok, freq_result}; + fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", + int_freq*1000, freq_result, _lock_detect()); + // 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 @@ -287,8 +291,8 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); // power up the transmit side, but don't enable the mixer - usrp()->_write_oe(d_which,(RX_TXN|ENABLE_33|ENABLE_5), 0xffff); - usrp()->write_io(d_which, (power_on()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->_write_oe(d_which,(PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_on()|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); //set_lo_offset(4e6); //set_gain((gain_min() + gain_max()) / 2.0); // initialize gain @@ -310,7 +314,7 @@ wbxng_base_tx::shutdown() // 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), (RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_off()|RX_TXN), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); /* // Power down VCO/PLL @@ -352,7 +356,7 @@ wbxng_base_tx::set_enable(bool on) int v; int mask = RX_TXN | ENABLE_5 | ENABLE_33; if(on) { - v = ENABLE_5 | ENABLE_33; + v = PLL_CE | ENABLE_5 | ENABLE_33; } else { v = RX_TXN; @@ -411,9 +415,8 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); - usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), 0xffff); - usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), - (RX2_RX1N|ENABLE_33|ENABLE_5)); + usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5)); // set up for RX on TX/RX port select_rx_antenna("TX/RX"); diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc index a1f024b4f..6e74bf0c1 100644 --- a/usrp/host/lib/db_wbxng_adf4350.cc +++ b/usrp/host/lib/db_wbxng_adf4350.cc @@ -13,11 +13,11 @@ //#include "io.h" //#include "spi.h" -#define INPUT_REF_FREQ FREQ_C(10e6) +#define INPUT_REF_FREQ FREQ_C(32e6) #define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom)) -#define FREQ_C(freq) ((uint32_t)DIV_ROUND(freq, (uint32_t)1000)) +#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000)) #define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ) /* input ref freq with doubler turned on */ -#define MIN_INT_DIV uint16_t(23) /* minimum int divider, prescaler 4/5 only */ +#define MIN_INT_DIV uint16_t(300) /* minimum int divider, prescaler 4/5 only */ #define MAX_RF_DIV uint8_t(16) /* max rf divider, divides rf output */ #define MIN_VCO_FREQ FREQ_C(2.2e9) /* minimum vco freq */ #define MAX_VCO_FREQ FREQ_C(4.4e9) /* minimum vco freq */ @@ -40,12 +40,23 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ d_regs = new adf4350_regs(this); /* Outputs */ - d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), 0xffff); + d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); + d_usrp->write_io(d_which, (CE_PIN), (CE_PIN | PDB_RF_PIN)); /* Initialize the pin levels. */ _enable(true); /* Initialize the registers. */ - d_regs->_load_register(5); + /* + timespec t; + t.tv_sec = 1; + t.tv_nsec = 0; + while (1) { + */ + d_regs->_load_register(5); + /* + nanosleep(&t, NULL); + } + */ d_regs->_load_register(4); d_regs->_load_register(3); d_regs->_load_register(2); @@ -75,9 +86,9 @@ adf4350::_get_locked(void){ void adf4350::_enable(bool enable){ if (enable){ /* chip enable */ - d_usrp->write_io(d_which, 1, CE_PIN); + d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); }else{ - d_usrp->write_io(d_which, 0, CE_PIN); + d_usrp->write_io(d_which, 0, (CE_PIN | PDB_RF_PIN)); } } @@ -91,9 +102,10 @@ adf4350::_write(uint8_t addr, uint32_t data){ s[1] = (char)((data >> 16) & 0xff); s[2] = (char)((data >> 8) & 0xff); s[3] = (char)(data & 0xff); - std::string str(s, 3); + std::string str(s, 4); d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str); + fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data); /* pulse latch */ //d_usrp->write_io(d_which, 1, LE_PIN); //d_usrp->write_io(d_which, 0, LE_PIN); @@ -110,26 +122,26 @@ adf4350::_set_freq(freq_t freq){ d_regs->d_divider_select++; //double the divider } /* Ramp up the R divider until the N divider is at least the minimum. */ - d_regs->d_10_bit_r_counter = INPUT_REF_FREQ_2X*MIN_INT_DIV/freq; + d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq; uint64_t n_mod; do{ d_regs->d_10_bit_r_counter++; n_mod = freq; n_mod *= d_regs->d_10_bit_r_counter; n_mod *= d_regs->d_mod; - n_mod /= INPUT_REF_FREQ_2X; + n_mod /= INPUT_REF_FREQ; /* calculate int and frac */ d_regs->d_int = n_mod/d_regs->d_mod; d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff); - /*printf( + fprintf(stderr, "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", freq, d_regs->d_int, d_regs->d_frac, d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select) - );*/ + ); }while(d_regs->d_int < MIN_INT_DIV); /* calculate the band select so PFD is under 125 KHz */ d_regs->d_8_bit_band_select_clock_divider_value = \ - INPUT_REF_FREQ_2X/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1; + INPUT_REF_FREQ/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1; /* load involved registers */ d_regs->_load_register(2); d_regs->_load_register(4); @@ -148,7 +160,7 @@ adf4350::_get_freq(void){ temp = d_regs->d_int; temp *= d_regs->d_mod; temp += d_regs->d_frac; - temp *= INPUT_REF_FREQ_2X; + temp *= INPUT_REF_FREQ; temp /= d_regs->d_mod; temp /= d_regs->d_10_bit_r_counter; temp /= (1 << d_regs->d_divider_select); diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc index 3452663c8..bf39c73ca 100644 --- a/usrp/host/lib/db_wbxng_adf4350_regs.cc +++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc @@ -8,13 +8,13 @@ /* reg 0 */ /* reg 1 */ -const uint8_t adf4350_regs::s_prescaler = 1; +const uint8_t adf4350_regs::s_prescaler = 0; const uint16_t adf4350_regs::s_phase = 0; /* reg 2 */ const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0; -const uint8_t adf4350_regs::s_muxout = 6; -const uint8_t adf4350_regs::s_reference_doubler = 1; -const uint8_t adf4350_regs::s_rdiv2 = 0; +const uint8_t adf4350_regs::s_muxout = 3; +const uint8_t adf4350_regs::s_reference_doubler = 0; +const uint8_t adf4350_regs::s_rdiv2 = 1; const uint8_t adf4350_regs::s_double_buff = 0; const uint8_t adf4350_regs::s_charge_pump_setting = 7; const uint8_t adf4350_regs::s_ldf = 0; @@ -31,11 +31,11 @@ const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0; const uint8_t adf4350_regs::s_feedback_select = 1; const uint8_t adf4350_regs::s_vco_power_down = 0; const uint8_t adf4350_regs::s_mtld = 0; -const uint8_t adf4350_regs::s_aux_output_select = 0; -const uint8_t adf4350_regs::s_aux_output_enable = 0; -const uint8_t adf4350_regs::s_aux_output_power = 0; -const uint8_t adf4350_regs::s_rf_output_enable = 1; -const uint8_t adf4350_regs::s_output_power = 1; +const uint8_t adf4350_regs::s_aux_output_select = 1; +const uint8_t adf4350_regs::s_aux_output_enable = 1; +const uint8_t adf4350_regs::s_aux_output_power = 1; +const uint8_t adf4350_regs::s_rf_output_enable = 0; +const uint8_t adf4350_regs::s_output_power = 0; /* reg 5 */ const uint8_t adf4350_regs::s_ld_pin_mode = 1; @@ -48,7 +48,7 @@ adf4350_regs::adf4350_regs(adf4350* _adf4350){ /* reg 1 */ d_mod = uint16_t(0xfff); /* max fractional accuracy */ /* reg 2 */ - d_10_bit_r_counter = uint16_t(1); + d_10_bit_r_counter = uint16_t(2); /* reg 3 */ /* reg 4 */ d_divider_select = 0; -- cgit From a85e0396f5adf1c4d72d81cbbead02e139a6d5af Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Mon, 24 Aug 2009 16:20:03 -0700 Subject: Locking, controllable synthesizer on TX and RX set Charge Pump Current (Icp) per design guide on schem set R divider to 3, so that PFD inputs are ~21MHz set RF output enable even when looking for AUX --- usrp/host/lib/db_wbxng.cc | 22 ++++++++++++++-------- usrp/host/lib/db_wbxng_adf4350.cc | 28 ++++++++++++++++++++++------ usrp/host/lib/db_wbxng_adf4350_regs.cc | 14 +++++++------- 3 files changed, 43 insertions(+), 21 deletions(-) (limited to 'usrp') diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index 1c7b23265..970d8efd6 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -203,13 +203,19 @@ wbxng_base::set_freq(double freq) actual_baseband_freq is the RF frequency that corresponds to DC in the IF. */ - freq_t int_freq = (freq_t) (freq/1000); + freq_t int_freq = freq_t(freq); bool ok = d_common->_set_freq(int_freq); - double freq_result = (double) d_common->_get_freq()*1000; + double freq_result = (double) d_common->_get_freq(); struct freq_result_t args = {ok, freq_result}; + /* Wait before reading Lock Detect*/ + timespec t; + t.tv_sec = 0; + t.tv_nsec = 10000000; + nanosleep(&t, NULL); + fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", - int_freq*1000, freq_result, _lock_detect()); + int_freq, freq_result, _lock_detect()); // 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 @@ -291,8 +297,8 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); // power up the transmit side, but don't enable the mixer - usrp()->_write_oe(d_which,(PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); - usrp()->write_io(d_which, (power_on()|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->_write_oe(d_which,(PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_on()|PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); //set_lo_offset(4e6); //set_gain((gain_min() + gain_max()) / 2.0); // initialize gain @@ -314,7 +320,7 @@ wbxng_base_tx::shutdown() // 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), (PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_off()|RX_TXN), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); /* // Power down VCO/PLL @@ -354,9 +360,9 @@ wbxng_base_tx::set_enable(bool on) */ int v; - int mask = RX_TXN | ENABLE_5 | ENABLE_33; + int mask = PLL_PDBRF | PLL_PDBRF | RX_TXN | ENABLE_5 | ENABLE_33; if(on) { - v = PLL_CE | ENABLE_5 | ENABLE_33; + v = PLL_PDBRF | PLL_CE | ENABLE_5 | ENABLE_33; } else { v = RX_TXN; diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc index 6e74bf0c1..1facfd882 100644 --- a/usrp/host/lib/db_wbxng_adf4350.cc +++ b/usrp/host/lib/db_wbxng_adf4350.cc @@ -13,11 +13,12 @@ //#include "io.h" //#include "spi.h" -#define INPUT_REF_FREQ FREQ_C(32e6) +#define INPUT_REF_FREQ FREQ_C(64e6) #define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom)) -#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000)) +//#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000)) +#define FREQ_C(freq) uint64_t(freq) #define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ) /* input ref freq with doubler turned on */ -#define MIN_INT_DIV uint16_t(300) /* minimum int divider, prescaler 4/5 only */ +#define MIN_INT_DIV uint16_t(23) /* minimum int divider, prescaler 4/5 only */ #define MAX_RF_DIV uint8_t(16) /* max rf divider, divides rf output */ #define MIN_VCO_FREQ FREQ_C(2.2e9) /* minimum vco freq */ #define MAX_VCO_FREQ FREQ_C(4.4e9) /* minimum vco freq */ @@ -41,7 +42,7 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ /* Outputs */ d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); - d_usrp->write_io(d_which, (CE_PIN), (CE_PIN | PDB_RF_PIN)); + d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); /* Initialize the pin levels. */ _enable(true); @@ -104,7 +105,14 @@ adf4350::_write(uint8_t addr, uint32_t data){ s[3] = (char)(data & 0xff); std::string str(s, 4); + timespec t; + t.tv_sec = 0; + t.tv_nsec = 5e6; + + nanosleep(&t, NULL); d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str); + nanosleep(&t, NULL); + fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data); /* pulse latch */ //d_usrp->write_io(d_which, 1, LE_PIN); @@ -122,7 +130,8 @@ adf4350::_set_freq(freq_t freq){ d_regs->d_divider_select++; //double the divider } /* Ramp up the R divider until the N divider is at least the minimum. */ - d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq; + //d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq; + d_regs->d_10_bit_r_counter = 2; uint64_t n_mod; do{ d_regs->d_10_bit_r_counter++; @@ -141,7 +150,14 @@ adf4350::_set_freq(freq_t freq){ }while(d_regs->d_int < MIN_INT_DIV); /* calculate the band select so PFD is under 125 KHz */ d_regs->d_8_bit_band_select_clock_divider_value = \ - INPUT_REF_FREQ/(FREQ_C(125e3)*d_regs->d_10_bit_r_counter) + 1; + INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1; + fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", + d_regs->d_8_bit_band_select_clock_divider_value, + INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1 + ); + d_regs->_load_register(5); + d_regs->_load_register(3); + d_regs->_load_register(1); /* load involved registers */ d_regs->_load_register(2); d_regs->_load_register(4); diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc index bf39c73ca..2c1660f56 100644 --- a/usrp/host/lib/db_wbxng_adf4350_regs.cc +++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc @@ -12,11 +12,11 @@ const uint8_t adf4350_regs::s_prescaler = 0; const uint16_t adf4350_regs::s_phase = 0; /* reg 2 */ const uint8_t adf4350_regs::s_low_noise_and_low_spur_modes = 0; -const uint8_t adf4350_regs::s_muxout = 3; +const uint8_t adf4350_regs::s_muxout = 6; const uint8_t adf4350_regs::s_reference_doubler = 0; -const uint8_t adf4350_regs::s_rdiv2 = 1; +const uint8_t adf4350_regs::s_rdiv2 = 0; const uint8_t adf4350_regs::s_double_buff = 0; -const uint8_t adf4350_regs::s_charge_pump_setting = 7; +const uint8_t adf4350_regs::s_charge_pump_setting = 5; const uint8_t adf4350_regs::s_ldf = 0; const uint8_t adf4350_regs::s_ldp = 0; const uint8_t adf4350_regs::s_pd_polarity = 1; @@ -31,11 +31,11 @@ const uint16_t adf4350_regs::s_12_bit_clock_divider_value = 0; const uint8_t adf4350_regs::s_feedback_select = 1; const uint8_t adf4350_regs::s_vco_power_down = 0; const uint8_t adf4350_regs::s_mtld = 0; -const uint8_t adf4350_regs::s_aux_output_select = 1; +const uint8_t adf4350_regs::s_aux_output_select = 0; const uint8_t adf4350_regs::s_aux_output_enable = 1; -const uint8_t adf4350_regs::s_aux_output_power = 1; -const uint8_t adf4350_regs::s_rf_output_enable = 0; -const uint8_t adf4350_regs::s_output_power = 0; +const uint8_t adf4350_regs::s_aux_output_power = 3; +const uint8_t adf4350_regs::s_rf_output_enable = 1; +const uint8_t adf4350_regs::s_output_power = 3; /* reg 5 */ const uint8_t adf4350_regs::s_ld_pin_mode = 1; -- cgit From 9aff67eeedcaf7c0fcca0fe2410ec2a3dbd4ea02 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Fri, 18 Sep 2009 18:28:02 -0700 Subject: First Functional TX modulator --- usrp/host/lib/db_wbxng.cc | 35 ++++----- usrp/host/lib/db_wbxng_adf4350.cc | 156 ++++++++++++++++++-------------------- 2 files changed, 91 insertions(+), 100 deletions(-) (limited to 'usrp') diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index 970d8efd6..8a03cfbac 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -21,6 +21,7 @@ #include <usrp/db_wbxng.h> #include <usrp/db_wbxng_adf4350.h> #include <db_base_impl.h> +#include <stdio.h> // d'board i/o pin defs // Tx and Rx have shared defs, but different i/o regs @@ -28,7 +29,7 @@ #define ENABLE_33 (1 << 6) // enables 3.3V supply #define RX_TXN (1 << 5) // Tx only: T/R antenna switch for TX/RX port #define RX2_RX1N (1 << 5) // Rx only: antenna switch between RX2 and TX/RX port -#define BBAMP_EN (1 << 4) +#define TXMOD_EN (1 << 4) #define PLL_CE (1 << 3) #define PLL_PDBRF (1 << 2) #define PLL_MUXOUT (1 << 1) @@ -204,8 +205,8 @@ wbxng_base::set_freq(double freq) */ freq_t int_freq = freq_t(freq); - bool ok = d_common->_set_freq(int_freq); - double freq_result = (double) d_common->_get_freq(); + bool ok = d_common->_set_freq(int_freq*2); + double freq_result = (double) d_common->_get_freq()/2.0; struct freq_result_t args = {ok, freq_result}; /* Wait before reading Lock Detect*/ @@ -268,13 +269,13 @@ wbxng_base::is_quadrature() double wbxng_base::freq_min() { - return (double) d_common->_get_min_freq(); + return (double) d_common->_get_min_freq()/2.0; } double wbxng_base::freq_max() { - return (double) d_common->_get_max_freq(); + return (double) d_common->_get_max_freq()/2.0; } // ---------------------------------------------------------------- @@ -297,8 +298,9 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); // power up the transmit side, but don't enable the mixer - usrp()->_write_oe(d_which,(PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); - usrp()->write_io(d_which, (power_on()|PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->_write_oe(d_which,(RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_on()|RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5)); + fprintf(stderr,"Setting WBXNG TXMOD on"); //set_lo_offset(4e6); //set_gain((gain_min() + gain_max()) / 2.0); // initialize gain @@ -320,12 +322,12 @@ wbxng_base_tx::shutdown() // 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), (PLL_PDBRF|PLL_CE|RX_TXN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_off()|RX_TXN), (RX_TXN|ENABLE_33|ENABLE_5)); - /* // Power down VCO/PLL - d_PD = 3; + d_common->_enable(false); + /* _write_control(_compute_control_reg()); */ _enable_refclk(false); // turn off refclk @@ -337,7 +339,6 @@ bool wbxng_base_tx::set_auto_tr(bool on) { bool ok = true; - /* if(on) { ok &= set_atr_mask (RX_TXN | ENABLE_33 | ENABLE_5); ok &= set_atr_txval(0 | ENABLE_33 | ENABLE_5); @@ -348,7 +349,6 @@ wbxng_base_tx::set_auto_tr(bool on) ok &= set_atr_txval(0); ok &= set_atr_rxval(0); } - */ return ok; } @@ -360,9 +360,9 @@ wbxng_base_tx::set_enable(bool on) */ int v; - int mask = PLL_PDBRF | PLL_PDBRF | RX_TXN | ENABLE_5 | ENABLE_33; + int mask = RX_TXN | ENABLE_5 | ENABLE_33; if(on) { - v = PLL_PDBRF | PLL_CE | ENABLE_5 | ENABLE_33; + v = ENABLE_5 | ENABLE_33; } else { v = RX_TXN; @@ -452,8 +452,7 @@ wbxng_base_rx::shutdown() usrp()->common_write_io(C_RX, d_which, power_off(), (ENABLE_33|ENABLE_5)); // Power down VCO/PLL - d_PD = 3; - + d_common->_enable(false); // fprintf(stderr, "wbxng_base_rx::shutdown before _write_control\n"); //_write_control(_compute_control_reg()); @@ -471,8 +470,7 @@ wbxng_base_rx::shutdown() bool wbxng_base_rx::set_auto_tr(bool on) { - //bool ok = true; - /* + bool ok = true; if(on) { ok &= set_atr_mask (ENABLE_33|ENABLE_5); ok &= set_atr_txval( 0); @@ -483,7 +481,6 @@ wbxng_base_rx::set_auto_tr(bool on) ok &= set_atr_txval(0); ok &= set_atr_rxval(0); } - */ return true; } diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc index 1facfd882..73485d90c 100644 --- a/usrp/host/lib/db_wbxng_adf4350.cc +++ b/usrp/host/lib/db_wbxng_adf4350.cc @@ -31,7 +31,7 @@ #define LD_PIN (1 << 0) adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ - /* Initialize the pin directions. */ + /* Initialize the pin directions. */ d_usrp = _usrp; d_which = _which; @@ -42,27 +42,17 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ /* Outputs */ d_usrp->_write_oe(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); - d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); + d_usrp->write_io(d_which, (0), (CE_PIN | PDB_RF_PIN)); - /* Initialize the pin levels. */ - _enable(true); - /* Initialize the registers. */ - /* - timespec t; - t.tv_sec = 1; - t.tv_nsec = 0; - while (1) { - */ + /* Initialize the pin levels. */ + _enable(true); + /* Initialize the registers. */ d_regs->_load_register(5); - /* - nanosleep(&t, NULL); - } - */ - d_regs->_load_register(4); - d_regs->_load_register(3); - d_regs->_load_register(2); - d_regs->_load_register(1); - d_regs->_load_register(0); + d_regs->_load_register(4); + d_regs->_load_register(3); + d_regs->_load_register(2); + d_regs->_load_register(1); + d_regs->_load_register(0); } adf4350::~adf4350(){ @@ -71,12 +61,12 @@ adf4350::~adf4350(){ freq_t adf4350::_get_max_freq(void){ - return MAX_FREQ; + return MAX_FREQ; } freq_t adf4350::_get_min_freq(void){ - return MIN_FREQ; + return MIN_FREQ; } bool @@ -86,16 +76,16 @@ adf4350::_get_locked(void){ void adf4350::_enable(bool enable){ - if (enable){ /* chip enable */ + if (enable){ /* chip enable */ d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); - }else{ + }else{ d_usrp->write_io(d_which, 0, (CE_PIN | PDB_RF_PIN)); - } + } } void adf4350::_write(uint8_t addr, uint32_t data){ - data |= addr; + data |= addr; // create str from data here char s[4]; @@ -113,72 +103,76 @@ adf4350::_write(uint8_t addr, uint32_t data){ d_usrp->_write_spi(0, d_spi_enable, d_spi_format, str); nanosleep(&t, NULL); - fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data); - /* pulse latch */ + //fprintf(stderr, "Wrote to WBXNG SPI address %d with data %8x\n", addr, data); + /* pulse latch */ //d_usrp->write_io(d_which, 1, LE_PIN); //d_usrp->write_io(d_which, 0, LE_PIN); } bool adf4350::_set_freq(freq_t freq){ - /* Set the frequency by setting int, frac, mod, r, div */ - if (freq > MAX_FREQ || freq < MIN_FREQ) return false; - /* Ramp up the RF divider until the VCO is within range. */ - d_regs->d_divider_select = 0; - while (freq < MIN_VCO_FREQ){ - freq <<= 1; //double the freq - d_regs->d_divider_select++; //double the divider - } - /* Ramp up the R divider until the N divider is at least the minimum. */ - //d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq; - d_regs->d_10_bit_r_counter = 2; - uint64_t n_mod; - do{ - d_regs->d_10_bit_r_counter++; - n_mod = freq; - n_mod *= d_regs->d_10_bit_r_counter; - n_mod *= d_regs->d_mod; - n_mod /= INPUT_REF_FREQ; - /* calculate int and frac */ - d_regs->d_int = n_mod/d_regs->d_mod; - d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff); - fprintf(stderr, - "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", - freq, d_regs->d_int, d_regs->d_frac, - d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select) - ); - }while(d_regs->d_int < MIN_INT_DIV); - /* calculate the band select so PFD is under 125 KHz */ - d_regs->d_8_bit_band_select_clock_divider_value = \ - INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1; + /* Set the frequency by setting int, frac, mod, r, div */ + if (freq > MAX_FREQ || freq < MIN_FREQ) return false; + /* Ramp up the RF divider until the VCO is within range. */ + d_regs->d_divider_select = 0; + while (freq < MIN_VCO_FREQ){ + freq <<= 1; //double the freq + d_regs->d_divider_select++; //double the divider + } + /* Ramp up the R divider until the N divider is at least the minimum. */ + //d_regs->d_10_bit_r_counter = INPUT_REF_FREQ*MIN_INT_DIV/freq; + d_regs->d_10_bit_r_counter = 2; + uint64_t n_mod; + do{ + d_regs->d_10_bit_r_counter++; + n_mod = freq; + n_mod *= d_regs->d_10_bit_r_counter; + n_mod *= d_regs->d_mod; + n_mod /= INPUT_REF_FREQ; + /* calculate int and frac */ + d_regs->d_int = n_mod/d_regs->d_mod; + d_regs->d_frac = (n_mod - (freq_t)d_regs->d_int*d_regs->d_mod) & uint16_t(0xfff); + /* + fprintf(stderr, + "VCO %lu KHz, Int %u, Frac %u, Mod %u, R %u, Div %u\n", + freq, d_regs->d_int, d_regs->d_frac, + d_regs->d_mod, d_regs->d_10_bit_r_counter, (1 << d_regs->d_divider_select) + ); + */ + }while(d_regs->d_int < MIN_INT_DIV); + /* calculate the band select so PFD is under 125 KHz */ + d_regs->d_8_bit_band_select_clock_divider_value = \ + INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1; + /* fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", d_regs->d_8_bit_band_select_clock_divider_value, - INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1 + INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1 ); - d_regs->_load_register(5); - d_regs->_load_register(3); - d_regs->_load_register(1); - /* load involved registers */ - d_regs->_load_register(2); - d_regs->_load_register(4); - d_regs->_load_register(0); /* register 0 must be last */ - return true; + */ + d_regs->_load_register(5); + d_regs->_load_register(3); + d_regs->_load_register(1); + /* load involved registers */ + d_regs->_load_register(2); + d_regs->_load_register(4); + d_regs->_load_register(0); /* register 0 must be last */ + return true; } freq_t adf4350::_get_freq(void){ - /* Calculate the freq from int, frac, mod, ref, r, div: - * freq = (int + frac/mod) * (ref/r) - * Keep precision by doing multiplies first: - * freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div) - */ - uint64_t temp; - temp = d_regs->d_int; - temp *= d_regs->d_mod; - temp += d_regs->d_frac; - temp *= INPUT_REF_FREQ; - temp /= d_regs->d_mod; - temp /= d_regs->d_10_bit_r_counter; - temp /= (1 << d_regs->d_divider_select); - return temp; + /* Calculate the freq from int, frac, mod, ref, r, div: + * freq = (int + frac/mod) * (ref/r) + * Keep precision by doing multiplies first: + * freq = (((((((int)*mod) + frac)*ref)/mod)/r)/div) + */ + uint64_t temp; + temp = d_regs->d_int; + temp *= d_regs->d_mod; + temp += d_regs->d_frac; + temp *= INPUT_REF_FREQ; + temp /= d_regs->d_mod; + temp /= d_regs->d_10_bit_r_counter; + temp /= (1 << d_regs->d_divider_select); + return temp; } -- cgit From 48e2124c1eac6806d3259964d80348ad1d64214c Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Tue, 22 Sep 2009 14:07:42 -0700 Subject: Enabled RX Baseband --- usrp/host/lib/db_wbxng.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'usrp') diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index 8a03cfbac..aa61012e7 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -29,6 +29,7 @@ #define ENABLE_33 (1 << 6) // enables 3.3V supply #define RX_TXN (1 << 5) // Tx only: T/R antenna switch for TX/RX port #define RX2_RX1N (1 << 5) // Rx only: antenna switch between RX2 and TX/RX port +#define RXBB_EN (1 << 4) #define TXMOD_EN (1 << 4) #define PLL_CE (1 << 3) #define PLL_PDBRF (1 << 2) @@ -421,8 +422,9 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); - usrp()->_write_oe(d_which, (RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5)); - usrp()->write_io(d_which, (power_on()|RX2_RX1N|ENABLE_33|ENABLE_5), (RX2_RX1N|ENABLE_33|ENABLE_5)); + usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5)); + fprintf(stderr,"Setting WBXNG RXBB on"); // set up for RX on TX/RX port select_rx_antenna("TX/RX"); -- cgit From bf0bbd9daf5360b5d1fb5f36dcb968d6bcd0fd60 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Thu, 24 Sep 2009 16:12:26 -0700 Subject: Integrated gain control for TX and RX of wbxng --- usrp/host/include/usrp/db_wbxng.h | 1 + usrp/host/lib/db_wbxng.cc | 69 +++++++++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 21 deletions(-) (limited to 'usrp') diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h index 0d03e4297..fb5c8da71 100644 --- a/usrp/host/include/usrp/db_wbxng.h +++ b/usrp/host/include/usrp/db_wbxng.h @@ -95,6 +95,7 @@ class wbxng_base_rx : public wbxng_base { protected: void shutdown(); + bool _set_attn(float attn); public: wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0); diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index aa61012e7..0dd8b0d38 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -36,6 +36,10 @@ #define PLL_MUXOUT (1 << 1) #define PLL_LOCK_DETECT (1 << 0) +// RX Attenuator constants +#define ATTN_SHIFT 8 +#define ATTN_MASK (63 << ATTN_SHIFT) + wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on) : db_base(_usrp, which), d_power_on(_power_on) { @@ -243,7 +247,6 @@ wbxng_base::set_freq(double freq) bool wbxng_base::_set_pga(float pga_gain) { - /* if(d_which == 0) { usrp()->set_pga(0, pga_gain); usrp()->set_pga(1, pga_gain); @@ -252,7 +255,6 @@ wbxng_base::_set_pga(float pga_gain) usrp()->set_pga(2, pga_gain); usrp()->set_pga(3, pga_gain); } - */ return true; } @@ -304,7 +306,7 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) fprintf(stderr,"Setting WBXNG TXMOD on"); //set_lo_offset(4e6); - //set_gain((gain_min() + gain_max()) / 2.0); // initialize gain + set_gain((gain_min() + gain_max()) / 2.0); // initialize gain } wbxng_base_tx::~wbxng_base_tx() @@ -380,7 +382,7 @@ wbxng_base_tx::gain_min() float wbxng_base_tx::gain_max() { - return usrp()->pga_max(); + return usrp()->pga_max() + 25.0; } float @@ -398,7 +400,35 @@ wbxng_base_tx::set_gain(float gain) @param gain: gain in decibels @returns True/False */ - return _set_pga(usrp()->pga_max()); + + // 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 = 0.7; + V_mingain = 1.4; + V_fullscale = 3.3; + dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale; + + fprintf(stderr, "TXGAIN: %f dB, Dac Code: %d, Voltage: %f\n", gain, int(dac_value), float((dac_value/4096.0)*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))); } @@ -422,8 +452,8 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) d_common = new adf4350(_usrp, d_which, d_spi_enable); - usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5)); - usrp()->write_io(d_which, (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5)); + usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); + usrp()->write_io(d_which, (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); fprintf(stderr,"Setting WBXNG RXBB on"); // set up for RX on TX/RX port @@ -540,12 +570,10 @@ wbxng_base_rx::set_gain(float gain) @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(); @@ -559,17 +587,16 @@ wbxng_base_rx::set_gain(float gain) 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 _set_attn(maxgain-agc_gain) && _set_pga(int(pga_gain)); +} - return (usrp()->write_aux_dac(d_which, 0, int(dac_value)) - && _set_pga(int(pga_gain))); - */ - return false; +bool +wbxng_base_rx::_set_attn(float attn) +{ + int attn_code = int(floor(attn/0.5)); + unsigned int iobits = (~attn_code) << ATTN_SHIFT; + fprintf(stderr, "Attenuation: %f dB, Code: %d, IO Bits %x, Mask: %x \n", attn, attn_code, iobits & ATTN_MASK, ATTN_MASK); + return usrp()->write_io(d_which, iobits, ATTN_MASK); } // ---------------------------------------------------------------- @@ -613,7 +640,7 @@ db_wbxng_rx::gain_min() float db_wbxng_rx::gain_max() { - return usrp()->pga_max()+70; + return usrp()->pga_max()+30.5; } float @@ -626,7 +653,7 @@ db_wbxng_rx::gain_db_per_step() bool db_wbxng_rx::i_and_q_swapped() { - return true; + return false; } /* -- cgit From 69caa7dce5a58b39614b1aba99c2dd71b38af322 Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Tue, 6 Oct 2009 17:50:59 -0700 Subject: Clean up for work-in-progress Copyright updates Trailing whitespace cleanup Move private headers out of install Use standard include guards Code cleanup --- usrp/host/apps/burn-db-eeprom | 18 +- usrp/host/include/usrp/Makefile.am | 14 +- usrp/host/include/usrp/db_wbxng.h | 37 ++-- usrp/host/include/usrp/db_wbxng_adf4350.h | 37 ---- usrp/host/include/usrp/db_wbxng_adf4350_regs.h | 65 ------- usrp/host/lib/Makefile.am | 12 +- usrp/host/lib/db_boards.cc | 14 +- usrp/host/lib/db_wbxng.cc | 227 ++++--------------------- usrp/host/lib/db_wbxng_adf4350.cc | 73 +++++--- usrp/host/lib/db_wbxng_adf4350.h | 53 ++++++ usrp/host/lib/db_wbxng_adf4350_regs.cc | 9 +- usrp/host/lib/db_wbxng_adf4350_regs.h | 64 +++++++ usrp/host/lib/usrp_dbid.dat | 8 +- 13 files changed, 241 insertions(+), 390 deletions(-) delete mode 100644 usrp/host/include/usrp/db_wbxng_adf4350.h delete mode 100644 usrp/host/include/usrp/db_wbxng_adf4350_regs.h create mode 100644 usrp/host/lib/db_wbxng_adf4350.h create mode 100644 usrp/host/lib/db_wbxng_adf4350_regs.h (limited to 'usrp') diff --git a/usrp/host/apps/burn-db-eeprom b/usrp/host/apps/burn-db-eeprom index 195c4e897..7ff1e9736 100755 --- a/usrp/host/apps/burn-db-eeprom +++ b/usrp/host/apps/burn-db-eeprom @@ -1,24 +1,24 @@ #!/usr/bin/env python # -# Copyright 2005,2007 Free Software Foundation, Inc. -# +# Copyright 2005,2007,2009 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 version 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. -# +# from usrpm.usrp_prims import * from optparse import OptionParser @@ -105,11 +105,11 @@ def init_eeprom(u, slot_name, force, dbid, oe): if not e: print "%s: no d'board, skipped" % (slot_name,) return True - + if not force and (sum (map (ord, e)) & 0xff) == 0 and ord (e[0]) == 0xDB: print "%s: already initialized, skipped" % (slot_name,) return True - + if not write_dboard_eeprom (u, i2c_addr, dbid, oe): print "%s: failed to write d'board EEPROM" % (slot_name,) return False @@ -169,4 +169,4 @@ and at least one side using -A and/or -B.""" if __name__ == "__main__": main () - + diff --git a/usrp/host/include/usrp/Makefile.am b/usrp/host/include/usrp/Makefile.am index 7c868e061..cfce51443 100644 --- a/usrp/host/include/usrp/Makefile.am +++ b/usrp/host/include/usrp/Makefile.am @@ -1,23 +1,23 @@ # # Copyright 2009 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 version 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 $(top_srcdir)/Makefile.common @@ -32,9 +32,7 @@ usrpinclude_HEADERS = \ db_flexrf.h \ db_flexrf_mimo.h \ db_tv_rx.h \ - db_tv_rx_mimo.h \ - db_wbxng_adf4350.h \ - db_wbxng_adf4350_regs.h \ + db_tv_rx_mimo.h \ db_wbxng.h \ db_xcvr2450.h \ libusb_types.h \ diff --git a/usrp/host/include/usrp/db_wbxng.h b/usrp/host/include/usrp/db_wbxng.h index fb5c8da71..2158face2 100644 --- a/usrp/host/include/usrp/db_wbxng.h +++ b/usrp/host/include/usrp/db_wbxng.h @@ -1,33 +1,30 @@ /* -*- c++ -*- */ // -// Copyright 2008,2009 Free Software Foundation, Inc. -// +// Copyright 2009 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. -#ifndef DB_WBXNG_H -#define DB_WBXNG_H +#ifndef INCLUDED_DB_WBXNG_H +#define INCLUDED_DB_WBXNG_H #include <usrp/db_base.h> #include <cmath> -//debug_using_gui = true // Must be set to True or False -#define debug_using_gui false // Must be set to True or False - class adf4350; class wbxng_base : public db_base @@ -43,11 +40,6 @@ public: double freq_max(); protected: - void _write_all(int R, int control, int N); - void _write_control(int control); - void _write_R(int R); - void _write_N(int N); - void _write_it(int v); bool _lock_detect(); //virtual bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq); @@ -80,8 +72,6 @@ public: wbxng_base_tx(usrp_basic_sptr usrp, int which, int _power_on=0); ~wbxng_base_tx(); - //*** TODO *** Fix comment - // All RFX tx d'boards have fixed gain float gain_min(); float gain_max(); float gain_db_per_step(); @@ -100,12 +90,11 @@ protected: public: wbxng_base_rx(usrp_basic_sptr usrp, int which, int _power_on=0); ~wbxng_base_rx(); - + bool set_auto_tr(bool on); bool select_rx_antenna(int which_antenna); bool select_rx_antenna(const std::string &which_antenna); bool set_gain(float gain); - }; // ---------------------------------------------------------------- @@ -115,9 +104,6 @@ class db_wbxng_tx : public wbxng_base_tx public: db_wbxng_tx(usrp_basic_sptr usrp, int which); ~db_wbxng_tx(); - - // Wrapper calls to d_common functions - //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq); }; class db_wbxng_rx : public wbxng_base_rx @@ -125,14 +111,11 @@ class db_wbxng_rx : public wbxng_base_rx public: db_wbxng_rx(usrp_basic_sptr usrp, int which); ~db_wbxng_rx(); - + float gain_min(); float gain_max(); float gain_db_per_step(); bool i_and_q_swapped(); - - //bool _compute_regs(double freq, int &retR, int &retcontrol, int &retN, double &retfreq); }; - -#endif +#endif /* INCLUDED_DB_WBXNG_H */ diff --git a/usrp/host/include/usrp/db_wbxng_adf4350.h b/usrp/host/include/usrp/db_wbxng_adf4350.h deleted file mode 100644 index d7b8dd99b..000000000 --- a/usrp/host/include/usrp/db_wbxng_adf4350.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2009 Ettus Research LLC - */ - -#ifndef ADF4350_H -#define ADF4350_H - -#include <usrp/db_wbxng_adf4350_regs.h> -#include <usrp/db_base.h> -#include <stdint.h> - -typedef uint64_t freq_t; -class adf4350_regs; - -class adf4350 -{ -public: - adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable); - ~adf4350(); - void _update(); - bool _get_locked(); - void _enable(bool enable); - void _write(uint8_t addr, uint32_t data); - bool _set_freq(freq_t freq); - freq_t _get_freq(); - freq_t _get_max_freq(); - freq_t _get_min_freq(); - -protected: - usrp_basic_sptr d_usrp; - int d_which; - int d_spi_enable; - int d_spi_format; - adf4350_regs *d_regs; -}; - -#endif /* ADF4350_H */ diff --git a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h b/usrp/host/include/usrp/db_wbxng_adf4350_regs.h deleted file mode 100644 index 6a5b77a4b..000000000 --- a/usrp/host/include/usrp/db_wbxng_adf4350_regs.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2009 Ettus Research LLC - */ - -#ifndef ADF4350_REGS_H -#define ADF4350_REGS_H - -#include <usrp/db_wbxng_adf4350.h> -#include <usrp/db_base.h> -#include <stdint.h> - -class adf4350; - -class adf4350_regs -{ -public: - adf4350_regs(adf4350* _adf4350); - ~adf4350_regs(); - - adf4350* d_adf4350; - - uint32_t _reg_shift(uint32_t data, uint32_t shift); - void _load_register(uint8_t addr); - - /* reg 0 */ - uint16_t d_int; - uint16_t d_frac; - /* reg 1 */ - static const uint8_t s_prescaler; - static const uint16_t s_phase; - uint16_t d_mod; - /* reg 2 */ - static const uint8_t s_low_noise_and_low_spur_modes; - static const uint8_t s_muxout; - static const uint8_t s_reference_doubler; - static const uint8_t s_rdiv2; - uint16_t d_10_bit_r_counter; - static const uint8_t s_double_buff; - static const uint8_t s_charge_pump_setting; - static const uint8_t s_ldf; - static const uint8_t s_ldp; - static const uint8_t s_pd_polarity; - static const uint8_t s_power_down; - static const uint8_t s_cp_three_state; - static const uint8_t s_counter_reset; - /* reg 3 */ - static const uint8_t s_csr; - static const uint8_t s_clk_div_mode; - static const uint16_t s_12_bit_clock_divider_value; - /* reg 4 */ - static const uint8_t s_feedback_select; - uint8_t d_divider_select; - uint8_t d_8_bit_band_select_clock_divider_value; - static const uint8_t s_vco_power_down; - static const uint8_t s_mtld; - static const uint8_t s_aux_output_select; - static const uint8_t s_aux_output_enable; - static const uint8_t s_aux_output_power; - static const uint8_t s_rf_output_enable; - static const uint8_t s_output_power; - /* reg 5 */ - static const uint8_t s_ld_pin_mode; -}; - -#endif /* ADF4350_REGS_H */ diff --git a/usrp/host/lib/Makefile.am b/usrp/host/lib/Makefile.am index 13f25d69b..72312ebbb 100644 --- a/usrp/host/lib/Makefile.am +++ b/usrp/host/lib/Makefile.am @@ -1,22 +1,22 @@ # # USRP - Universal Software Radio Peripheral -# +# # Copyright (C) 2003,2004,2006,2007,2008,2009 Free Software Foundation, Inc. -# +# # This program 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 version 3 of the License, or # (at your option) any later version. -# +# # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA -# +# include $(top_srcdir)/Makefile.common @@ -168,6 +168,8 @@ noinst_HEADERS = \ db_base_impl.h \ db_boards.h \ db_util.h \ + db_wbxng_adf4350.h \ + db_wbxng_adf4350_regs.h \ fusb.h \ fusb_darwin.h \ fusb_generic.h \ diff --git a/usrp/host/lib/db_boards.cc b/usrp/host/lib/db_boards.cc index 53304bd1a..590d8132d 100644 --- a/usrp/host/lib/db_boards.cc +++ b/usrp/host/lib/db_boards.cc @@ -1,19 +1,19 @@ /* -*- c++ -*- */ // // Copyright 2008,2009 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, @@ -64,7 +64,7 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side) db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 1))); db.push_back(db_base_sptr(new db_lf_rx(usrp, which_side, 2))); break; - + case(USRP_DBID_DBS_RX): db.push_back(db_base_sptr(new db_dbs_rx(usrp, which_side))); break; @@ -185,7 +185,7 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side) case(USRP_DBID_XCVR2450_RX): db.push_back(db_base_sptr(new db_xcvr2450_rx(usrp, which_side))); break; - + #if 0 // FIXME wbx doesn't compile case(USRP_DBID_WBX_LO_TX): db.push_back(db_base_sptr(new db_wbx_lo_tx(usrp, which_side))); @@ -218,7 +218,7 @@ instantiate_dbs(int dbid, usrp_basic_sptr usrp, int which_side) db.push_back(db_base_sptr(new db_basic_rx(usrp, which_side, 1))); } break; - + case(-2): default: if (boost::dynamic_pointer_cast<usrp_basic_tx>(usrp)){ diff --git a/usrp/host/lib/db_wbxng.cc b/usrp/host/lib/db_wbxng.cc index 0dd8b0d38..c23fc47ed 100644 --- a/usrp/host/lib/db_wbxng.cc +++ b/usrp/host/lib/db_wbxng.cc @@ -1,25 +1,25 @@ // -// Copyright 2008 Free Software Foundation, Inc. -// +// Copyright 2008,2009 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 <usrp/db_wbxng.h> -#include <usrp/db_wbxng_adf4350.h> +#include "db_wbxng_adf4350.h" #include <db_base_impl.h> #include <stdio.h> @@ -61,143 +61,8 @@ wbxng_base::wbxng_base(usrp_basic_sptr _usrp, int which, int _power_on) wbxng_base::~wbxng_base() { - delete d_common; -} - -void -wbxng_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 -wbxng_base::_write_control(int control) -{ - //_write_it((control & ~0x3) | 0); -} - -void -wbxng_base::_write_R(int R) -{ - //_write_it((R & ~0x3) | 1); -} - -void -wbxng_base::_write_N(int N) -{ - //_write_it((N & ~0x3) | 2); -} - -void -wbxng_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 -wbxng_base::_lock_detect() -{ - /* - @returns: the value of the VCO/PLL lock detect bit. - @rtype: 0 or 1 - */ - - if(d_common->_get_locked()){ - return true; - } - else { // Give it a second chance - return false; - /* - // 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; - } - */ - } - - throw std::runtime_error("_lock_detect called from wbxng_base\n"); -} - -/* -bool -wbxng_base::_compute_regs(double freq, int &retR, int &retcontrol, - int &retN, double &retfreq) -{ - **COMMENT** - 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. - **COMMENT** - - //raise NotImplementedError; - throw std::runtime_error("_compute_regs called from wbxng_base\n"); -} -*/ - -int -wbxng_base::_compute_control_reg() -{ - throw std::runtime_error("_compute_control_reg called from wbxng_base\n"); - //return d_common->_compute_control_reg(); -} - -int -wbxng_base::_refclk_divisor() -{ - throw std::runtime_error("_refclk_divisor called from wbxng_base\n"); - //return d_common->_refclk_divisor(); -} - -double -wbxng_base::_refclk_freq() -{ - throw std::runtime_error("_refclk_divisor called from wbxng_base\n"); - // *** TODO *** Magic Number 64e6? - //return 64e6/_refclk_divisor(); + if (d_common) + delete d_common; } struct freq_result_t @@ -220,27 +85,17 @@ wbxng_base::set_freq(double freq) t.tv_nsec = 10000000; nanosleep(&t, NULL); - fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", + fprintf(stderr,"Setting WBXNG frequency, requested %d, obtained %f, lock_detect %d\n", int_freq, freq_result, _lock_detect()); + // FIXME // 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; } @@ -263,7 +118,7 @@ wbxng_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; @@ -290,7 +145,7 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _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; } @@ -299,11 +154,11 @@ wbxng_base_tx::wbxng_base_tx(usrp_basic_sptr _usrp, int which, int _power_on) } d_common = new adf4350(_usrp, d_which, d_spi_enable); - - // power up the transmit side, but don't enable the mixer + + // FIXME: power up the transmit side, but don't enable the mixer usrp()->_write_oe(d_which,(RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5)); usrp()->write_io(d_which, (power_on()|RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5), (RX_TXN|TXMOD_EN|ENABLE_33|ENABLE_5)); - fprintf(stderr,"Setting WBXNG TXMOD on"); + fprintf(stderr,"Setting WBXNG TXMOD on"); //set_lo_offset(4e6); set_gain((gain_min() + gain_max()) / 2.0); // initialize gain @@ -329,7 +184,7 @@ wbxng_base_tx::shutdown() // Power down VCO/PLL d_common->_enable(false); - + /* _write_control(_compute_control_reg()); */ @@ -396,11 +251,11 @@ wbxng_base_tx::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())); @@ -418,7 +273,7 @@ wbxng_base_tx::set_gain(float gain) pga_gain = 0; agc_gain = gain; } - + V_maxgain = 0.7; V_mingain = 1.4; V_fullscale = 3.3; @@ -454,14 +309,14 @@ wbxng_base_rx::wbxng_base_rx(usrp_basic_sptr _usrp, int which, int _power_on) usrp()->_write_oe(d_which, (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); usrp()->write_io(d_which, (power_on()|RX2_RX1N|RXBB_EN|ENABLE_33|ENABLE_5), (RX2_RX1N|RXBB_EN|ATTN_MASK|ENABLE_33|ENABLE_5)); - fprintf(stderr,"Setting WBXNG RXBB on"); - + fprintf(stderr,"Setting WBXNG RXBB on"); + // set up for RX on TX/RX port select_rx_antenna("TX/RX"); - + bypass_adc_buffers(true); - /* + /* set_lo_offset(-4e6); */ } @@ -532,7 +387,6 @@ wbxng_base_rx::select_rx_antenna(int which_antenna) } else { return false; - // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n"); } return true; } @@ -545,7 +399,7 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna) @param which_antenna: either 'TX/RX' or 'RX2' */ - + if(which_antenna == "TX/RX") { usrp()->write_io(d_which, 0, RX2_RX1N); } @@ -553,10 +407,9 @@ wbxng_base_rx::select_rx_antenna(const std::string &which_antenna) 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; } @@ -565,11 +418,11 @@ wbxng_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())); @@ -586,7 +439,7 @@ wbxng_base_rx::set_gain(float gain) pga_gain = 0; agc_gain = gain; } - + return _set_attn(maxgain-agc_gain) && _set_pga(int(pga_gain)); } @@ -610,17 +463,6 @@ db_wbxng_tx::~db_wbxng_tx() { } -/* -bool -db_wbxng_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_wbxng_rx::db_wbxng_rx(usrp_basic_sptr usrp, int which) : wbxng_base_rx(usrp, which) { @@ -655,14 +497,3 @@ db_wbxng_rx::i_and_q_swapped() { return false; } - -/* -bool -db_wbxng_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); -} -*/ - diff --git a/usrp/host/lib/db_wbxng_adf4350.cc b/usrp/host/lib/db_wbxng_adf4350.cc index 73485d90c..af4eac573 100644 --- a/usrp/host/lib/db_wbxng_adf4350.cc +++ b/usrp/host/lib/db_wbxng_adf4350.cc @@ -1,21 +1,33 @@ -/* - * Copyright 2009 Ettus Research LLC - */ +// +// Copyright 2009 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. #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <usrp/db_wbxng_adf4350.h> -#include <usrp/db_wbxng_adf4350_regs.h> +#include "db_wbxng_adf4350.h" #include <db_base_impl.h> #include <stdio.h> -//#include "io.h" -//#include "spi.h" #define INPUT_REF_FREQ FREQ_C(64e6) #define DIV_ROUND(num, denom) (((num) + ((denom)/2))/(denom)) -//#define FREQ_C(freq) ((uint64_t)DIV_ROUND(freq, (uint64_t)1000)) #define FREQ_C(freq) uint64_t(freq) #define INPUT_REF_FREQ_2X (2*INPUT_REF_FREQ) /* input ref freq with doubler turned on */ #define MIN_INT_DIV uint16_t(23) /* minimum int divider, prescaler 4/5 only */ @@ -30,7 +42,8 @@ #define MUX_PIN (1 << 1) #define LD_PIN (1 << 0) -adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ +adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable) +{ /* Initialize the pin directions. */ d_usrp = _usrp; @@ -55,27 +68,32 @@ adf4350::adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable){ d_regs->_load_register(0); } -adf4350::~adf4350(){ +adf4350::~adf4350() +{ delete d_regs; } -freq_t -adf4350::_get_max_freq(void){ +freq_t +adf4350::_get_max_freq(void) +{ return MAX_FREQ; } -freq_t -adf4350::_get_min_freq(void){ +freq_t +adf4350::_get_min_freq(void) +{ return MIN_FREQ; } -bool -adf4350::_get_locked(void){ +bool +adf4350::_get_locked(void) +{ return d_usrp->read_io(d_which) & LD_PIN; } -void -adf4350::_enable(bool enable){ +void +adf4350::_enable(bool enable) +{ if (enable){ /* chip enable */ d_usrp->write_io(d_which, (CE_PIN | PDB_RF_PIN), (CE_PIN | PDB_RF_PIN)); }else{ @@ -83,8 +101,9 @@ adf4350::_enable(bool enable){ } } -void -adf4350::_write(uint8_t addr, uint32_t data){ +void +adf4350::_write(uint8_t addr, uint32_t data) +{ data |= addr; // create str from data here @@ -109,8 +128,9 @@ adf4350::_write(uint8_t addr, uint32_t data){ //d_usrp->write_io(d_which, 0, LE_PIN); } -bool -adf4350::_set_freq(freq_t freq){ +bool +adf4350::_set_freq(freq_t freq) +{ /* Set the frequency by setting int, frac, mod, r, div */ if (freq > MAX_FREQ || freq < MIN_FREQ) return false; /* Ramp up the RF divider until the VCO is within range. */ @@ -144,8 +164,8 @@ adf4350::_set_freq(freq_t freq){ d_regs->d_8_bit_band_select_clock_divider_value = \ INPUT_REF_FREQ/(FREQ_C(30e3)*d_regs->d_10_bit_r_counter) + 1; /* - fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", - d_regs->d_8_bit_band_select_clock_divider_value, + fprintf(stderr, "Band Selection: Div %u, Freq %lu\n", + d_regs->d_8_bit_band_select_clock_divider_value, INPUT_REF_FREQ/(d_regs->d_8_bit_band_select_clock_divider_value * d_regs->d_10_bit_r_counter) + 1 ); */ @@ -159,8 +179,9 @@ adf4350::_set_freq(freq_t freq){ return true; } -freq_t -adf4350::_get_freq(void){ +freq_t +adf4350::_get_freq(void) +{ /* Calculate the freq from int, frac, mod, ref, r, div: * freq = (int + frac/mod) * (ref/r) * Keep precision by doing multiplies first: diff --git a/usrp/host/lib/db_wbxng_adf4350.h b/usrp/host/lib/db_wbxng_adf4350.h new file mode 100644 index 000000000..2b0783c20 --- /dev/null +++ b/usrp/host/lib/db_wbxng_adf4350.h @@ -0,0 +1,53 @@ +// +// Copyright 2009 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. + +#ifndef INCLUDED_ADF4350_H +#define INCLUDED_ADF4350_H + +#include "db_wbxng_adf4350_regs.h" +#include <usrp/db_base.h> +#include <stdint.h> + +typedef uint64_t freq_t; +class adf4350_regs; + +class adf4350 +{ +public: + adf4350(usrp_basic_sptr _usrp, int _which, int _spi_enable); + ~adf4350(); + void _update(); + bool _get_locked(); + void _enable(bool enable); + void _write(uint8_t addr, uint32_t data); + bool _set_freq(freq_t freq); + freq_t _get_freq(); + freq_t _get_max_freq(); + freq_t _get_min_freq(); + +protected: + usrp_basic_sptr d_usrp; + int d_which; + int d_spi_enable; + int d_spi_format; + adf4350_regs *d_regs; +}; + +#endif /* INCLUDED_ADF4350_H */ diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.cc b/usrp/host/lib/db_wbxng_adf4350_regs.cc index 2c1660f56..11dcf8816 100644 --- a/usrp/host/lib/db_wbxng_adf4350_regs.cc +++ b/usrp/host/lib/db_wbxng_adf4350_regs.cc @@ -2,8 +2,9 @@ * Copyright 2009 Ettus Research LLC */ -#include <usrp/db_wbxng_adf4350_regs.h> -#include <usrp/db_wbxng_adf4350.h> +#include "db_wbxng_adf4350_regs.h" +#include "db_wbxng_adf4350.h" + //#include "cal_div.h" /* reg 0 */ @@ -59,12 +60,12 @@ adf4350_regs::adf4350_regs(adf4350* _adf4350){ adf4350_regs::~adf4350_regs(void){ } -uint32_t +uint32_t adf4350_regs::_reg_shift(uint32_t data, uint32_t shift){ return data << shift; } -void +void adf4350_regs::_load_register(uint8_t addr){ uint32_t data; switch (addr){ diff --git a/usrp/host/lib/db_wbxng_adf4350_regs.h b/usrp/host/lib/db_wbxng_adf4350_regs.h new file mode 100644 index 000000000..dc941ee87 --- /dev/null +++ b/usrp/host/lib/db_wbxng_adf4350_regs.h @@ -0,0 +1,64 @@ +/* + * Copyright 2009 Ettus Research LLC + */ + +#ifndef ADF4350_REGS_H +#define ADF4350_REGS_H + +#include <usrp/db_base.h> +#include <stdint.h> + +class adf4350; + +class adf4350_regs +{ +public: + adf4350_regs(adf4350* _adf4350); + ~adf4350_regs(); + + adf4350* d_adf4350; + + uint32_t _reg_shift(uint32_t data, uint32_t shift); + void _load_register(uint8_t addr); + + /* reg 0 */ + uint16_t d_int; + uint16_t d_frac; + /* reg 1 */ + static const uint8_t s_prescaler; + static const uint16_t s_phase; + uint16_t d_mod; + /* reg 2 */ + static const uint8_t s_low_noise_and_low_spur_modes; + static const uint8_t s_muxout; + static const uint8_t s_reference_doubler; + static const uint8_t s_rdiv2; + uint16_t d_10_bit_r_counter; + static const uint8_t s_double_buff; + static const uint8_t s_charge_pump_setting; + static const uint8_t s_ldf; + static const uint8_t s_ldp; + static const uint8_t s_pd_polarity; + static const uint8_t s_power_down; + static const uint8_t s_cp_three_state; + static const uint8_t s_counter_reset; + /* reg 3 */ + static const uint8_t s_csr; + static const uint8_t s_clk_div_mode; + static const uint16_t s_12_bit_clock_divider_value; + /* reg 4 */ + static const uint8_t s_feedback_select; + uint8_t d_divider_select; + uint8_t d_8_bit_band_select_clock_divider_value; + static const uint8_t s_vco_power_down; + static const uint8_t s_mtld; + static const uint8_t s_aux_output_select; + static const uint8_t s_aux_output_enable; + static const uint8_t s_aux_output_power; + static const uint8_t s_rf_output_enable; + static const uint8_t s_output_power; + /* reg 5 */ + static const uint8_t s_ld_pin_mode; +}; + +#endif /* ADF4350_REGS_H */ diff --git a/usrp/host/lib/usrp_dbid.dat b/usrp/host/lib/usrp_dbid.dat index 1df28802e..7d1e18714 100644 --- a/usrp/host/lib/usrp_dbid.dat +++ b/usrp/host/lib/usrp_dbid.dat @@ -1,18 +1,18 @@ # # Copyright 2005,2009 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 version 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 this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- cgit