Revision d9035414

b/host/include/uhd/usrp/dboard_base.hpp
19 19
#define INCLUDED_UHD_USRP_DBOARD_BASE_HPP
20 20

  
21 21
#include <uhd/config.hpp>
22
#include <uhd/wax.hpp>
22
#include <uhd/property_tree.hpp>
23 23
#include <uhd/utils/pimpl.hpp>
24 24
#include <boost/utility.hpp>
25 25
#include <boost/shared_ptr.hpp>
......
28 28

  
29 29
namespace uhd{ namespace usrp{
30 30

  
31
    /*!
32
     * Possible subdev connection types:
33
     *
34
     * A complex subdevice is physically connected to both channels,
35
     * which may be connected in one of two ways: IQ or QI (swapped).
36
     *
37
     * A real subdevice is only physically connected one channel,
38
     * either only the I channel or only the Q channel.
39
     */
40
    enum subdev_conn_t{
41
        SUBDEV_CONN_COMPLEX_IQ = 'C',
42
        SUBDEV_CONN_COMPLEX_QI = 'c',
43
        SUBDEV_CONN_REAL_I     = 'R',
44
        SUBDEV_CONN_REAL_Q     = 'r'
45
    };
46

  
47
    /*!
48
     * Possible device subdev properties
49
     */
50
    enum subdev_prop_t{
51
        SUBDEV_PROP_NAME,               //ro, std::string
52
        SUBDEV_PROP_OTHERS,             //ro, prop_names_t
53
        SUBDEV_PROP_SENSOR,             //ro, sensor_value_t
54
        SUBDEV_PROP_SENSOR_NAMES,       //ro, prop_names_t
55
        SUBDEV_PROP_GAIN,               //rw, double
56
        SUBDEV_PROP_GAIN_RANGE,         //ro, gain_range_t
57
        SUBDEV_PROP_GAIN_NAMES,         //ro, prop_names_t
58
        SUBDEV_PROP_FREQ,               //rw, double
59
        SUBDEV_PROP_FREQ_RANGE,         //ro, freq_range_t
60
        SUBDEV_PROP_ANTENNA,            //rw, std::string
61
        SUBDEV_PROP_ANTENNA_NAMES,      //ro, prop_names_t
62
        SUBDEV_PROP_CONNECTION,         //ro, subdev_conn_t
63
        SUBDEV_PROP_ENABLED,            //rw, bool
64
        SUBDEV_PROP_USE_LO_OFFSET,      //ro, bool
65
        SUBDEV_PROP_BANDWIDTH           //rw, double
66
    };
67

  
68 31
/*!
69 32
 * A daughter board dboard_base class for all dboards.
70 33
 * Only other dboard dboard_base classes should inherit this.
......
81 44

  
82 45
    //structors
83 46
    dboard_base(ctor_args_t);
84
    virtual ~dboard_base(void);
85

  
86
    //interface
87
    virtual void rx_get(const wax::obj &key, wax::obj &val) = 0;
88
    virtual void rx_set(const wax::obj &key, const wax::obj &val) = 0;
89
    virtual void tx_get(const wax::obj &key, wax::obj &val) = 0;
90
    virtual void tx_set(const wax::obj &key, const wax::obj &val) = 0;
91 47

  
92 48
protected:
93 49
    std::string get_subdev_name(void);
94 50
    dboard_iface::sptr get_iface(void);
95 51
    dboard_id_t get_rx_id(void);
96 52
    dboard_id_t get_tx_id(void);
53
    property_tree::sptr get_rx_subtree(void);
54
    property_tree::sptr get_tx_subtree(void);
97 55

  
98 56
private:
99 57
    UHD_PIMPL_DECL(impl) _impl;
......
109 67
     * Create a new xcvr dboard object, override in subclasses.
110 68
     */
111 69
    xcvr_dboard_base(ctor_args_t);
112

  
113
    virtual ~xcvr_dboard_base(void);
114 70
};
115 71

  
116 72
/*!
......
123 79
     * Create a new rx dboard object, override in subclasses.
124 80
     */
125 81
    rx_dboard_base(ctor_args_t);
126

  
127
    virtual ~rx_dboard_base(void);
128

  
129
    //override here so the derived classes cannot
130
    void tx_get(const wax::obj &key, wax::obj &val);
131
    void tx_set(const wax::obj &key, const wax::obj &val);
132 82
};
133 83

  
134 84
/*!
......
141 91
     * Create a new rx dboard object, override in subclasses.
142 92
     */
143 93
    tx_dboard_base(ctor_args_t);
144

  
145
    virtual ~tx_dboard_base(void);
146

  
147
    //override here so the derived classes cannot
148
    void rx_get(const wax::obj &key, wax::obj &val);
149
    void rx_set(const wax::obj &key, const wax::obj &val);
