Imported Upstream version 3.2.2
[debian/gnuradio] / usrp / host / lib / legacy / usrp_standard.h
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004,2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifndef INCLUDED_USRP_STANDARD_H
24 #define INCLUDED_USRP_STANDARD_H
25
26 #include <usrp_basic.h>
27 #include <boost/shared_ptr.hpp>
28 #include <usrp_tune_result.h>
29
30 class usrp_standard_tx;
31 class usrp_standard_rx;
32
33 typedef boost::shared_ptr<usrp_standard_tx> usrp_standard_tx_sptr;
34 typedef boost::shared_ptr<usrp_standard_rx> usrp_standard_rx_sptr;
35
36 /*!
37  * \ingroup usrp
38  */
39 class usrp_standard_common
40 {
41   int   d_fpga_caps;            // capability register val
42
43 protected:
44   usrp_standard_common(usrp_basic *parent);
45
46 public:
47   /*!
48    *\brief does the FPGA implement the final Rx half-band filter?
49    * If it doesn't, the maximum decimation factor with proper gain 
50    * is 1/2 of what it would otherwise be.
51    */
52   bool has_rx_halfband() const;
53
54   /*!
55    * \brief number of digital downconverters implemented in the FPGA
56    * This will be 0, 1, 2 or 4.
57    */
58   int nddcs() const;
59
60   /*!
61    *\brief does the FPGA implement the initial Tx half-band filter?
62    */
63   bool has_tx_halfband() const;
64
65   /*!
66    * \brief number of digital upconverters implemented in the FPGA
67    * This will be 0, 1, or 2.
68    */
69   int nducs() const;
70
71   /*!
72    * \brief Calculate the frequency to use for setting the digital up or down converter.
73    *
74    * \param target_freq is the desired RF frequency (Hz).
75    * \param baseband_freq is the RF frequency that corresponds to DC in the IF coming from the d'board.
76    * \param  fs is the sampling frequency.
77    * \param[out] dxc_freq the frequency to program into the DDC (or DUC).
78    * \param[out] inverted is true if we're operating in an inverted Nyquist zone.
79    */
80   static void calc_dxc_freq(double target_freq, double baseband_freq, double fs,
81                             double *dxc_freq, bool *inverted);
82 };
83
84 /*!
85  * \brief The C++ interface the receive side of the USRP
86  * \ingroup usrp
87  *
88  * This is the recommended interface to USRP receive functionality
89  * for applications that use the USRP but not GNU Radio.
90  */
91 class usrp_standard_rx : public usrp_basic_rx, public usrp_standard_common
92 {
93  private:
94   static const int      MAX_CHAN = 4;
95   unsigned int          d_decim_rate;
96   int                   d_nchan;
97   int                   d_sw_mux;
98   int                   d_hw_mux;
99   double                d_rx_freq[MAX_CHAN];
100
101  protected:
102   usrp_standard_rx (int which_board,
103                     unsigned int decim_rate,
104                     int nchan = 1,
105                     int mux = -1,
106                     int mode = 0,
107                     int fusb_block_size = 0,
108                     int fusb_nblocks = 0,
109                     const std::string fpga_filename = "",
110                     const std::string firmware_filename = ""
111                     );  // throws if trouble
112
113   bool write_hw_mux_reg ();
114
115  public:
116
117   enum {
118     FPGA_MODE_NORMAL     = 0x00,
119     FPGA_MODE_LOOPBACK   = 0x01,
120     FPGA_MODE_COUNTING   = 0x02,
121     FPGA_MODE_COUNTING_32BIT   = 0x04
122   };
123
124   ~usrp_standard_rx ();
125
126   /*!
127    * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble
128    *
129    * \param which_board      Which USRP board on usb (not particularly useful; use 0)
130    * \param decim_rate       decimation factor
131    * \param nchan            number of channels
132    * \param mux              Rx mux setting, \sa set_mux
133    * \param mode             mode
134    * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
135    *                         Use zero for a reasonable default.
136    * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
137    * \param fpga_filename    Name of rbf file to load
138    * \param firmware_filename Name of ihx file to load
139    */
140   static usrp_standard_rx_sptr make(int which_board,
141                                     unsigned int decim_rate,
142                                     int nchan = 1,
143                                     int mux = -1,
144                                     int mode = 0,
145                                     int fusb_block_size = 0,
146                                     int fusb_nblocks = 0,
147                                     const std::string fpga_filename = "",
148                                     const std::string firmware_filename = ""
149                                     );
150   /*!
151    * \brief Set decimator rate.  \p rate MUST BE EVEN and in [8, 256].
152    *
153    * The final complex sample rate across the USB is
154    *   adc_freq () / decim_rate () * nchannels ()
155    */
156   bool set_decim_rate  (unsigned int rate);
157
158   /*!
159    * \brief Set number of active channels.  \p nchannels must be 1, 2 or 4.
160    *
161    * The final complex sample rate across the USB is
162    *   adc_freq () / decim_rate () * nchannels ()
163    */
164   bool set_nchannels (int nchannels);
165
166   /*!
167    * \brief Set input mux configuration.
168    *
169    * This determines which ADC (or constant zero) is connected to 
170    * each DDC input.  There are 4 DDCs.  Each has two inputs.
171    *
172    * <pre>
173    * Mux value:
174    *
175    *    3                   2                   1                       
176    *  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
177    * +-------+-------+-------+-------+-------+-------+-------+-------+
178    * |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
179    * +-------+-------+-------+-------+-------+-------+-------+-------+
180    *
181    * Each 4-bit I field is either 0,1,2,3
182    * Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
183    * All Q's must be 0xf or none of them may be 0xf
184    * </pre>
185    */
186   bool set_mux  (int mux);
187
188   /*!
189    * Determine the appropriate Rx mux value as a function of the subdevice choosen
190    * and the characteristics of the respective daughterboard.
191    */
192   int determine_rx_mux_value(const usrp_subdev_spec &ss);
193   int determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
194
195   /*!
196    * \brief set the frequency of the digital down converter.
197    *
198    * \p channel must be in the range [0,3].  \p freq is the center
199    * frequency in Hz.  \p freq may be either negative or postive.
200    * The frequency specified is quantized.  Use rx_freq to retrieve
201    * the actual value used.
202    */
203   bool set_rx_freq (int channel, double freq);  
204
205   /*!
206    * \brief set fpga mode
207    */
208   bool set_fpga_mode (int mode);
209
210   /*!
211    * \brief Set the digital down converter phase register.
212    *
213    * \param channel     which ddc channel [0, 3]
214    * \param phase       32-bit integer phase value.
215    */
216   bool set_ddc_phase(int channel, int phase);
217
218   /*!
219    * \brief Specify Rx data format.
220    *
221    * \param format      format specifier
222    *
223    * Rx data format control register
224    *
225    *     3                   2                   1                       
226    *   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
227    *  +-----------------------------------------+-+-+---------+-------+
228    *  |          Reserved (Must be zero)        |B|Q|  WIDTH  | SHIFT |
229    *  +-----------------------------------------+-+-+---------+-------+
230    *
231    *  SHIFT specifies arithmetic right shift [0, 15]
232    *  WIDTH specifies bit-width of I & Q samples across the USB [1, 16] (not all valid)
233    *  Q     if set deliver both I & Q, else just I
234    *  B     if set bypass half-band filter.
235    *
236    * Right now the acceptable values are:
237    *
238    *   B  Q  WIDTH  SHIFT
239    *   0  1    16     0
240    *   0  1     8     8
241    *
242    * More valid combos to come.
243    *
244    * Default value is 0x00000300  16-bits, 0 shift, deliver both I & Q.
245    */
246   bool set_format(unsigned int format);
247
248   static unsigned int make_format(int width=16, int shift=0,
249                                   bool want_q=true, bool bypass_halfband=false);
250   static int format_width(unsigned int format);
251   static int format_shift(unsigned int format);
252   static bool format_want_q(unsigned int format);
253   static bool format_bypass_halfband(unsigned int format);
254
255   /*!
256    * \brief High-level "tune" method.  Works for the single channel case.
257    *
258    * This method adjusts both the daughterboard LO and the DDC so that
259    * target_freq ends up at DC in the complex baseband samples.
260    *
261    * \param chan  which DDC channel we're controlling (almost always 0).
262    * \param db    the daughterboard we're controlling.
263    * \param target_freq the RF frequency we want at DC in the complex baseband.
264    * \param[out] result details how the hardware was configured.
265    *
266    * \returns true iff everything was successful.
267    */
268   bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
269   
270
271   // ACCESSORS
272   unsigned int decim_rate () const;
273   double rx_freq (int channel) const;
274   int nchannels () const;
275   int mux () const;
276   unsigned int format () const;
277
278   // called in base class to derived class order
279   bool start ();
280   bool stop ();
281 };
282
283 // ----------------------------------------------------------------
284
285 /*!
286  * \brief The C++ interface the transmit side of the USRP
287  * \ingroup usrp
288  *
289  * This is the recommended interface to USRP transmit functionality
290  * for applications that use the USRP but not GNU Radio.
291  *
292  * Uses digital upconverter (coarse & fine modulators) in AD9862...
293  */
294 class usrp_standard_tx : public usrp_basic_tx, public usrp_standard_common
295 {
296  public:
297   enum coarse_mod_t {
298     CM_NEG_FDAC_OVER_4,         // -32 MHz
299     CM_NEG_FDAC_OVER_8,         // -16 MHz
300     CM_OFF,
301     CM_POS_FDAC_OVER_8,         // +16 MHz
302     CM_POS_FDAC_OVER_4          // +32 MHz
303   };
304
305  protected:
306   static const int      MAX_CHAN = 2;
307   unsigned int          d_interp_rate;
308   int                   d_nchan;
309   int                   d_sw_mux;
310   int                   d_hw_mux;
311   double                d_tx_freq[MAX_CHAN];
312   coarse_mod_t          d_coarse_mod[MAX_CHAN];
313   unsigned char         d_tx_modulator_shadow[MAX_CHAN];
314
315   virtual bool set_coarse_modulator (int channel, coarse_mod_t cm);
316   usrp_standard_tx::coarse_mod_t coarse_modulator (int channel) const;
317
318  protected:
319   usrp_standard_tx (int which_board,
320                     unsigned int interp_rate,
321                     int nchan = 1,
322                     int mux = -1,
323                     int fusb_block_size = 0,
324                     int fusb_nblocks = 0,
325                     const std::string fpga_filename = "",
326                     const std::string firmware_filename = ""
327                     );  // throws if trouble
328
329   bool write_hw_mux_reg ();
330
331  public:
332   ~usrp_standard_tx ();
333
334   /*!
335    * \brief invokes constructor, returns shared_ptr or shared_ptr equivalent of 0 if trouble
336    *
337    * \param which_board      Which USRP board on usb (not particularly useful; use 0)
338    * \param interp_rate      interpolation factor
339    * \param nchan            number of channels
340    * \param mux              Tx mux setting, \sa set_mux
341    * \param fusb_block_size  fast usb xfer block size.  Must be a multiple of 512. 
342    *                         Use zero for a reasonable default.
343    * \param fusb_nblocks     number of fast usb URBs to allocate.  Use zero for a reasonable default. 
344    * \param fpga_filename    Name of rbf file to load
345    * \param firmware_filename Name of ihx file to load
346    */
347   static usrp_standard_tx_sptr make(int which_board,
348                                     unsigned int interp_rate,
349                                     int nchan = 1,
350                                     int mux = -1,
351                                     int fusb_block_size = 0,
352                                     int fusb_nblocks = 0,
353                                     const std::string fpga_filename = "",
354                                     const std::string firmware_filename = ""
355                                     );
356
357   /*!
358    * \brief Set interpolator rate.  \p rate must be in [4, 512] and a multiple of 4.
359    *
360    * The final complex sample rate across the USB is
361    *   dac_freq () / interp_rate () * nchannels ()
362    */
363   virtual bool set_interp_rate (unsigned int rate);
364
365   /*!
366    * \brief Set number of active channels.  \p nchannels must be 1 or 2.
367    *
368    * The final complex sample rate across the USB is
369    *   dac_freq () / decim_rate () * nchannels ()
370    */
371   bool set_nchannels  (int nchannels);
372
373   /*!
374    * \brief Set output mux configuration.
375    *
376    * <pre>
377    *     3                   2                   1                       
378    *   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
379    *  +-------------------------------+-------+-------+-------+-------+
380    *  |                               | DAC3  | DAC2  | DAC1  |  DAC0 |
381    *  +-------------------------------+-------+-------+-------+-------+
382    * 
383    *  There are two interpolators with complex inputs and outputs.
384    *  There are four DACs.
385    * 
386    *  Each 4-bit DACx field specifies the source for the DAC and
387    *  whether or not that DAC is enabled.  Each subfield is coded
388    *  like this: 
389    * 
390    *     3 2 1 0
391    *    +-+-----+
392    *    |E|  N  |
393    *    +-+-----+
394    * 
395    *  Where E is set if the DAC is enabled, and N specifies which
396    *  interpolator output is connected to this DAC.
397    * 
398    *   N   which interp output
399    *  ---  -------------------
400    *   0   chan 0 I
401    *   1   chan 0 Q
402    *   2   chan 1 I
403    *   3   chan 1 Q
404    * </pre>
405    */
406   bool set_mux  (int mux);
407
408   /*!
409    * Determine the appropriate Tx mux value as a function of the subdevice choosen
410    * and the characteristics of the respective daughterboard.
411    */
412   int determine_tx_mux_value(const usrp_subdev_spec &ss);
413   int determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b);
414
415   /*!
416    * \brief set the frequency of the digital up converter.
417    *
418    * \p channel must be in the range [0,1].  \p freq is the center
419    * frequency in Hz.  It must be in the range [-44M, 44M].
420    * The frequency specified is quantized.  Use tx_freq to retrieve
421    * the actual value used.
422    */
423   virtual bool set_tx_freq (int channel, double freq);  // chan: [0,1]
424
425   // ACCESSORS
426   unsigned int interp_rate () const;
427   double tx_freq (int channel) const;
428   int nchannels () const;
429   int mux () const;
430
431   /*!
432    * \brief High-level "tune" method.  Works for the single channel case.
433    *
434    * This method adjusts both the daughterboard LO and the DUC so that
435    * DC in the complex baseband samples ends up at RF target_freq.
436    *
437    * \param chan  which DUC channel we're controlling (usually == which_side).
438    * \param db    the daughterboard we're controlling.
439    * \param target_freq the RF frequency we want our baseband translated to.
440    * \param[out] result details how the hardware was configured.
441    *
442    * \returns true iff everything was successful.
443    */
444   bool tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result);
445
446
447   // called in base class to derived class order
448   bool start ();
449   bool stop ();
450 };
451
452 #endif /* INCLUDED_USRP_STANDARD_H */