GNU Radio 3.4.2 C++ API
usrp_basic.h
Go to the documentation of this file.
00001 /*  -*- c++ -*- */
00002 /*
00003  * Copyright 2005,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_BASIC_H
00024 #define INCLUDED_USRP_BASIC_H
00025 
00026 #include <usrp/db_base.h>
00027 #include <usrp/usrp_slots.h>
00028 #include <usrp/usrp_subdev_spec.h>
00029 #include <usrp/libusb_types.h>
00030 #include <string>
00031 #include <vector>
00032 #include <boost/utility.hpp>
00033 
00034 class  fusb_devhandle;
00035 class  fusb_ephandle;
00036 
00037 enum txrx_t {
00038   C_RX = 0,
00039   C_TX = 1
00040 };
00041 
00042 /*
00043  * ----------------------------------------------------------------------
00044  * Mid level interface to the Universal Software Radio Peripheral (Rev 1)
00045  *
00046  * These classes implement the basic functionality for talking to the
00047  * USRP.  They try to be as independent of the signal processing code
00048  * in FPGA as possible.  They implement access to the low level
00049  * peripherals on the board, provide a common way for reading and
00050  * writing registers in the FPGA, and provide the high speed interface
00051  * to streaming data across the USB.
00052  *
00053  * It is expected that subclasses will be derived that provide
00054  * access to the functionality to a particular FPGA configuration.
00055  * ----------------------------------------------------------------------
00056  */
00057 
00058 
00059 /*!
00060  * \brief abstract base class for usrp operations
00061  * \ingroup usrp
00062  */
00063 class usrp_basic : boost::noncopyable
00064 {
00065 protected:
00066   void shutdown_daughterboards();
00067 
00068 protected:
00069   libusb_device_handle          *d_udh;
00070   struct libusb_context         *d_ctx;
00071   int                            d_usb_data_rate;       // bytes/sec
00072   int                            d_bytes_per_poll;      // how often to poll for overruns
00073   bool                           d_verbose;
00074   long                           d_fpga_master_clock_freq;
00075 
00076   static const int               MAX_REGS = 128;
00077   unsigned int                   d_fpga_shadows[MAX_REGS];
00078 
00079   int                            d_dbid[2];             // daughterboard ID's (side A, side B)
00080 
00081   /*!
00082    * Shared pointers to subclasses of db_base.
00083    *
00084    * The outer vector is of length 2 (0 = side A, 1 = side B).  The
00085    * inner vectors are of length 1, 2 or 3 depending on the number of
00086    * subdevices implemented by the daugherboard.  At this time, only
00087    * the Basic Rx and LF Rx implement more than 1 subdevice.
00088    */
00089   std::vector< std::vector<db_base_sptr> > d_db;
00090 
00091   // One time call, made only only from usrp_standard_*::make after shared_ptr is created.
00092   void init_db(usrp_basic_sptr u);
00093 
00094 
00095   usrp_basic (int which_board,
00096               libusb_device_handle *open_interface (libusb_device *dev),
00097               const std::string fpga_filename = "",
00098               const std::string firmware_filename = "");
00099 
00100   /*!
00101    * \brief advise usrp_basic of usb data rate (bytes/sec)
00102    *
00103    * N.B., this doesn't tweak any hardware.  Derived classes
00104    * should call this to inform us of the data rate whenever it's
00105    * first set or if it changes.
00106    *
00107    * \param usb_data_rate       bytes/sec
00108    */
00109   void set_usb_data_rate (int usb_data_rate);
00110   
00111   /*!
00112    * \brief Write auxiliary digital to analog converter.
00113    *
00114    * \param slot        Which Tx or Rx slot to write.
00115    *                    N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
00116    *                    SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
00117    * \param which_dac   [0,3] RX slots must use only 0 and 1.  TX slots must use only 2 and 3.
00118    * \param value       [0,4095]
00119    * \returns true iff successful
00120    */
00121   bool _write_aux_dac (int slot, int which_dac, int value);
00122 
00123   /*!
00124    * \brief Read auxiliary analog to digital converter.
00125    *
00126    * \param slot        2-bit slot number. E.g., SLOT_TX_A
00127    * \param which_adc   [0,1]
00128    * \param value       return 12-bit value [0,4095]
00129    * \returns true iff successful
00130    */
00131   bool _read_aux_adc (int slot, int which_adc, int *value);
00132 
00133   /*!
00134    * \brief Read auxiliary analog to digital converter.
00135    *
00136    * \param slot        2-bit slot number. E.g., SLOT_TX_A
00137    * \param which_adc   [0,1]
00138    * \returns value in the range [0,4095] if successful, else READ_FAILED.
00139    */
00140   int _read_aux_adc (int slot, int which_adc);
00141 
00142 
00143 public:
00144   virtual ~usrp_basic ();
00145 
00146 
00147   /*!
00148    * Return a vector of vectors that contain shared pointers
00149    * to the daughterboard instance(s) associated with the specified side.
00150    *
00151    * It is an error to use the returned objects after the usrp_basic
00152    * object has been destroyed.
00153    */
00154   std::vector<std::vector<db_base_sptr> > db() const { return d_db; }
00155 
00156   /*!
00157    * Return a vector of size >= 1 that contains shared pointers
00158    * to the daughterboard instance(s) associated with the specified side.
00159    *
00160    * \param which_side  [0,1] which daughterboard
00161    *
00162    * It is an error to use the returned objects after the usrp_basic
00163    * object has been destroyed.
00164    */
00165   std::vector<db_base_sptr> db(int which_side);
00166  
00167   /*!
00168    * \brief is the subdev_spec valid?
00169    */
00170   bool is_valid(const usrp_subdev_spec &ss);
00171 
00172   /*!
00173    * \brief given a subdev_spec, return the corresponding daughterboard object.
00174    * \throws std::invalid_ argument if ss is invalid.
00175    *
00176    * \param ss specifies the side and subdevice
00177    */
00178   db_base_sptr selected_subdev(const usrp_subdev_spec &ss);
00179 
00180   /*!
00181    * \brief return frequency of master oscillator on USRP
00182    */
00183   long fpga_master_clock_freq () const { return d_fpga_master_clock_freq; }
00184 
00185   /*!
00186    * Tell API that the master oscillator on the USRP is operating at a non-standard 
00187    * fixed frequency. This is only needed for custom USRP hardware modified to 
00188    * operate at a different frequency from the default factory configuration. This
00189    * function must be called prior to any other API function.
00190    * \param master_clock USRP2 FPGA master clock frequency in Hz (10..64 MHz)
00191    */
00192   void set_fpga_master_clock_freq (long master_clock) { d_fpga_master_clock_freq = master_clock; }
00193 
00194   /*!
00195    * \returns usb data rate in bytes/sec
00196    */
00197   int usb_data_rate () const { return d_usb_data_rate; }
00198 
00199   void set_verbose (bool on) { d_verbose = on; }
00200 
00201   //! magic value used on alternate register read interfaces
00202   static const int READ_FAILED = -99999;
00203 
00204   /*!
00205    * \brief Write EEPROM on motherboard or any daughterboard.
00206    * \param i2c_addr            I2C bus address of EEPROM
00207    * \param eeprom_offset       byte offset in EEPROM to begin writing
00208    * \param buf                 the data to write
00209    * \returns true iff sucessful
00210    */
00211   bool write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf);
00212 
00213   /*!
00214    * \brief Read EEPROM on motherboard or any daughterboard.
00215    * \param i2c_addr            I2C bus address of EEPROM
00216    * \param eeprom_offset       byte offset in EEPROM to begin reading
00217    * \param len                 number of bytes to read
00218    * \returns the data read if successful, else a zero length string.
00219    */
00220   std::string read_eeprom (int i2c_addr, int eeprom_offset, int len);
00221 
00222   /*!
00223    * \brief Write to I2C peripheral
00224    * \param i2c_addr            I2C bus address (7-bits)
00225    * \param buf                 the data to write
00226    * \returns true iff successful
00227    * Writes are limited to a maximum of of 64 bytes.
00228    */
00229   bool write_i2c (int i2c_addr, const std::string buf);
00230 
00231   /*!
00232    * \brief Read from I2C peripheral
00233    * \param i2c_addr            I2C bus address (7-bits)
00234    * \param len                 number of bytes to read
00235    * \returns the data read if successful, else a zero length string.
00236    * Reads are limited to a maximum of 64 bytes.
00237    */
00238   std::string read_i2c (int i2c_addr, int len);
00239 
00240   /*!
00241    * \brief Set ADC offset correction
00242    * \param which_adc   which ADC[0,3]: 0 = RX_A I, 1 = RX_A Q...
00243    * \param offset      16-bit value to subtract from raw ADC input.
00244    */
00245   bool set_adc_offset (int which_adc, int offset);
00246 
00247   /*!
00248    * \brief Set DAC offset correction
00249    * \param which_dac   which DAC[0,3]: 0 = TX_A I, 1 = TX_A Q...
00250    * \param offset      10-bit offset value (ambiguous format:  See AD9862 datasheet).
00251    * \param offset_pin  1-bit value.  If 0 offset applied to -ve differential pin;
00252    *                                  If 1 offset applied to +ve differential pin.
00253    */
00254   bool set_dac_offset (int which_dac, int offset, int offset_pin);
00255 
00256   /*!
00257    * \brief Control ADC input buffer
00258    * \param which_adc   which ADC[0,3]
00259    * \param bypass      if non-zero, bypass input buffer and connect input
00260    *                    directly to switched cap SHA input of RxPGA.
00261    */
00262   bool set_adc_buffer_bypass (int which_adc, bool bypass);
00263 
00264   /*!
00265    * \brief Enable/disable automatic DC offset removal control loop in FPGA
00266    *
00267    * \param bits  which control loops to enable
00268    * \param mask  which \p bits to pay attention to
00269    *
00270    * If the corresponding bit is set, enable the automatic DC
00271    * offset correction control loop.
00272    *
00273    * <pre>
00274    * The 4 low bits are significant:
00275    *
00276    *   ADC0 = (1 << 0)
00277    *   ADC1 = (1 << 1)
00278    *   ADC2 = (1 << 2)
00279    *   ADC3 = (1 << 3)
00280    * </pre>
00281    *
00282    * By default the control loop is enabled on all ADC's.
00283    */
00284   bool set_dc_offset_cl_enable(int bits, int mask);
00285 
00286   /*!
00287    * \brief return the usrp's serial number.
00288    *
00289    * \returns non-zero length string iff successful.
00290    */
00291   std::string serial_number();
00292 
00293   /*!
00294    * \brief Return daughterboard ID for given side [0,1].
00295    *
00296    * \param which_side  [0,1] which daughterboard
00297    *
00298    * \return daughterboard id >= 0 if successful
00299    * \return -1 if no daugherboard
00300    * \return -2 if invalid EEPROM on daughterboard
00301    */
00302   virtual int daughterboard_id (int which_side) const = 0;
00303 
00304   /*!
00305    * \brief Clock ticks to delay rising of T/R signal
00306    * \sa write_atr_mask, write_atr_txval, write_atr_rxval
00307    */
00308   bool write_atr_tx_delay(int value);
00309 
00310   /*!
00311    * \brief Clock ticks to delay falling edge of T/R signal
00312    * \sa write_atr_mask, write_atr_txval, write_atr_rxval
00313    */
00314   bool write_atr_rx_delay(int value);
00315 
00316 
00317   // ================================================================
00318   // Routines to access and control daughterboard specific i/o
00319   //
00320   // Those with a common_ prefix access either the Tx or Rx side depending
00321   // on the txrx parameter.  Those without the common_ prefix are virtual
00322   // and are overriden in usrp_basic_rx and usrp_basic_tx to access the
00323   // the Rx or Tx sides automatically.  We provide the common_ versions
00324   // for those daughterboards such as the WBX and XCVR2450 that share
00325   // h/w resources (such as the LO) between the Tx and Rx sides.
00326 
00327   // ----------------------------------------------------------------
00328   // BEGIN common_  daughterboard control functions
00329 
00330   /*!
00331    * \brief Set Programmable Gain Amplifier(PGA)
00332    *
00333    * \param txrx        Tx or Rx?
00334    * \param which_amp   which amp [0,3]
00335    * \param gain_in_db  gain value(linear in dB)
00336    *
00337    * gain is rounded to closest setting supported by hardware.
00338    *
00339    * \returns true iff sucessful.
00340    *
00341    * \sa pga_min(), pga_max(), pga_db_per_step()
00342    */
00343   bool common_set_pga(txrx_t txrx, int which_amp, double gain_in_db);
00344 
00345   /*!
00346    * \brief Return programmable gain amplifier gain setting in dB.
00347    *
00348    * \param txrx        Tx or Rx?
00349    * \param which_amp   which amp [0,3]
00350    */
00351   double common_pga(txrx_t txrx, int which_amp) const;
00352 
00353   /*!
00354    * \brief Return minimum legal PGA gain in dB.
00355    * \param txrx        Tx or Rx?
00356    */
00357   double common_pga_min(txrx_t txrx) const;
00358 
00359   /*!
00360    * \brief Return maximum legal PGA gain in dB.
00361    * \param txrx        Tx or Rx?
00362    */
00363   double common_pga_max(txrx_t txrx) const;
00364 
00365   /*!
00366    * \brief Return hardware step size of PGA(linear in dB).
00367    * \param txrx        Tx or Rx?
00368    */
00369   double common_pga_db_per_step(txrx_t txrx) const;
00370 
00371   /*!
00372    * \brief Write direction register(output enables) for pins that go to daughterboard.
00373    *
00374    * \param txrx        Tx or Rx?
00375    * \param which_side  [0,1] which size
00376    * \param value       value to write into register
00377    * \param mask        which bits of value to write into reg
00378    *
00379    * Each d'board has 16-bits of general purpose i/o.
00380    * Setting the bit makes it an output from the FPGA to the d'board.
00381    *
00382    * This register is initialized based on a value stored in the
00383    * d'board EEPROM.  In general, you shouldn't be using this routine
00384    * without a very good reason.  Using this method incorrectly will
00385    * kill your USRP motherboard and/or daughterboard.
00386    */
00387   bool _common_write_oe(txrx_t txrx, int which_side, int value, int mask);
00388 
00389   /*!
00390    * \brief Write daughterboard i/o pin value
00391    *
00392    * \param txrx        Tx or Rx?
00393    * \param which_side  [0,1] which d'board
00394    * \param value       value to write into register
00395    * \param mask        which bits of value to write into reg
00396    */
00397   bool common_write_io(txrx_t txrx, int which_side, int value, int mask);
00398 
00399   /*!
00400    * \brief Read daughterboard i/o pin value
00401    *
00402    * \param txrx        Tx or Rx?
00403    * \param which_side  [0,1] which d'board
00404    * \param value       output
00405    */
00406   bool common_read_io(txrx_t txrx, int which_side, int *value);
00407 
00408   /*!
00409    * \brief Read daughterboard i/o pin value
00410    *
00411    * \param txrx        Tx or Rx?
00412    * \param which_side  [0,1] which d'board
00413    * \returns register value if successful, else READ_FAILED
00414    */
00415   int common_read_io(txrx_t txrx, int which_side);
00416 
00417   /*!
00418    * \brief Write daughterboard refclk config register
00419    *
00420    * \param txrx        Tx or Rx?
00421    * \param which_side  [0,1] which d'board
00422    * \param value       value to write into register, see below
00423    *
00424    * <pre>
00425    * Control whether a reference clock is sent to the daughterboards,
00426    * and what frequency.  The refclk is sent on d'board i/o pin 0.
00427    * 
00428    *     3                   2                   1                       
00429    *   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
00430    *  +-----------------------------------------------+-+------------+
00431    *  |             Reserved (Must be zero)           |E|   DIVISOR  |
00432    *  +-----------------------------------------------+-+------------+
00433    * 
00434    *  Bit 7  -- 1 turns on refclk, 0 allows IO use
00435    *  Bits 6:0 Divider value
00436    * </pre>
00437    */
00438   bool common_write_refclk(txrx_t txrx, int which_side, int value);
00439 
00440   /*!
00441    * \brief Automatic Transmit/Receive switching
00442    * <pre>
00443    *
00444    * If automatic transmit/receive (ATR) switching is enabled in the
00445    * FR_ATR_CTL register, the presence or absence of data in the FPGA
00446    * transmit fifo selects between two sets of values for each of the 4
00447    * banks of daughterboard i/o pins.
00448    *
00449    * Each daughterboard slot has 3 16-bit registers associated with it:
00450    *   FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
00451    *
00452    * FR_ATR_MASK_{0,1,2,3}: 
00453    *
00454    *   These registers determine which of the daugherboard i/o pins are
00455    *   affected by ATR switching.  If a bit in the mask is set, the
00456    *   corresponding i/o bit is controlled by ATR, else it's output
00457    *   value comes from the normal i/o pin output register:
00458    *   FR_IO_{0,1,2,3}.
00459    *
00460    * FR_ATR_TXVAL_{0,1,2,3}:
00461    * FR_ATR_RXVAL_{0,1,2,3}:
00462    *
00463    *   If the Tx fifo contains data, then the bits from TXVAL that are
00464    *   selected by MASK are output.  Otherwise, the bits from RXVAL that
00465    *   are selected by MASK are output.
00466    * </pre>
00467    */
00468   bool common_write_atr_mask(txrx_t txrx, int which_side, int value);
00469   bool common_write_atr_txval(txrx_t txrx, int which_side, int value);
00470   bool common_write_atr_rxval(txrx_t txrx, int which_side, int value);
00471 
00472   /*!
00473    * \brief Write auxiliary digital to analog converter.
00474    *
00475    * \param txrx        Tx or Rx?
00476    * \param which_side  [0,1] which d'board
00477    *                    N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
00478    *                    SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
00479    * \param which_dac   [2,3] TX slots must use only 2 and 3.
00480    * \param value       [0,4095]
00481    * \returns true iff successful
00482    */
00483   bool common_write_aux_dac(txrx_t txrx, int which_side, int which_dac, int value);
00484 
00485   /*!
00486    * \brief Read auxiliary analog to digital converter.
00487    *
00488    * \param txrx        Tx or Rx?
00489    * \param which_side  [0,1] which d'board
00490    * \param which_adc   [0,1]
00491    * \param value       return 12-bit value [0,4095]
00492    * \returns true iff successful
00493    */
00494   bool common_read_aux_adc(txrx_t txrx, int which_side, int which_adc, int *value);
00495 
00496   /*!
00497    * \brief Read auxiliary analog to digital converter.
00498    *
00499    * \param txrx        Tx or Rx?
00500    * \param which_side  [0,1] which d'board
00501    * \param which_adc   [0,1]
00502    * \returns value in the range [0,4095] if successful, else READ_FAILED.
00503    */
00504   int common_read_aux_adc(txrx_t txrx, int which_side, int which_adc);
00505 
00506   // END common_ daughterboard control functions
00507   // ----------------------------------------------------------------
00508   // BEGIN virtual daughterboard control functions
00509 
00510   /*!
00511    * \brief Set Programmable Gain Amplifier (PGA)
00512    *
00513    * \param which_amp   which amp [0,3]
00514    * \param gain_in_db  gain value (linear in dB)
00515    *
00516    * gain is rounded to closest setting supported by hardware.
00517    *
00518    * \returns true iff sucessful.
00519    *
00520    * \sa pga_min(), pga_max(), pga_db_per_step()
00521    */
00522   virtual bool set_pga (int which_amp, double gain_in_db) = 0;
00523 
00524   /*!
00525    * \brief Return programmable gain amplifier gain setting in dB.
00526    *
00527    * \param which_amp   which amp [0,3]
00528    */
00529   virtual double pga (int which_amp) const = 0;
00530 
00531   /*!
00532    * \brief Return minimum legal PGA gain in dB.
00533    */
00534   virtual double pga_min () const = 0;
00535 
00536   /*!
00537    * \brief Return maximum legal PGA gain in dB.
00538    */
00539   virtual double pga_max () const = 0;
00540 
00541   /*!
00542    * \brief Return hardware step size of PGA (linear in dB).
00543    */
00544   virtual double pga_db_per_step () const = 0;
00545 
00546   /*!
00547    * \brief Write direction register (output enables) for pins that go to daughterboard.
00548    *
00549    * \param which_side  [0,1] which size
00550    * \param value       value to write into register
00551    * \param mask        which bits of value to write into reg
00552    *
00553    * Each d'board has 16-bits of general purpose i/o.
00554    * Setting the bit makes it an output from the FPGA to the d'board.
00555    *
00556    * This register is initialized based on a value stored in the
00557    * d'board EEPROM.  In general, you shouldn't be using this routine
00558    * without a very good reason.  Using this method incorrectly will
00559    * kill your USRP motherboard and/or daughterboard.
00560    */
00561   virtual bool _write_oe (int which_side, int value, int mask) = 0;
00562 
00563   /*!
00564    * \brief Write daughterboard i/o pin value
00565    *
00566    * \param which_side  [0,1] which d'board
00567    * \param value       value to write into register
00568    * \param mask        which bits of value to write into reg
00569    */
00570   virtual bool write_io (int which_side, int value, int mask) = 0;
00571 
00572   /*!
00573    * \brief Read daughterboard i/o pin value
00574    *
00575    * \param which_side  [0,1] which d'board
00576    * \param value       output
00577    */
00578   virtual bool read_io (int which_side, int *value) = 0;
00579 
00580   /*!
00581    * \brief Read daughterboard i/o pin value
00582    *
00583    * \param which_side  [0,1] which d'board
00584    * \returns register value if successful, else READ_FAILED
00585    */
00586   virtual int read_io (int which_side) = 0;
00587 
00588   /*!
00589    * \brief Write daughterboard refclk config register
00590    *
00591    * \param which_side  [0,1] which d'board
00592    * \param value       value to write into register, see below
00593    *
00594    * <pre>
00595    * Control whether a reference clock is sent to the daughterboards,
00596    * and what frequency.  The refclk is sent on d'board i/o pin 0.
00597    * 
00598    *     3                   2                   1                       
00599    *   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
00600    *  +-----------------------------------------------+-+------------+
00601    *  |             Reserved (Must be zero)           |E|   DIVISOR  |
00602    *  +-----------------------------------------------+-+------------+
00603    * 
00604    *  Bit 7  -- 1 turns on refclk, 0 allows IO use
00605    *  Bits 6:0 Divider value
00606    * </pre>
00607    */
00608   virtual bool write_refclk(int which_side, int value) = 0;
00609 
00610   virtual bool write_atr_mask(int which_side, int value) = 0;
00611   virtual bool write_atr_txval(int which_side, int value) = 0;
00612   virtual bool write_atr_rxval(int which_side, int value) = 0;
00613 
00614   /*!
00615    * \brief Write auxiliary digital to analog converter.
00616    *
00617    * \param which_side  [0,1] which d'board
00618    *                    N.B., SLOT_TX_A and SLOT_RX_A share the same AUX DAC's.
00619    *                    SLOT_TX_B and SLOT_RX_B share the same AUX DAC's.
00620    * \param which_dac   [2,3] TX slots must use only 2 and 3.
00621    * \param value       [0,4095]
00622    * \returns true iff successful
00623    */
00624   virtual bool write_aux_dac (int which_side, int which_dac, int value) = 0;
00625 
00626   /*!
00627    * \brief Read auxiliary analog to digital converter.
00628    *
00629    * \param which_side  [0,1] which d'board
00630    * \param which_adc   [0,1]
00631    * \param value       return 12-bit value [0,4095]
00632    * \returns true iff successful
00633    */
00634   virtual bool read_aux_adc (int which_side, int which_adc, int *value) = 0;
00635 
00636   /*!
00637    * \brief Read auxiliary analog to digital converter.
00638    *
00639    * \param which_side  [0,1] which d'board
00640    * \param which_adc   [0,1]
00641    * \returns value in the range [0,4095] if successful, else READ_FAILED.
00642    */
00643   virtual int read_aux_adc (int which_side, int which_adc) = 0;
00644 
00645   /*!
00646    * \brief returns current fusb block size
00647    */
00648   virtual int block_size() const = 0;
00649 
00650   /*!
00651    * \brief returns A/D or D/A converter rate in Hz
00652    */
00653   virtual long converter_rate() const = 0;
00654 
00655   // END virtual daughterboard control functions
00656 
00657   // ----------------------------------------------------------------
00658   // Low level implementation routines.
00659   // You probably shouldn't be using these...
00660   //
00661 
00662   bool _set_led (int which_led, bool on);
00663 
00664   /*!
00665    * \brief Write FPGA register.
00666    * \param regno       7-bit register number
00667    * \param value       32-bit value
00668    * \returns true iff successful
00669    */
00670   bool _write_fpga_reg (int regno, int value);  //< 7-bit regno, 32-bit value
00671 
00672   /*!
00673    * \brief Read FPGA register.
00674    * \param regno       7-bit register number
00675    * \param value       32-bit value
00676    * \returns true iff successful
00677    */
00678   bool _read_fpga_reg (int regno, int *value);  //< 7-bit regno, 32-bit value
00679 
00680   /*!
00681    * \brief Read FPGA register.
00682    * \param regno       7-bit register number
00683    * \returns register value if successful, else READ_FAILED
00684    */
00685   int  _read_fpga_reg (int regno);
00686 
00687   /*!
00688    * \brief Write FPGA register with mask.
00689    * \param regno       7-bit register number
00690    * \param value       16-bit value
00691    * \param mask        16-bit value
00692    * \returns true if successful
00693    * Only use this for registers who actually implement a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
00694    */
00695   bool _write_fpga_reg_masked (int regno, int value, int mask);
00696 
00697   /*!
00698    * \brief Write AD9862 register.
00699    * \param which_codec 0 or 1
00700    * \param regno       6-bit register number
00701    * \param value       8-bit value
00702    * \returns true iff successful
00703    */
00704   bool _write_9862 (int which_codec, int regno, unsigned char value);
00705 
00706   /*!
00707    * \brief Read AD9862 register.
00708    * \param which_codec 0 or 1
00709    * \param regno       6-bit register number
00710    * \param value       8-bit value
00711    * \returns true iff successful
00712    */
00713   bool _read_9862 (int which_codec, int regno, unsigned char *value) const;
00714 
00715   /*!
00716    * \brief Read AD9862 register.
00717    * \param which_codec 0 or 1
00718    * \param regno       6-bit register number
00719    * \returns register value if successful, else READ_FAILED
00720    */
00721   int  _read_9862 (int which_codec, int regno) const;
00722 
00723   /*!
00724    * \brief Write data to SPI bus peripheral.
00725    *
00726    * \param optional_header     0,1 or 2 bytes to write before buf.
00727    * \param enables             bitmask of peripherals to write. See usrp_spi_defs.h
00728    * \param format              transaction format.  See usrp_spi_defs.h SPI_FMT_*
00729    * \param buf                 the data to write
00730    * \returns true iff successful
00731    * Writes are limited to a maximum of 64 bytes.
00732    *
00733    * If \p format specifies that optional_header bytes are present, they are
00734    * written to the peripheral immediately prior to writing \p buf.
00735    */
00736   bool _write_spi (int optional_header, int enables, int format, std::string buf);
00737 
00738   /*
00739    * \brief Read data from SPI bus peripheral.
00740    *
00741    * \param optional_header     0,1 or 2 bytes to write before buf.
00742    * \param enables             bitmask of peripheral to read. See usrp_spi_defs.h
00743    * \param format              transaction format.  See usrp_spi_defs.h SPI_FMT_*
00744    * \param len                 number of bytes to read.  Must be in [0,64].
00745    * \returns the data read if sucessful, else a zero length string.
00746    *
00747    * Reads are limited to a maximum of 64 bytes.
00748    *
00749    * If \p format specifies that optional_header bytes are present, they
00750    * are written to the peripheral first.  Then \p len bytes are read from
00751    * the peripheral and returned.
00752    */
00753   std::string _read_spi (int optional_header, int enables, int format, int len);
00754 
00755   /*!
00756    * \brief Start data transfers.
00757    * Called in base class to derived class order.
00758    */
00759   bool start ();
00760 
00761   /*!
00762    * \brief Stop data transfers.
00763    * Called in base class to derived class order.
00764    */
00765   bool stop ();
00766 };
00767 
00768 /*!
00769  * \brief class for accessing the receive side of the USRP
00770  * \ingroup usrp
00771  */
00772 class usrp_basic_rx : public usrp_basic 
00773 {
00774 private:
00775   fusb_devhandle        *d_devhandle;
00776   fusb_ephandle         *d_ephandle;
00777   int                    d_bytes_seen;          // how many bytes we've seen
00778   bool                   d_first_read;
00779   bool                   d_rx_enable;
00780 
00781 protected:
00782   /*!
00783    * \param which_board      Which USRP board on usb (not particularly useful; use 0)
00784    * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
00785    *                         Use zero for a reasonable default.
00786    * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
00787    * \param fpga_filename    name of the rbf file to load
00788    * \param firmware_filename name of ihx file to load
00789    */
00790   usrp_basic_rx (int which_board,
00791                  int fusb_block_size=0,
00792                  int fusb_nblocks=0,
00793                  const std::string fpga_filename = "",
00794                  const std::string firmware_filename = ""
00795                  );  // throws if trouble
00796 
00797   bool set_rx_enable (bool on);
00798   bool rx_enable () const { return d_rx_enable; }
00799 
00800   bool disable_rx ();           // conditional disable, return prev state
00801   void restore_rx (bool on);    // conditional set
00802 
00803   void probe_rx_slots (bool verbose);
00804 
00805 public:
00806   ~usrp_basic_rx ();
00807 
00808   /*!
00809    * \brief invokes constructor, returns instance or 0 if trouble
00810    *
00811    * \param which_board      Which USRP board on usb (not particularly useful; use 0)
00812    * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
00813    *                         Use zero for a reasonable default.
00814    * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
00815    * \param fpga_filename    name of file that contains image to load into FPGA
00816    * \param firmware_filename   name of file that contains image to load into FX2
00817    */
00818   static usrp_basic_rx *make (int which_board,
00819                               int fusb_block_size=0,
00820                               int fusb_nblocks=0,
00821                               const std::string fpga_filename = "",
00822                               const std::string firmware_filename = ""
00823                               );
00824 
00825   /*!
00826    * \brief tell the fpga the rate rx samples are coming from the A/D's
00827    *
00828    * div = fpga_master_clock_freq () / sample_rate
00829    *
00830    * sample_rate is determined by a myriad of registers
00831    * in the 9862.  That's why you have to tell us, so
00832    * we can tell the fpga.
00833    */
00834   bool set_fpga_rx_sample_rate_divisor (unsigned int div);
00835 
00836   /*!
00837    * \brief read data from the D/A's via the FPGA.
00838    * \p len must be a multiple of 512 bytes.
00839    *
00840    * \returns the number of bytes read, or -1 on error.
00841    *
00842    * If overrun is non-NULL it will be set true iff an RX overrun is detected.
00843    */
00844   int read (void *buf, int len, bool *overrun);
00845 
00846 
00847   //! sampling rate of A/D converter
00848   virtual long converter_rate() const { return fpga_master_clock_freq(); } // 64M
00849   long adc_rate() const { return converter_rate(); }
00850   int daughterboard_id (int which_side) const { return d_dbid[which_side & 0x1]; }
00851 
00852   bool set_pga (int which_amp, double gain_in_db);
00853   double pga (int which_amp) const;
00854   double pga_min () const;
00855   double pga_max () const;
00856   double pga_db_per_step () const;
00857 
00858   bool _write_oe (int which_side, int value, int mask);
00859   bool write_io (int which_side, int value, int mask);
00860   bool read_io (int which_side, int *value);
00861   int read_io (int which_side);
00862   bool write_refclk(int which_side, int value);
00863   bool write_atr_mask(int which_side, int value);
00864   bool write_atr_txval(int which_side, int value);
00865   bool write_atr_rxval(int which_side, int value);
00866 
00867   bool write_aux_dac (int which_side, int which_dac, int value);
00868   bool read_aux_adc (int which_side, int which_adc, int *value);
00869   int  read_aux_adc (int which_side, int which_adc);
00870 
00871   int block_size() const;
00872 
00873   // called in base class to derived class order
00874   bool start ();
00875   bool stop ();
00876 };
00877 
00878 /*!
00879  * \brief class for accessing the transmit side of the USRP
00880  * \ingroup usrp
00881  */
00882 class usrp_basic_tx : public usrp_basic 
00883 {
00884 private:
00885   fusb_devhandle        *d_devhandle;
00886   fusb_ephandle         *d_ephandle;
00887   int                    d_bytes_seen;          // how many bytes we've seen
00888   bool                   d_first_write;
00889   bool                   d_tx_enable;
00890 
00891  protected:
00892   /*!
00893    * \param which_board      Which USRP board on usb (not particularly useful; use 0)
00894    * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512.
00895    *                         Use zero for a reasonable default.
00896    * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default.
00897    * \param fpga_filename    name of file that contains image to load into FPGA
00898    * \param firmware_filename   name of file that contains image to load into FX2
00899    */
00900   usrp_basic_tx (int which_board,
00901                  int fusb_block_size=0,
00902                  int fusb_nblocks=0,
00903                  const std::string fpga_filename = "",
00904                  const std::string firmware_filename = ""
00905                  );             // throws if trouble
00906 
00907   bool set_tx_enable (bool on);
00908   bool tx_enable () const { return d_tx_enable; }
00909 
00910   bool disable_tx ();           // conditional disable, return prev state
00911   void restore_tx (bool on);    // conditional set
00912 
00913   void probe_tx_slots (bool verbose);
00914 
00915 public:
00916 
00917   ~usrp_basic_tx ();
00918 
00919   /*!
00920    * \brief invokes constructor, returns instance or 0 if trouble
00921    *
00922    * \param which_board      Which USRP board on usb (not particularly useful; use 0)
00923    * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
00924    *                         Use zero for a reasonable default.
00925    * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
00926    * \param fpga_filename    name of file that contains image to load into FPGA
00927    * \param firmware_filename   name of file that contains image to load into FX2
00928    */
00929   static usrp_basic_tx *make (int which_board, int fusb_block_size=0, int fusb_nblocks=0,
00930                               const std::string fpga_filename = "",
00931                               const std::string firmware_filename = ""
00932                               );
00933 
00934   /*!
00935    * \brief tell the fpga the rate tx samples are going to the D/A's
00936    *
00937    * div = fpga_master_clock_freq () * 2
00938    *
00939    * sample_rate is determined by a myriad of registers
00940    * in the 9862.  That's why you have to tell us, so
00941    * we can tell the fpga.
00942    */
00943   bool set_fpga_tx_sample_rate_divisor (unsigned int div);
00944 
00945   /*!
00946    * \brief Write data to the A/D's via the FPGA.
00947    *
00948    * \p len must be a multiple of 512 bytes.
00949    * \returns number of bytes written or -1 on error.
00950    *
00951    * if \p underrun is non-NULL, it will be set to true iff
00952    * a transmit underrun condition is detected.
00953    */
00954   int write (const void *buf, int len, bool *underrun);
00955 
00956   /*
00957    * Block until all outstanding writes have completed.
00958    * This is typically used to assist with benchmarking
00959    */
00960   void wait_for_completion ();
00961 
00962   //! sampling rate of D/A converter
00963   virtual long converter_rate() const { return fpga_master_clock_freq () * 2; } // 128M
00964   long dac_rate() const { return converter_rate(); }
00965   int daughterboard_id (int which_side) const { return d_dbid[which_side & 0x1]; }
00966 
00967   bool set_pga (int which_amp, double gain_in_db);
00968   double pga (int which_amp) const;
00969   double pga_min () const;
00970   double pga_max () const;
00971   double pga_db_per_step () const;
00972 
00973   bool _write_oe (int which_side, int value, int mask);
00974   bool write_io (int which_side, int value, int mask);
00975   bool read_io (int which_side, int *value);
00976   int read_io (int which_side);
00977   bool write_refclk(int which_side, int value);
00978   bool write_atr_mask(int which_side, int value);
00979   bool write_atr_txval(int which_side, int value);
00980   bool write_atr_rxval(int which_side, int value);
00981 
00982   bool write_aux_dac (int which_side, int which_dac, int value);
00983   bool read_aux_adc (int which_side, int which_adc, int *value);
00984   int read_aux_adc (int which_side, int which_adc);
00985 
00986   int block_size() const;
00987 
00988   // called in base class to derived class order
00989   bool start ();
00990   bool stop ();
00991 };
00992 
00993 #endif /* INCLUDED_USRP_BASIC_H */