150 94
};
151 95

  
152 96
}} //namespace
b/host/include/uhd/usrp/dboard_manager.hpp
20 20

  
21 21
#include <uhd/config.hpp>
22 22
#include <uhd/property_tree.hpp>
23
#include <uhd/utils/props.hpp>
24 23
#include <uhd/usrp/dboard_base.hpp>
25 24
#include <uhd/usrp/dboard_id.hpp>
26 25
#include <boost/utility.hpp>
27 26
#include <boost/shared_ptr.hpp>
27
#include <string>
28
#include <vector>
28 29

  
29 30
namespace uhd{ namespace usrp{
30 31

  
......
37 38
public:
38 39
    typedef boost::shared_ptr<dboard_manager> sptr;
39 40

  
40
    //! It does what it says...
41
    static void populate_prop_tree_from_subdev(
42
        property_tree::sptr subtree, wax::obj subdev
43
    );
44

  
45 41
    //dboard constructor (each dboard should have a ::make with this signature)
46 42
    typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t);
47 43

  
......
57 53
        const dboard_id_t &dboard_id,
58 54
        dboard_ctor_t dboard_ctor,
59 55
        const std::string &name,
60
        const prop_names_t &subdev_names = prop_names_t(1, "0")
56
        const std::vector<std::string> &subdev_names = std::vector<std::string>(1, "0")
61 57
    );
62 58

  
63 59
    /*!
......
74 70
        const dboard_id_t &tx_dboard_id,
75 71
        dboard_ctor_t dboard_ctor,
76 72
        const std::string &name,
77
        const prop_names_t &subdev_names = prop_names_t(1, "0")
73
        const std::vector<std::string> &subdev_names = std::vector<std::string>(1, "0")
78 74
    );
79 75

  
80 76
    /*!
81 77
     * Make a new dboard manager.
82 78
     * \param rx_dboard_id the id of the rx dboard
83 79
     * \param tx_dboard_id the id of the tx dboard
80
     * \param gdboard_id the id of the grand-dboard
84 81
     * \param iface the custom dboard interface
82
     * \param subtree the subtree to load with props
85 83
     * \return an sptr to the new dboard manager
86 84
     */
87 85
    static sptr make(
88 86
        dboard_id_t rx_dboard_id,
89 87
        dboard_id_t tx_dboard_id,
90
        dboard_iface::sptr iface
88
        dboard_id_t gdboard_id,
89
        dboard_iface::sptr iface,
90
        property_tree::sptr subtree
91 91
    );
92

  
93
    //dboard manager interface
94
    virtual prop_names_t get_rx_subdev_names(void) = 0;
95
    virtual prop_names_t get_tx_subdev_names(void) = 0;
96
    virtual wax::obj get_rx_subdev(const std::string &subdev_name) = 0;
97
    virtual wax::obj get_tx_subdev(const std::string &subdev_name) = 0;
98 92
};
99 93

  
100 94
}} //namespace
b/host/lib/usrp/b100/b100_impl.cpp
404 404
    _dboard_iface = make_b100_dboard_iface(_fpga_ctrl, _fpga_i2c_ctrl, _fpga_spi_ctrl, _clock_ctrl, _codec_ctrl);
405 405
    _tree->create<dboard_iface::sptr>(mb_path / "dboards/A/iface").set(_dboard_iface);
406 406
    _dboard_manager = dboard_manager::make(
407
        rx_db_eeprom.id,
408
        ((gdb_eeprom.id == dboard_id_t::none())? tx_db_eeprom : gdb_eeprom).id,
409
        _dboard_iface
407
        rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id,
408
        _dboard_iface, _tree->subtree(mb_path / "dboards/A")
410 409
    );
411
    BOOST_FOREACH(const std::string &name, _dboard_manager->get_rx_subdev_names()){
412
        dboard_manager::populate_prop_tree_from_subdev(
413
            _tree->subtree(mb_path / "dboards/A/rx_frontends" / name),
414
            _dboard_manager->get_rx_subdev(name)
415
        );
416
    }
417
    BOOST_FOREACH(const std::string &name, _dboard_manager->get_tx_subdev_names()){
418
        dboard_manager::populate_prop_tree_from_subdev(
419
            _tree->subtree(mb_path / "dboards/A/tx_frontends" / name),
420
            _dboard_manager->get_tx_subdev(name)
421
        );
422
    }
423 410

  
424 411
    //initialize io handling
425 412
    this->io_init();
......
432 419
    _tree->access<double>(mb_path / "tick_rate") //now subscribe the clock rate setter
433 420
        .subscribe(boost::bind(&b100_clock_ctrl::set_fpga_clock_rate, _clock_ctrl, _1));
434 421

  
435
    _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:"+_dboard_manager->get_rx_subdev_names()[0]));
436
    _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:"+_dboard_manager->get_tx_subdev_names()[0]));
422
    _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/rx_frontends").at(0)));
423
    _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0)));
437 424
    _tree->access<std::string>(mb_path / "clock_source/value").set("internal");
438 425
    _tree->access<std::string>(mb_path / "time_source/value").set("none");
