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