From 13b2be45f22aa52304ef4918d7c7a8e84ffbf264 Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Wed, 9 Jun 2010 12:07:34 -0700
Subject: created capability for meta-registers

---
 host/lib/ic_reg_maps/common.py          | 53 +++++++++++++++++++++++++++++++--
 host/lib/ic_reg_maps/gen_ad9777_regs.py |  2 ++
 2 files changed, 53 insertions(+), 2 deletions(-)

(limited to 'host/lib')

diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py
index e27c2816d..173186eb1 100644
--- a/host/lib/ic_reg_maps/common.py
+++ b/host/lib/ic_reg_maps/common.py
@@ -80,6 +80,26 @@ $body
         return addrs;
     }
 
+    #for $mreg in $mregs
+    $mreg.get_type() get_$(mreg.get_name())(void){
+        return
+        #set $shift = 0
+        #for $reg in $mreg.get_regs()
+        ($(mreg.get_type())($reg.get_name() & $reg.get_mask()) << $shift) |
+            #set $shift = $shift + $reg.get_bit_width()
+        #end for
+        0;
+    }
+
+    void set_$(mreg.get_name())($mreg.get_type() reg){
+        #set $shift = 0
+        #for $reg in $mreg.get_regs()
+        $reg.get_name() = (reg >> $shift) & $reg.get_mask();
+            #set $shift = $shift + $reg.get_bit_width()
+        #end for
+    }
+
+    #end for
 private:
     $(name)_t *_state;
 };
@@ -90,7 +110,7 @@ private:
 def parse_tmpl(_tmpl_text, **kwargs):
     return str(Template(_tmpl_text, kwargs))
 
-def to_num(arg): return eval(arg)
+def to_num(arg): return int(eval(arg))
 
 class reg:
     def __init__(self, reg_des):
@@ -135,13 +155,42 @@ class reg:
     def get_mask(self): return hex(int('1'*self.get_bit_width(), 2))
     def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1
 
+class mreg:
+    def __init__(self, mreg_des, regs):
+        try: self.parse(mreg_des, regs)
+        except Exception, e:
+            raise Exception, 'Error parsing meta register description: "%s"\nWhat: %s'%(mreg_des, e)
+
+    def parse(self, mreg_des, regs):
+        x = re.match('^~(\w*)\s+(.*)\s*$', mreg_des)
+        self._name, reg_names = x.groups()
+        regs_dict = dict([(reg.get_name(), reg) for reg in regs])
+        self._regs = [regs_dict[reg_name] for reg_name in map(str.strip, reg_names.split(','))]
+
+    def get_name(self): return self._name
+    def get_regs(self): return self._regs
+    def get_bit_width(self): return sum(map(reg.get_bit_width, self._regs))
+    def get_type(self):
+        return 'boost::uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8)
+
 def generate(name, regs_tmpl, body_tmpl='', file=__file__):
-    regs = map(reg, parse_tmpl(regs_tmpl).splitlines())
+    #evaluate the regs template and parse each line into a register
+    regs = list(); mregs = list()
+    for entry in parse_tmpl(regs_tmpl).splitlines():
+        if entry.startswith('~'): mregs.append(mreg(entry, regs))
+        else:                     regs.append(reg(entry))
+
+    #evaluate the body template with the list of registers
     body = parse_tmpl(body_tmpl, regs=regs).replace('\n', '\n    ').strip()
+
+    #evaluate the code template with the parsed registers and arguments
     code = parse_tmpl(COMMON_TMPL,
         name=name,
         regs=regs,
+        mregs=mregs,
         body=body,
         file=file,
     )
+
+    #write the generated code to file specified by argv1
     open(sys.argv[1], 'w').write(code)
diff --git a/host/lib/ic_reg_maps/gen_ad9777_regs.py b/host/lib/ic_reg_maps/gen_ad9777_regs.py
index 690b15e24..47b61cf44 100755
--- a/host/lib/ic_reg_maps/gen_ad9777_regs.py
+++ b/host/lib/ic_reg_maps/gen_ad9777_regs.py
@@ -76,9 +76,11 @@ qdac_coarse_gain_adjust 0xA[0:3] 0
 ########################################################################
 idac_offset_adjust_msb  7[0:7]   0
 idac_offset_adjust_lsb  8[0:1]   0