439 426
}
b/host/lib/usrp/dboard/CMakeLists.txt
20 20
########################################################################
21 21

  
22 22
LIBUHD_APPEND_SOURCES(
23
    ${CMAKE_CURRENT_SOURCE_DIR}/db_basic_and_lf.cpp
24
    ${CMAKE_CURRENT_SOURCE_DIR}/db_rfx.cpp
25
    ${CMAKE_CURRENT_SOURCE_DIR}/db_xcvr2450.cpp
26
    ${CMAKE_CURRENT_SOURCE_DIR}/db_sbx.cpp
27
    ${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_common.cpp
28
    ${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_simple.cpp
29
    ${CMAKE_CURRENT_SOURCE_DIR}/db_dbsrx.cpp
30
    ${CMAKE_CURRENT_SOURCE_DIR}/db_unknown.cpp
31
    ${CMAKE_CURRENT_SOURCE_DIR}/db_tvrx.cpp
32
    ${CMAKE_CURRENT_SOURCE_DIR}/db_dbsrx2.cpp
33
    ${CMAKE_CURRENT_SOURCE_DIR}/db_tvrx2.cpp
23
    #${CMAKE_CURRENT_SOURCE_DIR}/db_basic_and_lf.cpp
24
    #${CMAKE_CURRENT_SOURCE_DIR}/db_rfx.cpp
25
    #${CMAKE_CURRENT_SOURCE_DIR}/db_xcvr2450.cpp
26
    #${CMAKE_CURRENT_SOURCE_DIR}/db_sbx.cpp
27
    #${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_common.cpp
28
    #${CMAKE_CURRENT_SOURCE_DIR}/db_wbx_simple.cpp
29
    #${CMAKE_CURRENT_SOURCE_DIR}/db_dbsrx.cpp
30
    #${CMAKE_CURRENT_SOURCE_DIR}/db_unknown.cpp
31
    #${CMAKE_CURRENT_SOURCE_DIR}/db_tvrx.cpp
32
    #${CMAKE_CURRENT_SOURCE_DIR}/db_dbsrx2.cpp
33
    #${CMAKE_CURRENT_SOURCE_DIR}/db_tvrx2.cpp
34 34
)
35 35

  
b/host/lib/usrp/dboard_base.cpp
20 20
#include <boost/format.hpp>
21 21
#include <stdexcept>
22 22

  
23
using namespace uhd;
23 24
using namespace uhd::usrp;
24 25

  
25 26
/***********************************************************************
......
34 35
    _impl->args = *static_cast<dboard_ctor_args_t *>(args);
35 36
}
36 37

  
37
dboard_base::~dboard_base(void){
38
   /* NOP */
39
}
40

  
41 38
std::string dboard_base::get_subdev_name(void){
42 39
    return _impl->args.sd_name;
43 40
}
......
54 51
    return _impl->args.tx_id;
55 52
}
56 53

  
54
property_tree::sptr dboard_base::get_rx_subtree(void){
55
    return _impl->args.rx_subtree;
56
}
57

  
58
property_tree::sptr dboard_base::get_tx_subtree(void){
59
    return _impl->args.tx_subtree;
60
}
61

  
57 62
/***********************************************************************
58 63
 * xcvr dboard dboard_base class
59 64
 **********************************************************************/
......
70 75
    }
71 76
}
72 77

  
73
xcvr_dboard_base::~xcvr_dboard_base(void){
74
    /* NOP */
75
}
76

  
77 78
/***********************************************************************
78 79
 * rx dboard dboard_base class
79 80
 **********************************************************************/
......
86 87
    }
87 88
}
88 89

  
89
rx_dboard_base::~rx_dboard_base(void){
90
    /* NOP */
91
}
92

  
93
void rx_dboard_base::tx_get(const wax::obj &, wax::obj &){
94
    throw uhd::runtime_error("cannot call tx_get on a rx dboard");
95
}
96

  
97
void rx_dboard_base::tx_set(const wax::obj &, const wax::obj &){
98
    throw uhd::runtime_error("cannot call tx_set on a rx dboard");
99
}
100

  
101 90
/***********************************************************************
102 91
 * tx dboard dboard_base class
103 92
 **********************************************************************/
......
109 98
        ) % get_rx_id().to_pp_string() % dboard_id_t::none().to_pp_string()));
110 99
    }
111 100
}
112

  
113
tx_dboard_base::~tx_dboard_base(void){
114
    /* NOP */
115
}
116

  
117
void tx_dboard_base::rx_get(const wax::obj &, wax::obj &){
118
    throw uhd::runtime_error("cannot call rx_get on a tx dboard");
119
}
120

  
121
void tx_dboard_base::rx_set(const wax::obj &, const wax::obj &){
122
    throw uhd::runtime_error("cannot call rx_set on a tx dboard");
123
}
b/host/lib/usrp/dboard_ctor_args.hpp
18 18
#ifndef INCLUDED_LIBUHD_USRP_DBOARD_CTOR_ARGS_HPP
19 19
#define INCLUDED_LIBUHD_USRP_DBOARD_CTOR_ARGS_HPP
20 20

  
21
#include <uhd/property_tree.hpp>
21 22
#include <uhd/usrp/dboard_id.hpp>
22 23
#include <uhd/usrp/dboard_base.hpp>
23 24
#include <uhd/usrp/dboard_iface.hpp>
......
29 30
        std::string               sd_name;
30 31
        dboard_iface::sptr        db_iface;
31 32
        dboard_id_t               rx_id, tx_id;
33
        property_tree::sptr       rx_subtree, tx_subtree;
32 34
    };
33 35

  
34 36
}} //namespace
b/host/lib/usrp/dboard_manager.cpp
79 79
 * storage and registering for dboards
80 80
 **********************************************************************/
