discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Discuss-gnuradio] CVS updates (automatic daughterboard handling)


From: Eric Blossom
Subject: [Discuss-gnuradio] CVS updates (automatic daughterboard handling)
Date: Wed, 21 Sep 2005 14:00:00 -0700
User-agent: Mutt/1.5.6i

I've just checked in a substantial set of updates that deal primarily
with automatically "doing the right thing" with the USRP and any
installed daughterboards.

The changes are in gnuradio-core, usrp, gr-usrp and gnuradio-examples.

The test case for these ideas is the revised usrp_fft.py.

It now looks like this:  http://comsec.com/images/usrp_fft_example.png

The fundamental thing to notice is that it allows you to tune and set
the gain.  This works regardless of what daughterboards you have
installed, and reflects the frequency and gain ranges of the
daughterboard subdevice selected on the command line.

In general, you specify the "side" and "subdevice" using the -S
command line parameter.  In the typical case, just use -S a or -S b.

Conceptually, Tx and Rx daughterboards can be split into two general
categories: 

  Those that use both converters as a pair (boards doing quadrature up
  or down conversion) and those that can use the converters
  independently.

Because we're using the digital up converter in the AD9862 in "Dual
Channel Complex DAC Data Mode", both D/A outputs are related (I&Q) and
as a result, all TX daughterboards are "quadrature" boards.

On the receive side we've got a bit more variation.

The TV_RX board is *not* a quadrature board, since it only uses a
single A/D.

On the FlexRF transceiver boards (400, 900, 1200 and 2400), both the
Tx side and Rx side are quadrature.

For the Basic Rx, it all depends on how you've got it hooked up and
how you're using it.  More about this later.


Subdevices.  A given Tx or Rx daughterboard consists of either one or
two subdevices.  Quadrature boards have a single subdevice.
Non-quadrature boards have one or two subdevices depending on the
daughterboard design.

The fundamental capabilities of a subdevice is the ability to tune and
set gain.  Each subdevice has a daughterboard specific class that is
derived from db_base.py (in gr-usrp).  The visible methods are:


    def dbid(self):
        """
        Returns integer daughterboard ID from EEPROM
        """

    def name(self):
        """
        Name of daughterboard.  E.g., "TV Rx"
        """

    def freq_range(self):
        """
        Return range of frequencies in Hz that can be tuned by this d'board.

        @returns (min_freq, max_freq, step_size)
        @rtype tuple
        """

    def set_freq(self, target_freq):
        """
        Set the frequency.

        @param freq:  target RF frequency in Hz
        @type freq:   float

        @returns (ok, actual_baseband_freq) where:
           ok is True or False and indicates success or failure,
           actual_baseband_freq is the RF frequency that corresponds to DC in 
the IF.
        """

    def gain_range(self):
        """
        Return range of gain that can be set by this d'board.

        @returns (min_gain, max_gain, step_size)
        Where gains are expressed in decibels (your mileage may vary)
        """

    def set_gain(self, gain):
        """
        Set the gain.

        @param gain:  gain in decibels
        @returns True/False
        """

    def is_quadrature(self):
        """
        Return True if this daughterboard does quadrature up or down conversion.
        That is, return True if this board requires both I & Q analog channels.

        This bit of info is useful when setting up the USRP Rx mux register.
        """


At this point, you're probably asking, why is he telling me all this...


As a result of these changes, when you create an instance of a usrp
source or sink, you now get an additional attribute, "db", that lets you
control the daughterboard subdevices.

   u = usrp.source_c(0, 64)

   u.db is a tuple of length 2.  

   u.db[0] contains a tuple of the subdevices for "side A"
   u.db[1] contains a tuple of the subdevices for "side B"

The tuples of subdevices each have either 1 or 2 elements depending on
the daughterboard installed on the respective side.  Each subdevice is
an instance of a class that's derived from db_base and exports the
methods listed above.


At this point, you have everything you need to control the daughterboards.

The -S command line option also has an "extended version" that allows
explicit selection of subdevices for cards with multiple subdevices.
Instead of just specifying, say -S a, you can specify -S a:0 or
-S a:1.


All this infrastruture has now made it possible to automatically
compute the appropriate Rx mux values given a user specified
subdevice specification.  This is implemented with a combination of
the option parser and the usrp.determine_rx_mux_value function.


        parser = OptionParser (option_class=eng_option)
        parser.add_option("-S", "--subdev", type="subdev", default=(0, None),
                          help="select USRP Rx side A or B (default=A)")
        ...

        (options, args) = parser.parse_args()

        self.u = usrp.source_c(0, options.decim, 1, 0, 0)
        self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.subdev))


Not bad, huh!

But wait, there's more!


When you're tuning, there are really at least two knobs to twist: 

  (1) Some kind of PLL on the daughterboard that 
      determines what RF frequency appears in the IF.

  (2) The digital downconverter that extracts the band of interest
      from the digitized IF.


Given a target frequency, we control them both like this:


    def set_freq(self, target_freq):
        """
        Set the center frequency we're interested in.

        @param target_freq: frequency in Hz
        @rypte: bool

        Tuning is a two step process.  First we ask the front-end to
        tune as close to the desired frequency as it can.  Then we use
        the result of that operation and our target_frequency to
        determine the value for the digital down converter.
        """

        # self.subdev is the subdevice we are controlling
        ok, baseband_freq = subdev.set_freq(target_freq)

        ddc_freq, inverted = usrp.calc_dxc_freq(target_freq, baseband_freq, 
self.u.converter_rate())

        ok &= self.u.set_rx_freq(0, ddc_freq)

 

That's the gist of the daughterboard stuff.


There's also a new wxgui.form class that automatically handles type
conversions, engineering notation and error checking.  It's used in
usrp_fft.py.  It may still evolve a bit, particular in how it
interacts with the wxPython sizers, but the basics should stay more or
less the same.


When I get back from DCC, I'll rework the examples to take advantage of
this stuff.  This will result in a big consolidation.


Let me know if you come across any problems.

Thanks,
Eric




reply via email to

[Prev in Thread] Current Thread [Next in Thread]