+~idac_offset_adjust     idac_offset_adjust_lsb, idac_offset_adjust_msb
 idac_ioffset_direction  8[7]     0     out_a, out_b
 qdac_offset_adjust_msb  0xB[0:7] 0
 qdac_offset_adjust_lsb  0xC[0:1] 0
+~qdac_offset_adjust     qdac_offset_adjust_lsb, qdac_offset_adjust_msb
 qdac_ioffset_direction  0xC[7]   0     out_a, out_b
 """
 
-- 
cgit v1.2.3


From f73a3688069b69327f6837871e0b524125c67038 Mon Sep 17 00:00:00 2001
From: Jason Abele <jason@ettus.com>
Date: Fri, 11 Jun 2010 18:22:01 -0700
Subject: Fixed USRP2 aux_dac numbering convention

---
 host/lib/ic_reg_maps/CMakeLists.txt     |  4 +--
 host/lib/ic_reg_maps/gen_ad5623_regs.py | 48 +++++++++++++++++++++++++++++++++
 host/lib/ic_reg_maps/gen_ad5624_regs.py | 48 ---------------------------------
 host/lib/usrp/dboard/db_rfx.cpp         |  2 +-
 host/lib/usrp/usrp2/dboard_iface.cpp    | 24 +++++++++--------
 5 files changed, 64 insertions(+), 62 deletions(-)
 create mode 100755 host/lib/ic_reg_maps/gen_ad5623_regs.py
 delete mode 100755 host/lib/ic_reg_maps/gen_ad5624_regs.py

(limited to 'host/lib')

diff --git a/host/lib/ic_reg_maps/CMakeLists.txt b/host/lib/ic_reg_maps/CMakeLists.txt
index 63378eb89..ba1bbc9f0 100644
--- a/host/lib/ic_reg_maps/CMakeLists.txt
+++ b/host/lib/ic_reg_maps/CMakeLists.txt
@@ -40,8 +40,8 @@ LIBUHD_PYTHON_GEN_SOURCE(
 )
 
 LIBUHD_PYTHON_GEN_SOURCE(
-    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad5624_regs.py
-    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad5624_regs.hpp
+    ${CMAKE_SOURCE_DIR}/lib/ic_reg_maps/gen_ad5623_regs.py
+    ${CMAKE_BINARY_DIR}/lib/ic_reg_maps/ad5623_regs.hpp
 )
 
 LIBUHD_PYTHON_GEN_SOURCE(
diff --git a/host/lib/ic_reg_maps/gen_ad5623_regs.py b/host/lib/ic_reg_maps/gen_ad5623_regs.py
new file mode 100755
index 000000000..e653921ba
--- /dev/null
+++ b/host/lib/ic_reg_maps/gen_ad5623_regs.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 Ettus Research LLC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+########################################################################
+# Template for raw text data describing registers
+# name addr[bit range inclusive] default optional enums
+########################################################################
+REGS_TMPL="""\
+data             0[4:15]           0
+addr             0[16:18]          0       DAC_A=0, DAC_B=1, ALL=7
+cmd              0[19:21]          0       wr_input_n, up_dac_n, wr_input_n_up_all, wr_up_dac_chan_n, power_down, reset, load_ldac
+"""
+
+########################################################################
+# Template for methods in the body of the struct
+########################################################################
+BODY_TMPL="""\
+boost::uint32_t get_reg(void){
+    boost::uint32_t reg = 0;
+    #for $reg in filter(lambda r: r.get_addr() == 0, $regs)
+    reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();
+    #end for
+    return reg;
+}
+"""
+
+if __name__ == '__main__':
+    import common; common.generate(
+        name='ad5623_regs',
+        regs_tmpl=REGS_TMPL,
+        body_tmpl=BODY_TMPL,
+        file=__file__,
+    )
diff --git a/host/lib/ic_reg_maps/gen_ad5624_regs.py b/host/lib/ic_reg_maps/gen_ad5624_regs.py
deleted file mode 100755
index 24401b878..000000000
--- a/host/lib/ic_reg_maps/gen_ad5624_regs.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010 Ettus Research LLC
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-########################################################################
-# Template for raw text data describing registers
-# name addr[bit range inclusive] default optional enums
-########################################################################
-REGS_TMPL="""\
-data             0[4:15]           0
-addr             0[16:18]          0       DAC_A=0, DAC_B=1, DAC_C=2, DAC_D=3, ALL=7
-cmd              0[19:21]          0       wr_input_n, up_dac_n, wr_input_n_up_all, wr_up_dac_chan_n, power_down, reset, load_ldac
-"""
-
-########################################################################
-# Template for methods in the body of the struct
-########################################################################
-BODY_TMPL="""\
-boost::uint32_t get_reg(void){
-    boost::uint32_t reg = 0;
-    #for $reg in filter(lambda r: r.get_addr() == 0, $regs)
-    reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift();
-    #end for
-    return reg;
-}
-"""
-
-if __name__ == '__main__':
-    import common; common.generate(
-        name='ad5624_regs',
-        regs_tmpl=REGS_TMPL,
-        body_tmpl=BODY_TMPL,
-        file=__file__,
-    )
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 17fc00d24..2585dfa8d 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -257,7 +257,7 @@ void rfx_xcvr::set_rx_gain(float gain, const std::string &name){
         _rx_gains[name] = gain;
 
         //write the new voltage to the aux dac
-        this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, 1, dac_volts);
+        this->get_iface()->write_aux_dac(dboard_iface::UNIT_RX, 0, dac_volts);
     }
     else UHD_THROW_INVALID_CODE_PATH();
 }
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index 9f7c7f9e6..244f502a4 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -25,7 +25,7 @@
 #include <boost/asio.hpp> //htonl and ntohl
 #include <boost/math/special_functions/round.hpp>
 #include "ad7922_regs.hpp" //aux adc
-#include "ad5624_regs.hpp" //aux dac
+#include "ad5623_regs.hpp" //aux dac
 
 using namespace uhd;
 using namespace uhd::usrp;
@@ -72,7 +72,7 @@ private:
     boost::uint32_t _ddr_shadow;
     boost::uint32_t _gpio_shadow;
 
-    uhd::dict<unit_t, ad5624_regs_t> _dac_regs;
+    uhd::dict<unit_t, ad5623_regs_t> _dac_regs;
     void _write_aux_dac(unit_t);
 };
 
@@ -99,12 +99,12 @@ usrp2_dboard_iface::usrp2_dboard_iface(
     _gpio_shadow = 0;
 
     //reset the aux dacs
-    _dac_regs[UNIT_RX] = ad5624_regs_t();
-    _dac_regs[UNIT_TX] = ad5624_regs_t();
+    _dac_regs[UNIT_RX] = ad5623_regs_t();
+    _dac_regs[UNIT_TX] = ad5623_regs_t();
     BOOST_FOREACH(unit_t unit, _dac_regs.keys()){
         _dac_regs[unit].data = 1;
-        _dac_regs[unit].addr = ad5624_regs_t::ADDR_ALL;
-        _dac_regs[unit].cmd  = ad5624_regs_t::CMD_RESET;
+        _dac_regs[unit].addr = ad5623_regs_t::ADDR_ALL;
+        _dac_regs[unit].cmd  = ad5623_regs_t::CMD_RESET;
         this->_write_aux_dac(unit);
     }
 }
@@ -242,12 +242,14 @@ void usrp2_dboard_iface::_write_aux_dac(unit_t unit){
 
 void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, float value){
     _dac_regs[unit].data = boost::math::iround(4095*value/3.3);
-    _dac_regs[unit].cmd = ad5624_regs_t::CMD_WR_UP_DAC_CHAN_N;
+    _dac_regs[unit].cmd = ad5623_regs_t::CMD_WR_UP_DAC_CHAN_N;
+    //standardize on USRP1 interface, A=0, B=1, C=2, D=3
+    //FIXME josh reccommends the use of a nested dictionary
     switch(which){
-    case 0: _dac_regs[unit].addr = ad5624_regs_t::ADDR_DAC_A; break;
-    case 1: _dac_regs[unit].addr = ad5624_regs_t::ADDR_DAC_B; break;
-    case 2: _dac_regs[unit].addr = ad5624_regs_t::ADDR_DAC_C; break;
-    case 3: _dac_regs[unit].addr = ad5624_regs_t::ADDR_DAC_D; break;
+    case 0: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_B : ad5623_regs_t::ADDR_DAC_A; break;
+    case 1: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_A : ad5623_regs_t::ADDR_DAC_B; break;
+    case 2: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_A : ad5623_regs_t::ADDR_DAC_B; break;
+    case 3: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_B : ad5623_regs_t::ADDR_DAC_A; break;
     default: throw std::runtime_error("not a possible aux dac, must be 0, 1, 2, or 3");
     }
     this->_write_aux_dac(unit);
-- 
cgit v1.2.3


From 0c6fbdfe3738e2d15b369fbd28d51ee0115628f9 Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Mon, 14 Jun 2010 10:44:50 -0700
Subject: work on algorithms and documentation

---
 host/include/uhd/utils/algorithm.hpp | 72 ++++++++++++++++++++++++++++++++----
 host/lib/device.cpp                  |  8 +---
 host/lib/usrp/tune_helper.cpp        |  2 +-
 3 files changed, 68 insertions(+), 14 deletions(-)

(limited to 'host/lib')

diff --git a/host/include/uhd/utils/algorithm.hpp b/host/include/uhd/utils/algorithm.hpp
index 146b56c63..08977a69f 100644
--- a/host/include/uhd/utils/algorithm.hpp
+++ b/host/include/uhd/utils/algorithm.hpp
@@ -19,31 +19,89 @@
 #define INCLUDED_UHD_UTILS_ALGORITHM_HPP
 
 #include <algorithm>
-#include <boost/range/functions.hpp>
+#include <boost/range/begin.hpp>
+#include <boost/range/end.hpp>
+#include <boost/range/size.hpp>
 
-/*!
- * Useful templated functions and classes that I like to pretend are part of stl
+/*! \file algorithm.hpp
+ * Useful templated functions and classes that I like to pretend are part of stl.
+ * Many of the range wrapper functions come with recent versions of boost (1.43).
  */
 namespace std{
 
+    /*!
+     * A wrapper around std::copy that takes ranges instead of iterators.
+     *
+     * Copy the elements of the source range into the destination range.
+     * The destination range should be at least as large as the source range.
+     *
+     * \param src the range of elements to copy from
+     * \param dst the range of elements to be filled
+     */
     template<typename RangeSrc, typename RangeDst> inline
     void copy(const RangeSrc &src, RangeDst &dst){
         std::copy(boost::begin(src), boost::end(src), boost::begin(dst));
     }
 
+    /*!
+     * A wrapper around std::sort that takes a range instead of an iterator.
+     *
+     * The elements are sorted into ascending order using the less-than operator.
+     *
+     * \param range the range of elements to be sorted
+     */
+    template<typename Range> inline void sort(Range &range){
+        return std::sort(boost::begin(range), boost::end(range));
+    }
+
+    /*!
+     * A wrapper around std::sort that takes a range instead of an iterator.
+     *
+     * The elements are sorted into ascending order using the less-than operator.
+     * This wrapper sorts the elements non-destructively into a new range.
+     * Based on the builtin python function sorted(...)
+     *
+     * \param range the range of elements to be sorted
+     * \return a new range with the elements sorted
+     */
+    template<typename Range> inline Range sorted(const Range &range){
+        Range srange(range); std::sort(srange); return srange;
+    }
+
+    /*!
+     * Is the value found within the elements in this range?
+     *
+     * Uses std::find to search the iterable for an element.
+     *
+     * \param range the elements to search through
+     * \param value the match to look for in the range
+     * \return true when the value is found in the range
+     */
     template<typename Range, typename T> inline
     bool has(const Range &range, const T &value){
         return boost::end(range) != std::find(boost::begin(range), boost::end(range), value);
     }
 
-    template<typename T> inline T signum(T n){
+    /*!
+     * A templated signum implementation.
+     * \param n the comparable to process
+     * \return -1 when n negative, +1 when n positive, otherwise 0
+     */
+    template<typename T> inline int signum(T n){
         if (n < 0) return -1;
-        if (n > 0) return 1;
+        if (n > 0) return +1;
         return 0;
     }
 
-    template<typename T> inline T clip(T val, T minVal, T maxVal){
-        return std::min(std::max(val, minVal), maxVal);
+    /*!
+     * A templated clip implementation.
+     * \param val the value to clip between an upper and lower limit
+     * \param bound1 the upper or lower bound
+     * \param bound2 the upper or lower bound
+     * \return the value clipped at the bounds
+     */
+    template<typename T> inline T clip(T val, T bound1, T bound2){
+        return std::min(std::max(val, std::min(bound1, bound2)), std::max(bound1, bound2));
     }
 
 }//namespace std
diff --git a/host/lib/device.cpp b/host/lib/device.cpp
index f139ecb20..431595c4f 100644
--- a/host/lib/device.cpp
+++ b/host/lib/device.cpp
@@ -19,13 +19,13 @@
 #include <uhd/types/dict.hpp>
 #include <uhd/utils/assert.hpp>
 #include <uhd/utils/static.hpp>
+#include <uhd/utils/algorithm.hpp>
 #include <boost/foreach.hpp>
 #include <boost/format.hpp>
 #include <boost/weak_ptr.hpp>
 #include <boost/functional/hash.hpp>
 #include <boost/tuple/tuple.hpp>
 #include <stdexcept>
-#include <algorithm>
 
 using namespace uhd;
 
@@ -41,13 +41,9 @@ using namespace uhd;
 static size_t hash_device_addr(
     const device_addr_t &dev_addr
 ){
-    //sort the keys of the device address
-    std::vector<std::string> keys = dev_addr.keys();
-    std::sort(keys.begin(), keys.end());
-
     //combine the hashes of sorted keys/value pairs
     size_t hash = 0;
-    BOOST_FOREACH(const std::string &key, keys){
+    BOOST_FOREACH(const std::string &key, std::sorted(dev_addr.keys())){
         boost::hash_combine(hash, key);
         boost::hash_combine(hash, dev_addr[key]);
     }
diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp
index a7d695b4e..082c39f6d 100644
--- a/host/lib/usrp/tune_helper.cpp
+++ b/host/lib/usrp/tune_helper.cpp
@@ -46,7 +46,7 @@ static tune_result_t tune_xx_subdev_and_dxc(
     // Calculate the DDC setting that will downconvert the baseband from the
     // daughterboard to our target frequency.
     double delta_freq = target_freq - actual_inter_freq;
-    double delta_sign = std::signum(delta_freq);
+    int delta_sign = std::signum(delta_freq);
     delta_freq *= delta_sign;
     delta_freq = std::fmod(delta_freq, dxc_sample_rate);
     bool inverted = delta_freq > dxc_sample_rate/2.0;
-- 
cgit v1.2.3


From 00ca9fcc3d7645d3f1a9d7d767b8ccab110325bb Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Mon, 14 Jun 2010 18:32:23 -0700
Subject: usrp2: improved print-out for socket buffer sizing

---
 host/lib/transport/udp_zero_copy_asio.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

(limited to 'host/lib')

diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp
index ced606777..c3c02707e 100644
--- a/host/lib/transport/udp_zero_copy_asio.cpp
+++ b/host/lib/transport/udp_zero_copy_asio.cpp
@@ -148,9 +148,12 @@ template<typename Opt> static void resize_buff_helper(
     if (target_size > 0){
         size_t actual_size = udp_trans->resize_buff<Opt>(target_size);
         if (target_size != actual_size) std::cout << boost::format(
-            "Target %s buffer size: %d\n"
-            "Actual %s byffer size: %d"
+            "Target %s sock buff size: %d bytes\n"
+            "Actual %s sock buff size: %d bytes"
         ) % name % target_size % name % actual_size << std::endl;
+        else std::cout << boost::format(
+            "Current %s sock buff size: %d bytes"
+        ) % name % actual_size << std::endl;
     }
 
     //otherwise, ensure that the buffer is at least the minimum size
-- 
cgit v1.2.3


From 73ea268536e83b8961bea4a0f825ac68f3da2f2b Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Mon, 14 Jun 2010 18:47:22 -0700
Subject: usrp2: dboard iface: switched to nested dictionary for dac regs

---
 host/lib/usrp/usrp2/dboard_iface.cpp | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

(limited to 'host/lib')

diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index 244f502a4..114f83f41 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -244,14 +244,23 @@ void usrp2_dboard_iface::write_aux_dac(unit_t unit, int which, float value){
     _dac_regs[unit].data = boost::math::iround(4095*value/3.3);
     _dac_regs[unit].cmd = ad5623_regs_t::CMD_WR_UP_DAC_CHAN_N;
     //standardize on USRP1 interface, A=0, B=1, C=2, D=3
-    //FIXME josh reccommends the use of a nested dictionary
-    switch(which){
-    case 0: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_B : ad5623_regs_t::ADDR_DAC_A; break;
-    case 1: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_A : ad5623_regs_t::ADDR_DAC_B; break;
-    case 2: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_A : ad5623_regs_t::ADDR_DAC_B; break;
-    case 3: _dac_regs[unit].addr = unit == dboard_iface::UNIT_RX ? ad5623_regs_t::ADDR_DAC_B : ad5623_regs_t::ADDR_DAC_A; break;
-    default: throw std::runtime_error("not a possible aux dac, must be 0, 1, 2, or 3");
-    }
+    static const uhd::dict<
+        unit_t, uhd::dict<int, ad5623_regs_t::addr_t>
+    > unit_to_which_to_addr = map_list_of
+        (UNIT_RX, map_list_of
+            (0, ad5623_regs_t::ADDR_DAC_B)
+            (1, ad5623_regs_t::ADDR_DAC_A)
+            (2, ad5623_regs_t::ADDR_DAC_A)
+            (3, ad5623_regs_t::ADDR_DAC_B)
+        )
+        (UNIT_TX, map_list_of
+            (0, ad5623_regs_t::ADDR_DAC_A)
+            (1, ad5623_regs_t::ADDR_DAC_B)
+            (2, ad5623_regs_t::ADDR_DAC_B)
+            (3, ad5623_regs_t::ADDR_DAC_A)
+        )
+    ;
+    _dac_regs[unit].addr = unit_to_which_to_addr[unit][which];
     this->_write_aux_dac(unit);
 }
 
-- 
cgit v1.2.3


From ca6417739de4e5344325e96887dcdbf8311e265b Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Tue, 15 Jun 2010 15:06:18 -0700
Subject: uhd: added ability to boost rt priority, added general app notes

---
 host/docs/CMakeLists.txt |  1 +
 host/docs/general.rst    | 79 ++++++++++++++++++++++++++++++++++++++++++++++++
 host/docs/index.rst      |  3 +-
 host/lib/CMakeLists.txt  | 16 ++++++++++
 host/lib/sched.cpp       | 45 +++++++++++++++++++++++++++
 5 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100644 host/docs/general.rst
 create mode 100644 host/lib/sched.cpp

(limited to 'host/lib')

diff --git a/host/docs/CMakeLists.txt b/host/docs/CMakeLists.txt
index 61eede8b7..d0041f71c 100644
--- a/host/docs/CMakeLists.txt
+++ b/host/docs/CMakeLists.txt
@@ -23,6 +23,7 @@ SET(manual_sources
     build.rst
     coding.rst
     dboards.rst
+    general.rst
     usrp2.rst
 )
 
diff --git a/host/docs/general.rst b/host/docs/general.rst
new file mode 100644
index 000000000..7d1f467a0
--- /dev/null
+++ b/host/docs/general.rst
@@ -0,0 +1,79 @@
+========================================================================
+UHD - General Application Notes
+========================================================================
+
+.. contents:: Table of Contents
+
+------------------------------------------------------------------------
+Finding devices
+------------------------------------------------------------------------
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Device addressing
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Deviced are addressed through key/value string pairs.
+These string pairs can be used to narrow down the search for a specific device or group of devices.
+Most UHD utility applications and examples have a --args parameter that takes a device address;
+where the device address is expressed as a delimited string.
+
+* See the documentation in types/device_addr.hpp for reference.
+* See device-specific application notes for usage.
+
+**Example:**
+::
+
+    serial=0x1234, type=usrpx
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Device discovery
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Devices attached to your system can be discovered using the "uhd_find_devices" program.
+The find devices program scans your system for supported devices and prints
+out an enumerated list of discovered devices and their addresses.
+The list of discovered devices can be narrowed down by specifying device address args.
+
+**Usage:**
+::
+
+    uhd_find_devices
+
+    -- OR --
+
+    uhd_find_devices --args <device-specific-address-args>
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Device properties
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Properties of devices attached to your system can be probed with the "uhd_usrp_probe" program.
+The usrp probe program contructs an instance of the device and prints out its properties;
+properties such as detected daughter-boards, frequency range, gain ranges, etc...
+
+**Usage:**
+::
+
+    uhd_usrp_probe --args <device-specific-address-args>
+
+------------------------------------------------------------------------
+Misc notes
+------------------------------------------------------------------------
+
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Process scheduling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The UHD will try to automatically boost the process's scheduling priority.
+Currently, this is only supported on platforms with *sched.h*.
+
+When setting the priority fails, the UHD prints out an error.
+This error is harmless, it simply means that your process will have a normal scheduling priority.
+
+**Linux Notes:**
+
+Non-privileged users need special permission to change the scheduling priority.
+Add the following line to */etc/security/limits.conf*:
+::
+
+    @<my_group>    -    rtprio    99
+
+Replace <my_group> with a group to which your user belongs.
+Settings will not take effect until the user has logged in and out.
diff --git a/host/docs/index.rst b/host/docs/index.rst
index 3dc7a2d98..b31a3d0ac 100644
--- a/host/docs/index.rst
+++ b/host/docs/index.rst
@@ -18,8 +18,9 @@ Building the UHD
 * `Build Guide <./build.html>`_
 
 ^^^^^^^^^^^^^^^^^^^^^
-Supported Devices
+Application Notes
 ^^^^^^^^^^^^^^^^^^^^^
+* `General App Notes <./general.html>`_
 * `USRP2 App Notes <./usrp2.html>`_
 * `Daughterboard App Notes <./dboards.html>`_
 
diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt
index 7b765b0d3..50787f6a2 100644
--- a/host/lib/CMakeLists.txt
+++ b/host/lib/CMakeLists.txt
@@ -73,6 +73,21 @@ INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/CMakeLists.txt)
 INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/dboard/CMakeLists.txt)
 INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/usrp/usrp2/CMakeLists.txt)
 
+########################################################################
+# Setup defines for process scheduling
+########################################################################
+MESSAGE(STATUS "Configuring process scheduling...")
+
+INCLUDE(CheckIncludeFileCXX)
+CHECK_INCLUDE_FILE_CXX(sched.h HAVE_SCHED_H)
+
+IF(HAVE_SCHED_H)
+    MESSAGE(STATUS "  Process scheduling supported through sched_setscheduler.")
+    ADD_DEFINITIONS(-DHAVE_SCHED_H)
+ELSE(HAVE_SCHED_H)
+    MESSAGE(STATUS "  Process scheduling not supported.")
+ENDIF(HAVE_SCHED_H)
+
 ########################################################################
 # Setup defines for module loading
 ########################################################################
@@ -99,6 +114,7 @@ LIBUHD_APPEND_SOURCES(
     ${CMAKE_CURRENT_SOURCE_DIR}/device.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/gain_handler.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/sched.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/wax.cpp
diff --git a/host/lib/sched.cpp b/host/lib/sched.cpp
new file mode 100644
index 000000000..712014c9c
--- /dev/null
+++ b/host/lib/sched.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/utils/static.hpp>
+#include <stdexcept>
+#include <iostream>
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+
+/*
+ * # /etc/security/limits.conf
+#
+@usrp   -       rtprio  99
+*/
+
+UHD_STATIC_BLOCK(setup_process_sched){
+    try{
+        int policy = SCHED_RR;
+        int max_pri = sched_get_priority_max(policy);
+        if (max_pri == -1) throw std::runtime_error("sched_get_priority_max with SCHED_RR failed");
+        sched_param sp; sp.sched_priority = max_pri;
+        int ss_ret = sched_setscheduler(0, policy, &sp);
+        if (ss_ret == -1) throw std::runtime_error("sched_setscheduler with SCHED_RR failed");
+    }
+    catch(const std::exception &e){
+        std::cerr << "Process scheduling error: " << e.what() << std::endl;
+    }
+}
+
+#endif /* HAVE_SCHED_H */
-- 
cgit v1.2.3