81 81
//dboard registry tuple: dboard constructor, canonical name, subdev names
82
typedef boost::tuple<dboard_manager::dboard_ctor_t, std::string, prop_names_t> args_t;
82
typedef boost::tuple<dboard_manager::dboard_ctor_t, std::string, std::vector<std::string> > args_t;
83 83

  
84 84
//map a dboard id to a dboard constructor
85 85
typedef uhd::dict<dboard_key_t, args_t> id_to_args_map_t;
......
89 89
    const dboard_key_t &dboard_key,
90 90
    dboard_manager::dboard_ctor_t dboard_ctor,
91 91
    const std::string &name,
92
    const prop_names_t &subdev_names
92
    const std::vector<std::string> &subdev_names
93 93
){
94 94
    UHD_LOGV(always) << "registering: " << name << std::endl;
95 95
    if (get_id_to_args_map().has_key(dboard_key)){
......
110 110
    const dboard_id_t &dboard_id,
111 111
    dboard_ctor_t dboard_ctor,
112 112
    const std::string &name,
113
    const prop_names_t &subdev_names
113
    const std::vector<std::string> &subdev_names
114 114
){
115 115
    register_dboard_key(dboard_key_t(dboard_id), dboard_ctor, name, subdev_names);
116 116
}
......
120 120
    const dboard_id_t &tx_dboard_id,
121 121
    dboard_ctor_t dboard_ctor,
122 122
    const std::string &name,
123
    const prop_names_t &subdev_names
123
    const std::vector<std::string> &subdev_names
124 124
){
125 125
    register_dboard_key(dboard_key_t(rx_dboard_id, tx_dboard_id), dboard_ctor, name, subdev_names);
126 126
}
......
144 144
}
145 145

  
146 146
/***********************************************************************
147
 * internal helper classes
148
 **********************************************************************/
149
/*!
150
 * A special wax proxy object that forwards calls to a subdev.
151
 * A sptr to an instance will be used in the properties structure. 
152
 */
153
class subdev_proxy : boost::noncopyable, public wax::obj{
154
public:
155
    typedef boost::shared_ptr<subdev_proxy> sptr;
156
    enum type_t{RX_TYPE, TX_TYPE};
157

  
158
    //structors
159
    subdev_proxy(dboard_base::sptr subdev, type_t type):
160
        _subdev(subdev), _type(type)
161
    {
162
        /* NOP */
163
    }
164

  
165
private:
166
    dboard_base::sptr   _subdev;
167
    type_t              _type;
168

  
169
    //forward the get calls to the rx or tx
170
    void get(const wax::obj &key, wax::obj &val){
171
        switch(_type){
172
        case RX_TYPE: return _subdev->rx_get(key, val);
173
        case TX_TYPE: return _subdev->tx_get(key, val);
174
        }
175
    }
176

  
177
    //forward the set calls to the rx or tx
178
    void set(const wax::obj &key, const wax::obj &val){
179
        switch(_type){
180
        case RX_TYPE: return _subdev->rx_set(key, val);
181
        case TX_TYPE: return _subdev->tx_set(key, val);
182
        }
183
    }
184
};
185

  
186
/***********************************************************************
187 147
 * dboard manager implementation class
188 148
 **********************************************************************/
189 149
class dboard_manager_impl : public dboard_manager{
......
192 152
    dboard_manager_impl(
193 153
        dboard_id_t rx_dboard_id,
194 154
        dboard_id_t tx_dboard_id,
195
        dboard_iface::sptr iface
155
        dboard_iface::sptr iface,
156
        property_tree::sptr subtree
196 157
    );
197 158
    ~dboard_manager_impl(void);
198 159

  
199
    //dboard_iface
200
    prop_names_t get_rx_subdev_names(void);
201
    prop_names_t get_tx_subdev_names(void);
202
    wax::obj get_rx_subdev(const std::string &subdev_name);
203
    wax::obj get_tx_subdev(const std::string &subdev_name);
204

  
205 160
private:
206
    void init(dboard_id_t, dboard_id_t);
161
    void init(dboard_id_t, dboard_id_t, property_tree::sptr);
207 162
    //list of rx and tx dboards in this dboard_manager
208 163
    //each dboard here is actually a subdevice proxy
209 164
    //the subdevice proxy is internal to the cpp file
210
    uhd::dict<std::string, subdev_proxy::sptr> _rx_dboards;
211
    uhd::dict<std::string, subdev_proxy::sptr> _tx_dboards;
165
    uhd::dict<std::string, dboard_base::sptr> _rx_dboards;
166
    uhd::dict<std::string, dboard_base::sptr> _tx_dboards;
212 167
    dboard_iface::sptr _iface;
213 168
    void set_nice_dboard_if(void);
214 169
};
......
219 174
dboard_manager::sptr dboard_manager::make(
220 175
    dboard_id_t rx_dboard_id,
221 176
    dboard_id_t tx_dboard_id,
222
    dboard_iface::sptr iface
177
    dboard_id_t gdboard_id,
178
    dboard_iface::sptr iface,
179
    property_tree::sptr subtree
223 180
){
224 181
    return dboard_manager::sptr(
225
        new dboard_manager_impl(rx_dboard_id, tx_dboard_id, iface)
182
        new dboard_manager_impl(
183
            rx_dboard_id,
184
            (gdboard_id == dboard_id_t::none())? tx_dboard_id : gdboard_id,
185
            iface, subtree
186
        )
226 187
    );
227 188
}
228 189

  
......
232 193
dboard_manager_impl::dboard_manager_impl(
233 194
    dboard_id_t rx_dboard_id,
234 195
    dboard_id_t tx_dboard_id,
235
    dboard_iface::sptr iface
196
    dboard_iface::sptr iface,
197
    property_tree::sptr subtree
236 198
):
237 199
    _iface(iface)
