On Fri, Sep 22, 2006 at 10:44:36PM -0600, Bdale Garbee wrote:
> Working on interfacing an external 1296 Mhz transverter to one of my USRPs 
> with basic RX and basic TX daughter cards.  Has anyone already done something 
> like this and established a "standard" way of implementing TX/RX switching?  
> Or do I just randomly pick one of the controllable bits to drive the 
> sequencer's push to talk input?
> 
> Bdale

Hi Bdale,

Two ways come to mind:

(1) just grab an i/o pin, output enable it, and wiggle as you please.

Here are the C++ centric docs

  /*!
   * \brief Write direction register (output enables) for pins that go to 
daughterboard.
   *
   * \param which_dboard        [0,1] which d'board
   * \param value               value to write into register
   * \param mask                which bits of value to write into reg
   *
   * Each d'board has 16-bits of general purpose i/o.
   * Setting the bit makes it an output from the FPGA to the d'board.
   *
   * This register is initialized based on a value stored in the
   * d'board EEPROM.  In general, you shouldn't be using this routine
   * without a very good reason.  Using this method incorrectly will
   * kill your USRP motherboard and/or daughterboard.
   */
  bool _write_oe (int which_dboard, int value, int mask);

  /*!
   * \brief Write daughterboard i/o pin value
   *
   * \param which_dboard        [0,1] which d'board
   * \param value               value to write into register
   * \param mask                which bits of value to write into reg
   */
  bool write_io (int which_dboard, int value, int mask);

  /*!
   * \brief Read daughterboard i/o pin value
   *
   * \param which_dboard        [0,1] which d'board
   * \returns register value if successful, else READ_FAILED
   */
  int read_io (int which_dboard);


In python it looks like:

  u_rx = usrp.source_c(...)
  u_rx.subdev = ...

 # make all pins on the RX d'board on selected side outputs
 u_rx._write_oe(u_rx.subdev._which, 0xffff, 0xffff)

This works with either the sink or source.

Etc.



(2) Take advantage of the hooks for "auto T/R switching".  
The RFX boards use this, but it's ignored by the basic tx and rx.

Here are the low level details extracted from
usrp/firmware/include/fpga_regs_common.h:

    # ------------------------------------------------------------------------
    # Automatic Transmit/Receive switching
    #
    # The presence or absence of data in the FPGA transmit fifo
    # selects between two sets of values for each of the 4 banks of
    # daughterboard i/o pins.
    #
    # Each daughterboard slot has 3 16-bit registers associated with it:
    #   FR_ATR_MASK_*, FR_ATR_TXVAL_* and FR_ATR_RXVAL_*
    #
    # FR_ATR_MASK_{0,1,2,3}: 
    #
    #   These registers determine which of the daugherboard i/o pins are
    #   affected by ATR switching.  If a bit in the mask is set, the
    #   corresponding i/o bit is controlled by ATR, else it's output
    #   value comes from the normal i/o pin output register:
    #   FR_IO_{0,1,2,3}.
    #
    # FR_ATR_TXVAL_{0,1,2,3}:
    # FR_ATR_RXVAL_{0,1,2,3}:
    #
    #   If the Tx fifo contains data, then the bits from TXVAL that are
    #   selected by MASK are output.  Otherwise, the bits from RXVAL that
    #   are selected by MASK are output.


Assuming you've opened the USRP as normal, call the selected subdev
methods like this:

    u_tx = usrp.sink_c(...)
    u_tx.subdev = ...

    u_tx.subdev.set_atr_mask (XXX)
    u_tx.subdev.set_atr_txval(YYY)
    u_tx.subdev.set_atr_rxval(ZZZ)

There are separate regs for the Tx and Rx halves, so depending on
which pins you want to watch, call this on either u_tx or u_rx.

Also, you still have to output enable the relevant pins as above.


Now of course, all this depends on your application "stalling" the
transmit path unless it's got something to do.  I seem to recall
that somebody built a "stall" block, but in looking through "general",
I don't see it.  Does this sound familiar to anyone?  Johnathan,
weren't you looking at this?  (It might have been a mute/squelch
block, with the same idea).


As I recall it was going to work like this:

  stall = gr.stall(sizeof_item)

  ... 
  stall.set_stall(True)       # Causes the block to consume all input,
                              # but produce no output

  ...
  stall.set_stall(False)      # block copies input to output, producing
                              # and consuming in the normal way

Then your "push to talk" button would just call the set_stall method
as appropriate.

Eric


_______________________________________________
Discuss-gnuradio mailing list
Discuss-gnuradio@gnu.org
http://lists.gnu.org/mailman/listinfo/discuss-gnuradio

Reply via email to