GNU Radio 3.3.0 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2004,2008,2009 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #ifndef INCLUDED_USRP_STANDARD_H 00024 #define INCLUDED_USRP_STANDARD_H 00025 00026 #include <usrp/usrp_basic.h> 00027 #include <boost/shared_ptr.hpp> 00028 #include <usrp/usrp_tune_result.h> 00029 00030 class usrp_standard_tx; 00031 class usrp_standard_rx; 00032 00033 typedef boost::shared_ptr<usrp_standard_tx> usrp_standard_tx_sptr; 00034 typedef boost::shared_ptr<usrp_standard_rx> usrp_standard_rx_sptr; 00035 00036 /*! 00037 * \ingroup usrp 00038 */ 00039 class usrp_standard_common 00040 { 00041 int d_fpga_caps; // capability register val 00042 00043 protected: 00044 usrp_standard_common(usrp_basic *parent); 00045 00046 public: 00047 /*! 00048 *\brief does the FPGA implement the final Rx half-band filter? 00049 * If it doesn't, the maximum decimation factor with proper gain 00050 * is 1/2 of what it would otherwise be. 00051 */ 00052 bool has_rx_halfband() const; 00053 00054 /*! 00055 * \brief number of digital downconverters implemented in the FPGA 00056 * This will be 0, 1, 2 or 4. 00057 */ 00058 int nddcs() const; 00059 00060 /*! 00061 *\brief does the FPGA implement the initial Tx half-band filter? 00062 */ 00063 bool has_tx_halfband() const; 00064 00065 /*! 00066 * \brief number of digital upconverters implemented in the FPGA 00067 * This will be 0, 1, or 2. 00068 */ 00069 int nducs() const; 00070 00071 /*! 00072 * \brief Calculate the frequency to use for setting the digital up or down converter. 00073 * 00074 * \param target_freq is the desired RF frequency (Hz). 00075 * \param baseband_freq is the RF frequency that corresponds to DC in the IF coming from the d'board. 00076 * \param fs is the sampling frequency. 00077 * \param[out] dxc_freq the frequency to program into the DDC (or DUC). 00078 * \param[out] inverted is true if we're operating in an inverted Nyquist zone. 00079 */ 00080 static void calc_dxc_freq(double target_freq, double baseband_freq, double fs, 00081 double *dxc_freq, bool *inverted); 00082 }; 00083 00084 /*! 00085 * \brief The C++ interface the receive side of the USRP 00086 * \ingroup usrp 00087 * 00088 * This is the recommended interface to USRP receive functionality 00089 * for applications that use the USRP but not GNU Radio. 00090 */ 00091 class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common 00092 { 00093 private: 00094 static const int MAX_CHAN = 4; 00095 unsigned int d_decim_rate; 00096 int d_nchan; 00097 int d_sw_mux; 00098 int d_hw_mux; 00099 double d_rx_freq[MAX_CHAN]; 00100 00101 protected: 00102 usrp_standard_rx (int which_board, 00103 unsigned int decim_rate, 00104 int nchan = 1, 00105 int mux = -1, 00106 int mode = 0, 00107 int fusb_block_size = 0, 00108 int fusb_nblocks = 0, 00109 const std::string fpga_filename = "", 00110 const std::string firmware_filename = "" 00111 ); // throws if trouble 00112 00113 bool write_hw_mux_reg (); 00114 00115 public: 00116 00117 enum { 00118 FPGA_MODE_NORMAL = 0x00, 00119 FPGA_MODE_LOOPBACK = 0x01, 00120 FPGA_MODE_COUNTING = 0x02, 00121 FPGA_MODE_COUNTING_32BIT = 0x04 00122 }; 00123 00124 ~usrp_standard_rx (); 00125 00126 /*! 00127 * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble 00128 * 00129 * \param which_board Which USRP board on usb (not particularly useful; use 0) 00130 * \param decim_rate decimation factor 00131 * \param nchan number of channels 00132 * \param mux Rx mux setting, \sa set_mux 00133 * \param mode mode 00134 * \param fusb_block_size fast usb xfer block size. Must be a multiple of 512. 00135 * Use zero for a reasonable default. 00136 * \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default. 00137 * \param fpga_filename Name of rbf file to load 00138 * \param firmware_filename Name of ihx file to load 00139 */ 00140 static usrp_standard_rx_sptr make(int which_board, 00141 unsigned int decim_rate, 00142 int nchan = 1, 00143 int mux = -1, 00144 int mode = 0, 00145 int fusb_block_size = 0, 00146 int fusb_nblocks = 0, 00147 const std::string fpga_filename = "", 00148 const std::string firmware_filename = "" 00149 ); 00150 /*! 00151 * \brief Set decimator rate. \p rate MUST BE EVEN and in [8, 256]. 00152 * 00153 * The final complex sample rate across the USB is 00154 * adc_freq () / decim_rate () * nchannels () 00155 */ 00156 bool set_decim_rate (unsigned int rate); 00157 00158 /*! 00159 * \brief Set number of active channels. \p nchannels must be 1, 2 or 4. 00160 * 00161 * The final complex sample rate across the USB is 00162 * adc_freq () / decim_rate () * nchannels () 00163 */ 00164 bool set_nchannels (int nchannels); 00165 00166 /*! 00167 * \brief Set input mux configuration. 00168 * 00169 * This determines which ADC (or constant zero) is connected to 00170 * each DDC input. There are 4 DDCs. Each has two inputs. 00171 * 00172 * <pre> 00173 * Mux value: 00174 * 00175 * 3 2 1 00176 * 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 00177 * +-------+-------+-------+-------+-------+-------+-------+-------+ 00178 * | Q3 | I3 | Q2 | I2 | Q1 | I1 | Q0 | I0 | 00179 * +-------+-------+-------+-------+-------+-------+-------+-------+ 00180 * 00181 * Each 4-bit I field is either 0,1,2,3 00182 * Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero) 00183 * All Q's must be 0xf or none of them may be 0xf 00184 * </pre> 00185 */ 00186 bool set_mux (int mux); 00187 00188 /*! 00189 * Determine the appropriate Rx mux value as a function of the subdevice choosen 00190 * and the characteristics of the respective daughterboard. 00191 */ 00192 int determine_rx_mux_value(const usrp_subdev_spec &ss); 00193 int determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b); 00194 00195 /*! 00196 * \brief set the frequency of the digital down converter. 00197 * 00198 * \p channel must be in the range [0,3]. \p freq is the center 00199 * frequency in Hz. \p freq may be either negative or postive. 00200 * The frequency specified is quantized. Use rx_freq to retrieve 00201 * the actual value used. 00202 */ 00203 bool set_rx_freq (int channel, double freq); 00204 00205 /*! 00206 * \brief set fpga mode 00207 */ 00208 bool set_fpga_mode (int mode); 00209 00210 /*! 00211 * \brief Set the digital down converter phase register. 00212 * 00213 * \param channel which ddc channel [0, 3] 00214 * \param phase 32-bit integer phase value. 00215 */ 00216 bool set_ddc_phase(int channel, int phase); 00217 00218 /*! 00219 * \brief Specify Rx data format. 00220 * 00221 * \param format format specifier 00222 * 00223 * Rx data format control register 00224 * 00225 * 3 2 1 00226 * 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 00227 * +-----------------------------------------+-+-+---------+-------+ 00228 * | Reserved (Must be zero) |B|Q| WIDTH | SHIFT | 00229 * +-----------------------------------------+-+-+---------+-------+ 00230 * 00231 * SHIFT specifies arithmetic right shift [0, 15] 00232 * WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid) 00233 * Q if set deliver both I & Q, else just I 00234 * B if set bypass half-band filter. 00235 * 00236 * Right now the acceptable values are: 00237 * 00238 * B Q WIDTH SHIFT 00239 * 0 1 16 0 00240 * 0 1 8 8 00241 * 00242 * More valid combos to come. 00243 * 00244 * Default value is 0x00000300 16-bits, 0 shift, deliver both I & Q. 00245 */ 00246 bool set_format(unsigned int format); 00247 00248 static unsigned int make_format(int width=16, int shift=0, 00249 bool want_q=true, bool bypass_halfband=false); 00250 static int format_width(unsigned int format); 00251 static int format_shift(unsigned int format); 00252 static bool format_want_q(unsigned int format); 00253 static bool format_bypass_halfband(unsigned int format); 00254 00255 /*! 00256 * \brief High-level "tune" method. Works for the single channel case. 00257 * 00258 * This method adjusts both the daughterboard LO and the DDC so that 00259 * target_freq ends up at DC in the complex baseband samples. 00260 * 00261 * \param chan which DDC channel we're controlling (almost always 0). 00262 * \param db the daughterboard we're controlling. 00263 * \param target_freq the RF frequency we want at DC in the complex baseband. 00264 * \param[out] result details how the hardware was configured. 00265 * 00266 * \returns true iff everything was successful. 00267 */ 00268 bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result); 00269 00270 00271 // ACCESSORS 00272 unsigned int decim_rate () const; 00273 double rx_freq (int channel) const; 00274 int nchannels () const; 00275 int mux () const; 00276 unsigned int format () const; 00277 00278 // called in base class to derived class order 00279 bool start (); 00280 bool stop (); 00281 }; 00282 00283 // ---------------------------------------------------------------- 00284 00285 /*! 00286 * \brief The C++ interface the transmit side of the USRP 00287 * \ingroup usrp 00288 * 00289 * This is the recommended interface to USRP transmit functionality 00290 * for applications that use the USRP but not GNU Radio. 00291 * 00292 * Uses digital upconverter (coarse & fine modulators) in AD9862... 00293 */ 00294 class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common 00295 { 00296 public: 00297 enum coarse_mod_t { 00298 CM_NEG_FDAC_OVER_4, // -32 MHz 00299 CM_NEG_FDAC_OVER_8, // -16 MHz 00300 CM_OFF, 00301 CM_POS_FDAC_OVER_8, // +16 MHz 00302 CM_POS_FDAC_OVER_4 // +32 MHz 00303 }; 00304 00305 protected: 00306 static const int MAX_CHAN = 2; 00307 unsigned int d_interp_rate; 00308 int d_nchan; 00309 int d_sw_mux; 00310 int d_hw_mux; 00311 double d_tx_freq[MAX_CHAN]; 00312 coarse_mod_t d_coarse_mod[MAX_CHAN]; 00313 unsigned char d_tx_modulator_shadow[MAX_CHAN]; 00314 00315 virtual bool set_coarse_modulator (int channel, coarse_mod_t cm); 00316 usrp_standard_tx::coarse_mod_t coarse_modulator (int channel) const; 00317 00318 protected: 00319 usrp_standard_tx (int which_board, 00320 unsigned int interp_rate, 00321 int nchan = 1, 00322 int mux = -1, 00323 int fusb_block_size = 0, 00324 int fusb_nblocks = 0, 00325 const std::string fpga_filename = "", 00326 const std::string firmware_filename = "" 00327 ); // throws if trouble 00328 00329 bool write_hw_mux_reg (); 00330 00331 public: 00332 ~usrp_standard_tx (); 00333 00334 /*! 00335 * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble 00336 * 00337 * \param which_board Which USRP board on usb (not particularly useful; use 0) 00338 * \param interp_rate interpolation factor 00339 * \param nchan number of channels 00340 * \param mux Tx mux setting, \sa set_mux 00341 * \param fusb_block_size fast usb xfer block size. Must be a multiple of 512. 00342 * Use zero for a reasonable default. 00343 * \param fusb_nblocks number of fast usb URBs to allocate. Use zero for a reasonable default. 00344 * \param fpga_filename Name of rbf file to load 00345 * \param firmware_filename Name of ihx file to load 00346 */ 00347 static usrp_standard_tx_sptr make(int which_board, 00348 unsigned int interp_rate, 00349 int nchan = 1, 00350 int mux = -1, 00351 int fusb_block_size = 0, 00352 int fusb_nblocks = 0, 00353 const std::string fpga_filename = "", 00354 const std::string firmware_filename = "" 00355 ); 00356 00357 /*! 00358 * \brief Set interpolator rate. \p rate must be in [4, 512] and a multiple of 4. 00359 * 00360 * The final complex sample rate across the USB is 00361 * dac_freq () / interp_rate () * nchannels () 00362 */ 00363 virtual bool set_interp_rate (unsigned int rate); 00364 00365 /*! 00366 * \brief Set number of active channels. \p nchannels must be 1 or 2. 00367 * 00368 * The final complex sample rate across the USB is 00369 * dac_freq () / decim_rate () * nchannels () 00370 */ 00371 bool set_nchannels (int nchannels); 00372 00373 /*! 00374 * \brief Set output mux configuration. 00375 * 00376 * <pre> 00377 * 3 2 1 00378 * 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 00379 * +-------------------------------+-------+-------+-------+-------+ 00380 * | | DAC3 | DAC2 | DAC1 | DAC0 | 00381 * +-------------------------------+-------+-------+-------+-------+ 00382 * 00383 * There are two interpolators with complex inputs and outputs. 00384 * There are four DACs. 00385 * 00386 * Each 4-bit DACx field specifies the source for the DAC and 00387 * whether or not that DAC is enabled. Each subfield is coded 00388 * like this: 00389 * 00390 * 3 2 1 0 00391 * +-+-----+ 00392 * |E| N | 00393 * +-+-----+ 00394 * 00395 * Where E is set if the DAC is enabled, and N specifies which 00396 * interpolator output is connected to this DAC. 00397 * 00398 * N which interp output 00399 * --- ------------------- 00400 * 0 chan 0 I 00401 * 1 chan 0 Q 00402 * 2 chan 1 I 00403 * 3 chan 1 Q 00404 * </pre> 00405 */ 00406 bool set_mux (int mux); 00407 00408 /*! 00409 * Determine the appropriate Tx mux value as a function of the subdevice choosen 00410 * and the characteristics of the respective daughterboard. 00411 */ 00412 int determine_tx_mux_value(const usrp_subdev_spec &ss); 00413 int determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b); 00414 00415 /*! 00416 * \brief set the frequency of the digital up converter. 00417 * 00418 * \p channel must be in the range [0,1]. \p freq is the center 00419 * frequency in Hz. It must be in the range [-44M, 44M]. 00420 * The frequency specified is quantized. Use tx_freq to retrieve 00421 * the actual value used. 00422 */ 00423 virtual bool set_tx_freq (int channel, double freq); // chan: [0,1] 00424 00425 // ACCESSORS 00426 unsigned int interp_rate () const; 00427 double tx_freq (int channel) const; 00428 int nchannels () const; 00429 int mux () const; 00430 00431 /*! 00432 * \brief High-level "tune" method. Works for the single channel case. 00433 * 00434 * This method adjusts both the daughterboard LO and the DUC so that 00435 * DC in the complex baseband samples ends up at RF target_freq. 00436 * 00437 * \param chan which DUC channel we're controlling (usually == which_side). 00438 * \param db the daughterboard we're controlling. 00439 * \param target_freq the RF frequency we want our baseband translated to. 00440 * \param[out] result details how the hardware was configured. 00441 * 00442 * \returns true iff everything was successful. 00443 */ 00444 bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result); 00445 00446 00447 // called in base class to derived class order 00448 bool start (); 00449 bool stop (); 00450 }; 00451 00452 #endif /* INCLUDED_USRP_STANDARD_H */