238 200
{
239 201
    try{
240
        this->init(rx_dboard_id, tx_dboard_id);
202
        this->init(rx_dboard_id, tx_dboard_id, subtree);
241 203
    }
242 204
    catch(const std::exception &e){
243 205
        UHD_MSG(error) << "The daughterboard manager encountered a recoverable error in init" << std::endl << e.what();
244
        this->init(dboard_id_t::none(), dboard_id_t::none());
206
        this->init(dboard_id_t::none(), dboard_id_t::none(), subtree);
245 207
    }
246 208
}
247 209

  
248 210
void dboard_manager_impl::init(
249
    dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id
211
    dboard_id_t rx_dboard_id, dboard_id_t tx_dboard_id, property_tree::sptr subtree
250 212
){
251 213
    //find the dboard key matches for the dboard ids
252 214
    dboard_key_t rx_dboard_key, tx_dboard_key, xcvr_dboard_key;
......
283 245
    if (xcvr_dboard_key.is_xcvr()){
284 246

  
285 247
        //extract data for the xcvr dboard key
286
        dboard_ctor_t dboard_ctor; std::string name; prop_names_t subdevs;
248
        dboard_ctor_t dboard_ctor; std::string name; std::vector<std::string> subdevs;
287 249
        boost::tie(dboard_ctor, name, subdevs) = get_id_to_args_map()[xcvr_dboard_key];
288 250

  
289 251
        //create the xcvr object for each subdevice
......
291 253
            db_ctor_args.sd_name = subdev;
292 254
            db_ctor_args.rx_id = rx_dboard_id;
293 255
            db_ctor_args.tx_id = tx_dboard_id;
256
            db_ctor_args.rx_subtree = subtree->subtree("rx_frontends/" + subdev);
257
            db_ctor_args.tx_subtree = subtree->subtree("tx_frontends/" + subdev);
294 258
            dboard_base::sptr xcvr_dboard = dboard_ctor(&db_ctor_args);
295
            //create a rx proxy for this xcvr board
296
            _rx_dboards[subdev] = subdev_proxy::sptr(
297
                new subdev_proxy(xcvr_dboard, subdev_proxy::RX_TYPE)
298
            );
299
            //create a tx proxy for this xcvr board
300
            _tx_dboards[subdev] = subdev_proxy::sptr(
301
                new subdev_proxy(xcvr_dboard, subdev_proxy::TX_TYPE)
302
            );
259
            _rx_dboards[subdev] = xcvr_dboard;
260
            _tx_dboards[subdev] = xcvr_dboard;
303 261
        }
304 262
    }
305 263

  
......
312 270
        }
313 271

  
314 272
        //extract data for the rx dboard key
315
        dboard_ctor_t rx_dboard_ctor; std::string rx_name; prop_names_t rx_subdevs;
273
        dboard_ctor_t rx_dboard_ctor; std::string rx_name; std::vector<std::string> rx_subdevs;
316 274
        boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_id_to_args_map()[rx_dboard_key];
317 275

  
318 276
        //make the rx subdevs
......
320 278
            db_ctor_args.sd_name = subdev;
321 279
            db_ctor_args.rx_id = rx_dboard_id;
322 280
            db_ctor_args.tx_id = dboard_id_t::none();
323
            dboard_base::sptr rx_dboard = rx_dboard_ctor(&db_ctor_args);
324
            //create a rx proxy for this rx board
325
            _rx_dboards[subdev] = subdev_proxy::sptr(
326
                new subdev_proxy(rx_dboard, subdev_proxy::RX_TYPE)
327
            );
281
            db_ctor_args.rx_subtree = subtree->subtree("rx_frontends/" + subdev);
282
            db_ctor_args.tx_subtree = property_tree::sptr(); //null
283
            _rx_dboards[subdev] = rx_dboard_ctor(&db_ctor_args);
328 284
        }
329 285

  
330 286
        //force the tx key to the unknown board for bad combinations
......
333 289
        }
334 290

  
335 291
        //extract data for the tx dboard key
336
        dboard_ctor_t tx_dboard_ctor; std::string tx_name; prop_names_t tx_subdevs;
292
        dboard_ctor_t tx_dboard_ctor; std::string tx_name; std::vector<std::string> tx_subdevs;
337 293
        boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_id_to_args_map()[tx_dboard_key];
338 294

  
339 295
        //make the tx subdevs
......
341 297
            db_ctor_args.sd_name = subdev;
342 298
            db_ctor_args.rx_id = dboard_id_t::none();
343 299
            db_ctor_args.tx_id = tx_dboard_id;
344
            dboard_base::sptr tx_dboard = tx_dboard_ctor(&db_ctor_args);
345
            //create a tx proxy for this tx board
346
            _tx_dboards[subdev] = subdev_proxy::sptr(
347
                new subdev_proxy(tx_dboard, subdev_proxy::TX_TYPE)
348
            );
