X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=usrp%2Fhost%2Flib%2Flegacy%2Fusrp_standard.h;fp=usrp%2Fhost%2Flib%2Flegacy%2Fusrp_standard.h;h=734fff4b5bcffb716a07bbb3b818a4bb0bac5cb3;hb=ea29b08aeb54227e6628f655ccfdb96fe4d8c378;hp=0000000000000000000000000000000000000000;hpb=09a1e803a9e6587c78d20cdf16891e5295874668;p=debian%2Fgnuradio diff --git a/usrp/host/lib/legacy/usrp_standard.h b/usrp/host/lib/legacy/usrp_standard.h new file mode 100644 index 00000000..734fff4b --- /dev/null +++ b/usrp/host/lib/legacy/usrp_standard.h @@ -0,0 +1,452 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either 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. + */ + +#ifndef INCLUDED_USRP_STANDARD_H +#define INCLUDED_USRP_STANDARD_H + +#include +#include +#include + +class usrp_standard_tx; +class usrp_standard_rx; + +typedef boost::shared_ptr usrp_standard_tx_sptr; +typedef boost::shared_ptr usrp_standard_rx_sptr; + +/*! + * \ingroup usrp + */ +class usrp_standard_common +{ + int d_fpga_caps; // capability register val + +protected: + usrp_standard_common(usrp_basic *parent); + +public: + /*! + *\brief does the FPGA implement the final Rx half-band filter? + * If it doesn't, the maximum decimation factor with proper gain + * is 1/2 of what it would otherwise be. + */ + bool has_rx_halfband() const; + + /*! + * \brief number of digital downconverters implemented in the FPGA + * This will be 0, 1, 2 or 4. + */ + int nddcs() const; + + /*! + *\brief does the FPGA implement the initial Tx half-band filter? + */ + bool has_tx_halfband() const; + + /*! + * \brief number of digital upconverters implemented in the FPGA + * This will be 0, 1, or 2. + */ + int nducs() const; + + /*! + * \brief Calculate the frequency to use for setting the digital up or down converter. + * + * \param target_freq is the desired RF frequency (Hz). + * \param baseband_freq is the RF frequency that corresponds to DC in the IF coming from the d'board. + * \param fs is the sampling frequency. + * \param[out] dxc_freq the frequency to program into the DDC (or DUC). + * \param[out] inverted is true if we're operating in an inverted Nyquist zone. + */ + static void calc_dxc_freq(double target_freq, double baseband_freq, double fs, + double *dxc_freq, bool *inverted); +}; + +/*! + * \brief The C++ interface the receive side of the USRP + * \ingroup usrp + * + * This is the recommended interface to USRP receive functionality + * for applications that use the USRP but not GNU Radio. + */ +class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common +{ + private: + static const int MAX_CHAN = 4; + unsigned int d_decim_rate; + int d_nchan; + int d_sw_mux; + int d_hw_mux; + double d_rx_freq[MAX_CHAN]; + + protected: + usrp_standard_rx (int which_board, + unsigned int decim_rate, + int nchan = 1, + int mux = -1, + int mode = 0, + int fusb_block_size = 0, + int fusb_nblocks = 0, + const std::string fpga_filename = "", + const std::string firmware_filename = "" + ); // throws if trouble + + bool write_hw_mux_reg (); + + public: + + enum { + FPGA_MODE_NORMAL = 0x00, + FPGA_MODE_LOOPBACK = 0x01, + FPGA_MODE_COUNTING = 0x02, + FPGA_MODE_COUNTING_32BIT = 0x04 + }; + + ~usrp_standard_rx (); + + /*! + * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble + * + * \param which_board Which USRP board on usb (not particularly useful; use 0) + * \param decim_rate decimation factor + * \param nchan number of channels + * \param mux Rx mux setting, \sa set_mux + * \param mode mode + * \param fusb_block_size fast usb xfer block size. Must be a multiple of 512. + * Use zero for a reasonable default. + * \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default. + * \param fpga_filename Name of rbf file to load + * \param firmware_filename Name of ihx file to load + */ + static usrp_standard_rx_sptr make(int which_board, + unsigned int decim_rate, + int nchan = 1, + int mux = -1, + int mode = 0, + int fusb_block_size = 0, + int fusb_nblocks = 0, + const std::string fpga_filename = "", + const std::string firmware_filename = "" + ); + /*! + * \brief Set decimator rate. \p rate MUST BE EVEN and in [8, 256]. + * + * The final complex sample rate across the USB is + * adc_freq () / decim_rate () * nchannels () + */ + bool set_decim_rate (unsigned int rate); + + /*! + * \brief Set number of active channels. \p nchannels must be 1, 2 or 4. + * + * The final complex sample rate across the USB is + * adc_freq () / decim_rate () * nchannels () + */ + bool set_nchannels (int nchannels); + + /*! + * \brief Set input mux configuration. + * + * This determines which ADC (or constant zero) is connected to + * each DDC input. There are 4 DDCs. Each has two inputs. + * + *
+   * Mux value:
+   *
+   *    3                   2                   1                       
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-------+-------+-------+-------+-------+-------+-------+-------+
+   * |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
+   * +-------+-------+-------+-------+-------+-------+-------+-------+
+   *
+   * Each 4-bit I field is either 0,1,2,3
+   * Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
+   * All Q's must be 0xf or none of them may be 0xf
+   * 
+ */ + bool set_mux (int mux); + + /*! + * Determine the appropriate Rx mux value as a function of the subdevice choosen + * and the characteristics of the respective daughterboard. + */ + int determine_rx_mux_value(const usrp_subdev_spec &ss); + int determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b); + + /*! + * \brief set the frequency of the digital down converter. + * + * \p channel must be in the range [0,3]. \p freq is the center + * frequency in Hz. \p freq may be either negative or postive. + * The frequency specified is quantized. Use rx_freq to retrieve + * the actual value used. + */ + bool set_rx_freq (int channel, double freq); + + /*! + * \brief set fpga mode + */ + bool set_fpga_mode (int mode); + + /*! + * \brief Set the digital down converter phase register. + * + * \param channel which ddc channel [0, 3] + * \param phase 32-bit integer phase value. + */ + bool set_ddc_phase(int channel, int phase); + + /*! + * \brief Specify Rx data format. + * + * \param format format specifier + * + * Rx data format control register + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-----------------------------------------+-+-+---------+-------+ + * | Reserved (Must be zero) |B|Q| WIDTH | SHIFT | + * +-----------------------------------------+-+-+---------+-------+ + * + * SHIFT specifies arithmetic right shift [0, 15] + * WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid) + * Q if set deliver both I & Q, else just I + * B if set bypass half-band filter. + * + * Right now the acceptable values are: + * + * B Q WIDTH SHIFT + * 0 1 16 0 + * 0 1 8 8 + * + * More valid combos to come. + * + * Default value is 0x00000300 16-bits, 0 shift, deliver both I & Q. + */ + bool set_format(unsigned int format); + + static unsigned int make_format(int width=16, int shift=0, + bool want_q=true, bool bypass_halfband=false); + static int format_width(unsigned int format); + static int format_shift(unsigned int format); + static bool format_want_q(unsigned int format); + static bool format_bypass_halfband(unsigned int format); + + /*! + * \brief High-level "tune" method. Works for the single channel case. + * + * This method adjusts both the daughterboard LO and the DDC so that + * target_freq ends up at DC in the complex baseband samples. + * + * \param chan which DDC channel we're controlling (almost always 0). + * \param db the daughterboard we're controlling. + * \param target_freq the RF frequency we want at DC in the complex baseband. + * \param[out] result details how the hardware was configured. + * + * \returns true iff everything was successful. + */ + bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result); + + + // ACCESSORS + unsigned int decim_rate () const; + double rx_freq (int channel) const; + int nchannels () const; + int mux () const; + unsigned int format () const; + + // called in base class to derived class order + bool start (); + bool stop (); +}; + +// ---------------------------------------------------------------- + +/*! + * \brief The C++ interface the transmit side of the USRP + * \ingroup usrp + * + * This is the recommended interface to USRP transmit functionality + * for applications that use the USRP but not GNU Radio. + * + * Uses digital upconverter (coarse & fine modulators) in AD9862... + */ +class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common +{ + public: + enum coarse_mod_t { + CM_NEG_FDAC_OVER_4, // -32 MHz + CM_NEG_FDAC_OVER_8, // -16 MHz + CM_OFF, + CM_POS_FDAC_OVER_8, // +16 MHz + CM_POS_FDAC_OVER_4 // +32 MHz + }; + + protected: + static const int MAX_CHAN = 2; + unsigned int d_interp_rate; + int d_nchan; + int d_sw_mux; + int d_hw_mux; + double d_tx_freq[MAX_CHAN]; + coarse_mod_t d_coarse_mod[MAX_CHAN]; + unsigned char d_tx_modulator_shadow[MAX_CHAN]; + + virtual bool set_coarse_modulator (int channel, coarse_mod_t cm); + usrp_standard_tx::coarse_mod_t coarse_modulator (int channel) const; + + protected: + usrp_standard_tx (int which_board, + unsigned int interp_rate, + int nchan = 1, + int mux = -1, + int fusb_block_size = 0, + int fusb_nblocks = 0, + const std::string fpga_filename = "", + const std::string firmware_filename = "" + ); // throws if trouble + + bool write_hw_mux_reg (); + + public: + ~usrp_standard_tx (); + + /*! + * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble + * + * \param which_board Which USRP board on usb (not particularly useful; use 0) + * \param interp_rate interpolation factor + * \param nchan number of channels + * \param mux Tx mux setting, \sa set_mux + * \param fusb_block_size fast usb xfer block size. Must be a multiple of 512. + * Use zero for a reasonable default. + * \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default. + * \param fpga_filename Name of rbf file to load + * \param firmware_filename Name of ihx file to load + */ + static usrp_standard_tx_sptr make(int which_board, + unsigned int interp_rate, + int nchan = 1, + int mux = -1, + int fusb_block_size = 0, + int fusb_nblocks = 0, + const std::string fpga_filename = "", + const std::string firmware_filename = "" + ); + + /*! + * \brief Set interpolator rate. \p rate must be in [4, 512] and a multiple of 4. + * + * The final complex sample rate across the USB is + * dac_freq () / interp_rate () * nchannels () + */ + virtual bool set_interp_rate (unsigned int rate); + + /*! + * \brief Set number of active channels. \p nchannels must be 1 or 2. + * + * The final complex sample rate across the USB is + * dac_freq () / decim_rate () * nchannels () + */ + bool set_nchannels (int nchannels); + + /*! + * \brief Set output mux configuration. + * + *
+   *     3                   2                   1                       
+   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   *  +-------------------------------+-------+-------+-------+-------+
+   *  |                               | DAC3  | DAC2  | DAC1  |  DAC0 |
+   *  +-------------------------------+-------+-------+-------+-------+
+   * 
+   *  There are two interpolators with complex inputs and outputs.
+   *  There are four DACs.
+   * 
+   *  Each 4-bit DACx field specifies the source for the DAC and
+   *  whether or not that DAC is enabled.  Each subfield is coded
+   *  like this: 
+   * 
+   *     3 2 1 0
+   *    +-+-----+
+   *    |E|  N  |
+   *    +-+-----+
+   * 
+   *  Where E is set if the DAC is enabled, and N specifies which
+   *  interpolator output is connected to this DAC.
+   * 
+   *   N   which interp output
+   *  ---  -------------------
+   *   0   chan 0 I
+   *   1   chan 0 Q
+   *   2   chan 1 I
+   *   3   chan 1 Q
+   * 
+ */ + bool set_mux (int mux); + + /*! + * Determine the appropriate Tx mux value as a function of the subdevice choosen + * and the characteristics of the respective daughterboard. + */ + int determine_tx_mux_value(const usrp_subdev_spec &ss); + int determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b); + + /*! + * \brief set the frequency of the digital up converter. + * + * \p channel must be in the range [0,1]. \p freq is the center + * frequency in Hz. It must be in the range [-44M, 44M]. + * The frequency specified is quantized. Use tx_freq to retrieve + * the actual value used. + */ + virtual bool set_tx_freq (int channel, double freq); // chan: [0,1] + + // ACCESSORS + unsigned int interp_rate () const; + double tx_freq (int channel) const; + int nchannels () const; + int mux () const; + + /*! + * \brief High-level "tune" method. Works for the single channel case. + * + * This method adjusts both the daughterboard LO and the DUC so that + * DC in the complex baseband samples ends up at RF target_freq. + * + * \param chan which DUC channel we're controlling (usually == which_side). + * \param db the daughterboard we're controlling. + * \param target_freq the RF frequency we want our baseband translated to. + * \param[out] result details how the hardware was configured. + * + * \returns true iff everything was successful. + */ + bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result); + + + // called in base class to derived class order + bool start (); + bool stop (); +}; + +#endif /* INCLUDED_USRP_STANDARD_H */