300
            db_ctor_args.rx_subtree = property_tree::sptr(); //null
301
            db_ctor_args.tx_subtree = subtree->subtree("tx_frontends/" + subdev);
302
            _tx_dboards[subdev] = tx_dboard_ctor(&db_ctor_args);
349 303
        }
350 304
    }
351 305
}
......
354 308
    set_nice_dboard_if();
355 309
)}
356 310

  
357
prop_names_t dboard_manager_impl::get_rx_subdev_names(void){
358
    return _rx_dboards.keys();
359
}
360

  
361
prop_names_t dboard_manager_impl::get_tx_subdev_names(void){
362
    return _tx_dboards.keys();
363
}
364

  
365
wax::obj dboard_manager_impl::get_rx_subdev(const std::string &subdev_name){
366
    if (not _rx_dboards.has_key(subdev_name)) throw uhd::key_error(
367
        str(boost::format("Unknown rx subdev name %s") % subdev_name)
368
    );
369
    //get a link to the rx subdev proxy
370
    return _rx_dboards[subdev_name]->get_link();
371
}
372

  
373
wax::obj dboard_manager_impl::get_tx_subdev(const std::string &subdev_name){
374
    if (not _tx_dboards.has_key(subdev_name)) throw uhd::key_error(
375
        str(boost::format("Unknown tx subdev name %s") % subdev_name)
376
    );
377
    //get a link to the tx subdev proxy
378
    return _tx_dboards[subdev_name]->get_link();
379
}
380

  
381 311
void dboard_manager_impl::set_nice_dboard_if(void){
382 312
    //make a list of possible unit types
383 313
    std::vector<dboard_iface::unit_t> units = boost::assign::list_of
......
392 322
        _iface->set_pin_ctrl(unit, 0x0000); //all gpio
393 323
        _iface->set_clock_enabled(unit, false); //clock off
394 324
    }
395

  
396
    //disable all rx subdevices
397
    BOOST_FOREACH(const std::string &sd_name, this->get_rx_subdev_names()){
398
        this->get_rx_subdev(sd_name)[SUBDEV_PROP_ENABLED] = false;
399
    }
400

  
401
    //disable all tx subdevices
402
    BOOST_FOREACH(const std::string &sd_name, this->get_tx_subdev_names()){
403
        this->get_tx_subdev(sd_name)[SUBDEV_PROP_ENABLED] = false;
404
    }
405
}
406

  
407
/***********************************************************************
408
 * Populate a properties tree from a subdev waxy object
409
 **********************************************************************/
410
#include <uhd/types/ranges.hpp>
411
#include <uhd/types/sensors.hpp>
412

  
413
static sensor_value_t get_sensor(wax::obj subdev, const std::string &name){
414
    return subdev[named_prop_t(SUBDEV_PROP_SENSOR, name)].as<sensor_value_t>();
415
}
416

  
417
static void set_gain(wax::obj subdev, const std::string &name, const double gain){
418
    subdev[named_prop_t(SUBDEV_PROP_GAIN, name)] = gain;
419
}
420

  
421
static double get_gain(wax::obj subdev, const std::string &name){
422
    return subdev[named_prop_t(SUBDEV_PROP_GAIN, name)].as<double>();
423
}
424

  
425
static meta_range_t get_gain_range(wax::obj subdev, const std::string &name){
426
    return subdev[named_prop_t(SUBDEV_PROP_GAIN_RANGE, name)].as<meta_range_t>();
427
}
428

  
429
static void set_freq(wax::obj subdev, const double freq){
430
    subdev[SUBDEV_PROP_FREQ] = freq;
431
}
432

  
433
static double get_freq(wax::obj subdev){
434
    return subdev[SUBDEV_PROP_FREQ].as<double>();
435
}
436

  
437
static meta_range_t get_freq_range(wax::obj subdev){
438
    return subdev[SUBDEV_PROP_FREQ_RANGE].as<meta_range_t>();
439
}
440

  
441
static void set_ant(wax::obj subdev, const std::string &ant){
442
    subdev[SUBDEV_PROP_ANTENNA] = ant;
443
}
444

  
445
static std::string get_ant(wax::obj subdev){
446
    return subdev[SUBDEV_PROP_ANTENNA].as<std::string>();
447
}
448

  
449
static std::vector<std::string> get_ants(wax::obj subdev){
450
    return subdev[SUBDEV_PROP_ANTENNA_NAMES].as<std::vector<std::string> >();
451
}
452

  
453
static std::string get_conn(wax::obj subdev){
454
    switch(subdev[SUBDEV_PROP_CONNECTION].as<subdev_conn_t>()){
455
    case SUBDEV_CONN_COMPLEX_IQ: return "IQ";
456
    case SUBDEV_CONN_COMPLEX_QI: return "QI";
457
    case SUBDEV_CONN_REAL_I: return "I";
458
    case SUBDEV_CONN_REAL_Q: return "Q";
459
    }
460
    UHD_THROW_INVALID_CODE_PATH();
461
}
462

  
463
static bool get_use_lo_off(wax::obj subdev){
464
    return subdev[SUBDEV_PROP_USE_LO_OFFSET].as<bool>();
465
}
466

  
467
static bool get_set_enb(wax::obj subdev, const bool enb){
468
    subdev[SUBDEV_PROP_ENABLED] = enb;
469
    return subdev[SUBDEV_PROP_ENABLED].as<bool>();
470
}
471

  
472
static void set_bw(wax::obj subdev, const double freq){
473
    subdev[SUBDEV_PROP_BANDWIDTH] = freq;
474
}
475

  
476
static double get_bw(wax::obj subdev){
477
    return subdev[SUBDEV_PROP_BANDWIDTH].as<double>();
478
}
479

  
480
void dboard_manager::populate_prop_tree_from_subdev(
481
    property_tree::sptr subtree, wax::obj subdev
482
){
483
    subtree->create<std::string>("name").set(subdev[SUBDEV_PROP_NAME].as<std::string>());
484

  
485
    const prop_names_t sensor_names = subdev[SUBDEV_PROP_SENSOR_NAMES].as<prop_names_t>();
486
    subtree->create<int>("sensors"); //phony property so this dir exists
487
    BOOST_FOREACH(const std::string &name, sensor_names){
488
        subtree->create<sensor_value_t>("sensors/" + name)
489
            .publish(boost::bind(&get_sensor, subdev, name));
490
    }
491

  
492
    const prop_names_t gain_names = subdev[SUBDEV_PROP_GAIN_NAMES].as<prop_names_t>();
493
    subtree->create<int>("gains"); //phony property so this dir exists
494
    BOOST_FOREACH(const std::string &name, gain_names){
495
        subtree->create<double>("gains/" + name + "/value")
496
            .publish(boost::bind(&get_gain, subdev, name))
497
            .subscribe(boost::bind(&set_gain, subdev, name, _1));
498
        subtree->create<meta_range_t>("gains/" + name + "/range")
499
            .publish(boost::bind(&get_gain_range, subdev, name));
500
    }
501

  
502
    subtree->create<double>("freq/value")
503
        .publish(boost::bind(&get_freq, subdev))
504
        .subscribe(boost::bind(&set_freq, subdev, _1));
505

  
506
    subtree->create<meta_range_t>("freq/range")
507
        .publish(boost::bind(&get_freq_range, subdev));
508

  
509
    subtree->create<std::string>("antenna/value")
510
        .publish(boost::bind(&get_ant, subdev))
511
        .subscribe(boost::bind(&set_ant, subdev, _1));
512

  
513
    subtree->create<std::vector<std::string> >("antenna/options")
514
        .publish(boost::bind(&get_ants, subdev));
515

  
516
    subtree->create<std::string>("connection")
517
        .publish(boost::bind(&get_conn, subdev));
518

  
519
    subtree->create<bool>("enabled")
520
        .coerce(boost::bind(&get_set_enb, subdev, _1));
521

  
522
    subtree->create<bool>("use_lo_offset")
523
        .publish(boost::bind(&get_use_lo_off, subdev));
524

  
525
    subtree->create<double>("bandwidth/value")
526
        .publish(boost::bind(&get_bw, subdev))
527
        .subscribe(boost::bind(&set_bw, subdev, _1));
528 325
}
b/host/lib/usrp/e100/e100_impl.cpp
370 370
    _dboard_iface = make_e100_dboard_iface(_fpga_ctrl, _fpga_i2c_ctrl, _fpga_spi_ctrl, _clock_ctrl, _codec_ctrl);
371 371
    _tree->create<dboard_iface::sptr>(mb_path / "dboards/A/iface").set(_dboard_iface);
372 372
    _dboard_manager = dboard_manager::make(
373
        rx_db_eeprom.id,
374
        ((gdb_eeprom.id == dboard_id_t::none())? tx_db_eeprom : gdb_eeprom).id,
375
        _dboard_iface
373
        rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id,
374
        _dboard_iface, _tree->subtree(mb_path / "dboards/A")
376 375
    );
377
    BOOST_FOREACH(const std::string &name, _dboard_manager->get_rx_subdev_names()){
378
        dboard_manager::populate_prop_tree_from_subdev(
379
            _tree->subtree(mb_path / "dboards/A/rx_frontends" / name),
380
            _dboard_manager->get_rx_subdev(name)
381
        );
382
    }
383
    BOOST_FOREACH(const std::string &name, _dboard_manager->get_tx_subdev_names()){
384
        dboard_manager::populate_prop_tree_from_subdev(
385
            _tree->subtree(mb_path / "dboards/A/tx_frontends" / name),
386
            _dboard_manager->get_tx_subdev(name)
387
        );
388
    }
389 376

  
390 377
    //initialize io handling
391 378
    this->io_init();
......
398 385
    _tree->access<double>(mb_path / "tick_rate") //now subscribe the clock rate setter
399 386
        .subscribe(boost::bind(&e100_clock_ctrl::set_fpga_clock_rate, _clock_ctrl, _1));
400 387

  
401
    _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:"+_dboard_manager->get_rx_subdev_names()[0]));
402
    _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:"+_dboard_manager->get_tx_subdev_names()[0]));
388
    _tree->access<subdev_spec_t>(mb_path / "rx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/rx_frontends").at(0)));
389
    _tree->access<subdev_spec_t>(mb_path / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(mb_path / "dboards/A/tx_frontends").at(0)));
403 390
    _tree->access<std::string>(mb_path / "clock_source/value").set("internal");
404 391
    _tree->access<std::string>(mb_path / "time_source/value").set("none");
405 392

  
b/host/lib/usrp/usrp1/usrp1_impl.cpp
363 363
        );
364 364
        _tree->create<dboard_iface::sptr>(mb_path / "dboards" / db/ "iface").set(_dbc[db].dboard_iface);
365 365
        _dbc[db].dboard_manager = dboard_manager::make(
366
            rx_db_eeprom.id,
367
            ((gdb_eeprom.id == dboard_id_t::none())? tx_db_eeprom : gdb_eeprom).id,
368
            _dbc[db].dboard_iface
366
            rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id,
367
            _dbc[db].dboard_iface, _tree->subtree(mb_path / "dboards" / db)
369 368
        );
370
        BOOST_FOREACH(const std::string &name, _dbc[db].dboard_manager->get_rx_subdev_names()){
371
            dboard_manager::populate_prop_tree_from_subdev(
372
                _tree->subtree(mb_path / "dboards" / db/ "rx_frontends" / name),
373
                _dbc[db].dboard_manager->get_rx_subdev(name)
374
            );
375
        }
376
        BOOST_FOREACH(const std::string &name, _dbc[db].dboard_manager->get_tx_subdev_names()){
377
            dboard_manager::populate_prop_tree_from_subdev(
378
                _tree->subtree(mb_path / "dboards" / db/ "tx_frontends" / name),
379
                _dbc[db].dboard_manager->get_tx_subdev(name)
380
            );
381
        }
382 369

  
383 370
        //init the subdev specs if we have a dboard (wont leave this loop empty)
384 371
        if (rx_db_eeprom.id != dboard_id_t::none() or _rx_subdev_spec.empty()){
385
            _rx_subdev_spec = subdev_spec_t(db + ":" + _dbc[db].dboard_manager->get_rx_subdev_names()[0]);
372
            _rx_subdev_spec = subdev_spec_t(db + ":" + _tree->list(mb_path / "dboards" / db / "rx_frontends").at(0));
386 373
        }
387 374
        if (tx_db_eeprom.id != dboard_id_t::none() or _tx_subdev_spec.empty()){
388
            _tx_subdev_spec = subdev_spec_t(db + ":" + _dbc[db].dboard_manager->get_tx_subdev_names()[0]);
375
            _tx_subdev_spec = subdev_spec_t(db + ":" + _tree->list(mb_path / "dboards" / db / "tx_frontends").at(0));
389 376
        }
390 377
    }
391 378

  
b/host/lib/usrp/usrp2/usrp2_impl.cpp
597 597
        _mbc[mb].dboard_iface = make_usrp2_dboard_iface(_mbc[mb].iface, _mbc[mb].clock);
598 598
        _tree->create<dboard_iface::sptr>(mb_path / "dboards/A/iface").set(_mbc[mb].dboard_iface);
599 599
        _mbc[mb].dboard_manager = dboard_manager::make(
600
            rx_db_eeprom.id,
601
            ((gdb_eeprom.id == dboard_id_t::none())? tx_db_eeprom : gdb_eeprom).id,
602
            _mbc[mb].dboard_iface
600
            rx_db_eeprom.id, tx_db_eeprom.id, gdb_eeprom.id,
601
            _mbc[mb].dboard_iface, _tree->subtree(mb_path / "dboards/A")
603 602
        );
604
        BOOST_FOREACH(const std::string &name, _mbc[mb].dboard_manager->get_rx_subdev_names()){
605
            dboard_manager::populate_prop_tree_from_subdev(
606
                _tree->subtree(mb_path / "dboards/A/rx_frontends" / name),
607
                _mbc[mb].dboard_manager->get_rx_subdev(name)
608
            );
609
        }
610
        BOOST_FOREACH(const std::string &name, _mbc[mb].dboard_manager->get_tx_subdev_names()){
611
            dboard_manager::populate_prop_tree_from_subdev(
612
                _tree->subtree(mb_path / "dboards/A/tx_frontends" / name),
613
                _mbc[mb].dboard_manager->get_tx_subdev(name)
614
            );
615
        }
616 603
    }
617 604

  
618 605
    //initialize io handling
......
623 610
    BOOST_FOREACH(const std::string &mb, _mbc.keys()){
624 611
        fs_path root = "/mboards/" + mb;
625 612

  
626
        _tree->access<subdev_spec_t>(root / "rx_subdev_spec").set(subdev_spec_t("A:"+_mbc[mb].dboard_manager->get_rx_subdev_names()[0]));
627
        _tree->access<subdev_spec_t>(root / "tx_subdev_spec").set(subdev_spec_t("A:"+_mbc[mb].dboard_manager->get_tx_subdev_names()[0]));
613
        _tree->access<subdev_spec_t>(root / "rx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(root / "dboards/A/rx_frontends").at(0)));
614
        _tree->access<subdev_spec_t>(root / "tx_subdev_spec").set(subdev_spec_t("A:" + _tree->list(root / "dboards/A/tx_frontends").at(0)));
628 615
        _tree->access<std::string>(root / "clock_source/value").set("internal");
629 616
        _tree->access<std::string>(root / "time_source/value").set("none");
630 617

  

Also available in: Unified diff