aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-06-18 17:24:39 -0700
committerJosh Blum <josh@joshknows.com>2010-06-18 17:24:39 -0700
commit2d7c3f4cc38627a8f0243b78c3c10adc6f1cda46 (patch)
tree906ef314d0a401377a2bde4b83e116710f4194eb
parentf58cf8f6dc0b0bae5b7644a03aa30a57e99e595a (diff)
parente3058c022e4d71401a073fdaa16a97808977e23b (diff)
downloaduhd-2d7c3f4cc38627a8f0243b78c3c10adc6f1cda46.tar.gz
uhd-2d7c3f4cc38627a8f0243b78c3c10adc6f1cda46.tar.bz2
uhd-2d7c3f4cc38627a8f0243b78c3c10adc6f1cda46.zip
Merge branch 'burn_dbid' into pre_merge
-rw-r--r--host/include/uhd/usrp/dboard_manager.hpp21
-rw-r--r--host/lib/usrp/dboard/CMakeLists.txt1
-rw-r--r--host/lib/usrp/dboard/db_rfx.cpp24
-rw-r--r--host/lib/usrp/dboard/db_unknown.cpp265
-rw-r--r--host/lib/usrp/dboard/db_wbx.cpp3
-rw-r--r--host/lib/usrp/dboard/db_xcvr2450.cpp3
-rw-r--r--host/lib/usrp/dboard_manager.cpp58
-rw-r--r--host/utils/uhd_burn_db_eeprom.cpp12
8 files changed, 343 insertions, 44 deletions
diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp
index b84fee4e7..e5831d4cf 100644
--- a/host/include/uhd/usrp/dboard_manager.hpp
+++ b/host/include/uhd/usrp/dboard_manager.hpp
@@ -40,7 +40,7 @@ public:
typedef dboard_base::sptr(*dboard_ctor_t)(dboard_base::ctor_args_t);
/*!
- * Register a dboard into the system.
+ * Register a rx or tx dboard into the system.
* For single subdevice boards, omit subdev_names.
* \param dboard_id the dboard id (rx or tx)
* \param dboard_ctor the dboard constructor function pointer
@@ -48,7 +48,24 @@ public:
* \param subdev_names the names of the subdevs on this dboard
*/
static void register_dboard(
- dboard_id_t dboard_id,
+ const dboard_id_t &dboard_id,
+ dboard_ctor_t dboard_ctor,
+ const std::string &name,
+ const prop_names_t &subdev_names = prop_names_t(1, "")
+ );
+
+ /*!
+ * Register an xcvr dboard into the system.
+ * For single subdevice boards, omit subdev_names.
+ * \param rx_dboard_id the rx unit dboard id
+ * \param tx_dboard_id the tx unit dboard id
+ * \param dboard_ctor the dboard constructor function pointer
+ * \param name the canonical name for the dboard represented
+ * \param subdev_names the names of the subdevs on this dboard
+ */
+ static void register_dboard(
+ const dboard_id_t &rx_dboard_id,
+ const dboard_id_t &tx_dboard_id,
dboard_ctor_t dboard_ctor,
const std::string &name,
const prop_names_t &subdev_names = prop_names_t(1, "")
diff --git a/host/lib/usrp/dboard/CMakeLists.txt b/host/lib/usrp/dboard/CMakeLists.txt
index 3a6c2d84a..6093583d3 100644
--- a/host/lib/usrp/dboard/CMakeLists.txt
+++ b/host/lib/usrp/dboard/CMakeLists.txt
@@ -22,5 +22,6 @@ LIBUHD_APPEND_SOURCES(
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_rfx.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_xcvr2450.cpp
${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_wbx.cpp
+ ${CMAKE_SOURCE_DIR}/lib/usrp/dboard/db_unknown.cpp
)
diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp
index 7f2275b07..2d6088983 100644
--- a/host/lib/usrp/dboard/db_rfx.cpp
+++ b/host/lib/usrp/dboard/db_rfx.cpp
@@ -137,25 +137,21 @@ static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t args){
return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1150e6, 1450e6), true, true));
}
+static dboard_base::sptr make_rfx_flex2200(dboard_base::ctor_args_t args){
+ return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2000e6, 2400e6), false, false));
+}
+
static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t args){
return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2300e6, 2900e6), false, false));
}
UHD_STATIC_BLOCK(reg_rfx_dboards){
- dboard_manager::register_dboard(0x0024, &make_rfx_flex400, "Flex 400 Rx MIMO B");
- dboard_manager::register_dboard(0x0028, &make_rfx_flex400, "Flex 400 Tx MIMO B");
-
- dboard_manager::register_dboard(0x0025, &make_rfx_flex900, "Flex 900 Rx MIMO B");
- dboard_manager::register_dboard(0x0029, &make_rfx_flex900, "Flex 900 Tx MIMO B");
-
- dboard_manager::register_dboard(0x0034, &make_rfx_flex1800, "Flex 1800 Rx MIMO B");
- dboard_manager::register_dboard(0x0035, &make_rfx_flex1800, "Flex 1800 Tx MIMO B");
-
- dboard_manager::register_dboard(0x0026, &make_rfx_flex1200, "Flex 1200 Rx MIMO B");
- dboard_manager::register_dboard(0x002a, &make_rfx_flex1200, "Flex 1200 Tx MIMO B");
-
- dboard_manager::register_dboard(0x0027, &make_rfx_flex2400, "Flex 2400 Rx MIMO B");
- dboard_manager::register_dboard(0x002b, &make_rfx_flex2400, "Flex 2400 Tx MIMO B");
+ dboard_manager::register_dboard(0x0024, 0x0028, &make_rfx_flex400, "Flex 400 MIMO B");
+ dboard_manager::register_dboard(0x0025, 0x0029, &make_rfx_flex900, "Flex 900 MIMO B");
+ dboard_manager::register_dboard(0x0034, 0x0035, &make_rfx_flex1800, "Flex 1800 MIMO B");
+ dboard_manager::register_dboard(0x0026, 0x002a, &make_rfx_flex1200, "Flex 1200 MIMO B");
+ dboard_manager::register_dboard(0x002c, 0x002d, &make_rfx_flex2200, "Flex 2200 MIMO B");
+ dboard_manager::register_dboard(0x0027, 0x002b, &make_rfx_flex2400, "Flex 2400 MIMO B");
}
/***********************************************************************
diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp
new file mode 100644
index 000000000..ced27e34d
--- /dev/null
+++ b/host/lib/usrp/dboard/db_unknown.cpp
@@ -0,0 +1,265 @@
+//
+// 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/usrp/subdev_props.hpp>
+#include <uhd/types/ranges.hpp>
+#include <uhd/utils/assert.hpp>
+#include <uhd/utils/static.hpp>
+#include <uhd/usrp/dboard_base.hpp>
+#include <uhd/usrp/dboard_manager.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/format.hpp>
+
+using namespace uhd;
+using namespace uhd::usrp;
+using namespace boost::assign;
+
+/***********************************************************************
+ * The unknown boards:
+ * Like a basic board, but with only one subdev.
+ **********************************************************************/
+class unknown_rx : public rx_dboard_base{
+public:
+ unknown_rx(ctor_args_t args);
+ ~unknown_rx(void);
+
+ void rx_get(const wax::obj &key, wax::obj &val);
+ void rx_set(const wax::obj &key, const wax::obj &val);
+};
+
+class unknown_tx : public tx_dboard_base{
+public:
+ unknown_tx(ctor_args_t args);
+ ~unknown_tx(void);
+
+ void tx_get(const wax::obj &key, wax::obj &val);
+ void tx_set(const wax::obj &key, const wax::obj &val);
+};
+
+/***********************************************************************
+ * Register the unknown dboards
+ **********************************************************************/
+static dboard_base::sptr make_unknown_rx(dboard_base::ctor_args_t args){
+ return dboard_base::sptr(new unknown_rx(args));
+}
+
+static dboard_base::sptr make_unknown_tx(dboard_base::ctor_args_t args){
+ return dboard_base::sptr(new unknown_tx(args));
+}
+
+UHD_STATIC_BLOCK(reg_unknown_dboards){
+ dboard_manager::register_dboard(0xfff0, &make_unknown_tx, "Unknown TX");
+ dboard_manager::register_dboard(0xfff1, &make_unknown_rx, "Unknown RX");
+}
+
+/***********************************************************************
+ * Unknown RX dboard
+ **********************************************************************/
+unknown_rx::unknown_rx(ctor_args_t args) : rx_dboard_base(args){
+ /* NOP */
+}
+
+unknown_rx::~unknown_rx(void){
+ /* NOP */
+}
+
+void unknown_rx::rx_get(const wax::obj &key_, wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+ case SUBDEV_PROP_NAME:
+ val = "Unknown - " + get_rx_id().to_pp_string();
+ return;
+
+ case SUBDEV_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_GAIN:
+ val = float(0);
+ return;
+
+ case SUBDEV_PROP_GAIN_RANGE:
+ val = gain_range_t(0, 0, 0);
+ return;
+
+ case SUBDEV_PROP_GAIN_NAMES:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ val = double(0);
+ return;
+
+ case SUBDEV_PROP_FREQ_RANGE:
+ val = freq_range_t(0, 0);
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ val = std::string("");
+ return;
+
+ case SUBDEV_PROP_ANTENNA_NAMES:
+ val = prop_names_t(1, ""); //vector of 1 empty string
+ return;
+
+ case SUBDEV_PROP_QUADRATURE:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_IQ_SWAPPED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_SPECTRUM_INVERTED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_USE_LO_OFFSET:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_LO_LOCKED:
+ val = true; //there is no LO, so it must be true!
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+void unknown_rx::rx_set(const wax::obj &key_, const wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+
+ case SUBDEV_PROP_GAIN:
+ UHD_ASSERT_THROW(val.as<float>() == float(0));
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ UHD_ASSERT_THROW(val.as<std::string>() == std::string(""));
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ return; // it wont do you much good, but you can set it
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
+
+/***********************************************************************
+ * Basic and LF TX dboard
+ **********************************************************************/
+unknown_tx::unknown_tx(ctor_args_t args) : tx_dboard_base(args){
+ /* NOP */
+}
+
+unknown_tx::~unknown_tx(void){
+ /* NOP */
+}
+
+void unknown_tx::tx_get(const wax::obj &key_, wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+ case SUBDEV_PROP_NAME:
+ val = "Unknown - " + get_tx_id().to_pp_string();
+ return;
+
+ case SUBDEV_PROP_OTHERS:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_GAIN:
+ val = float(0);
+ return;
+
+ case SUBDEV_PROP_GAIN_RANGE:
+ val = gain_range_t(0, 0, 0);
+ return;
+
+ case SUBDEV_PROP_GAIN_NAMES:
+ val = prop_names_t(); //empty
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ val = double(0);
+ return;
+
+ case SUBDEV_PROP_FREQ_RANGE:
+ val = freq_range_t(0, 0);
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ val = std::string("");
+ return;
+
+ case SUBDEV_PROP_ANTENNA_NAMES:
+ val = prop_names_t(1, ""); //vector of 1 empty string
+ return;
+
+ case SUBDEV_PROP_QUADRATURE:
+ val = true;
+ return;
+
+ case SUBDEV_PROP_IQ_SWAPPED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_SPECTRUM_INVERTED:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_USE_LO_OFFSET:
+ val = false;
+ return;
+
+ case SUBDEV_PROP_LO_LOCKED:
+ val = true; //there is no LO, so it must be true!
+ return;
+
+ default: UHD_THROW_PROP_GET_ERROR();
+ }
+}
+
+void unknown_tx::tx_set(const wax::obj &key_, const wax::obj &val){
+ wax::obj key; std::string name;
+ boost::tie(key, name) = extract_named_prop(key_);
+
+ //handle the get request conditioned on the key
+ switch(key.as<subdev_prop_t>()){
+
+ case SUBDEV_PROP_GAIN:
+ UHD_ASSERT_THROW(val.as<float>() == float(0));
+ return;
+
+ case SUBDEV_PROP_ANTENNA:
+ UHD_ASSERT_THROW(val.as<std::string>() == std::string(""));
+ return;
+
+ case SUBDEV_PROP_FREQ:
+ return; // it wont do you much good, but you can set it
+
+ default: UHD_THROW_PROP_SET_ERROR();
+ }
+}
diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp
index aa5daf9a3..2b2822b6b 100644
--- a/host/lib/usrp/dboard/db_wbx.cpp
+++ b/host/lib/usrp/dboard/db_wbx.cpp
@@ -154,8 +154,7 @@ static dboard_base::sptr make_wbx(dboard_base::ctor_args_t args){
}
UHD_STATIC_BLOCK(reg_wbx_dboards){
- dboard_manager::register_dboard(0x0052, &make_wbx, "WBX RX");
- dboard_manager::register_dboard(0x0053, &make_wbx, "WBX TX");
+ dboard_manager::register_dboard(0x0052, 0x0053, &make_wbx, "WBX");
}
/***********************************************************************
diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp
index d83781965..5032b6f31 100644
--- a/host/lib/usrp/dboard/db_xcvr2450.cpp
+++ b/host/lib/usrp/dboard/db_xcvr2450.cpp
@@ -158,8 +158,7 @@ static dboard_base::sptr make_xcvr2450(dboard_base::ctor_args_t args){
UHD_STATIC_BLOCK(reg_xcvr2450_dboard){
//register the factory function for the rx and tx dbids
- dboard_manager::register_dboard(0x0060, &make_xcvr2450, "XCVR2450 TX");
- dboard_manager::register_dboard(0x0061, &make_xcvr2450, "XCVR2450 RX");
+ dboard_manager::register_dboard(0x0061, 0x0060, &make_xcvr2450, "XCVR2450");
}
/***********************************************************************
diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp
index 35ddfc4ee..6321e018f 100644
--- a/host/lib/usrp/dboard_manager.cpp
+++ b/host/lib/usrp/dboard_manager.cpp
@@ -43,7 +43,7 @@ typedef uhd::dict<dboard_id_t, args_t> id_to_args_map_t;
UHD_SINGLETON_FCN(id_to_args_map_t, get_id_to_args_map)
void dboard_manager::register_dboard(
- dboard_id_t dboard_id,
+ const dboard_id_t &dboard_id,
dboard_ctor_t dboard_ctor,
const std::string &name,
const prop_names_t &subdev_names
@@ -57,6 +57,26 @@ void dboard_manager::register_dboard(
get_id_to_args_map()[dboard_id] = args_t(dboard_ctor, name, subdev_names);
}
+//map an xcvr dboard id to its partner dboard id
+typedef uhd::dict<dboard_id_t, dboard_id_t> xcvr_id_to_id_map_t;
+UHD_SINGLETON_FCN(xcvr_id_to_id_map_t, get_xcvr_id_to_id_map)
+
+void dboard_manager::register_dboard(
+ const dboard_id_t &rx_dboard_id,
+ const dboard_id_t &tx_dboard_id,
+ dboard_ctor_t dboard_ctor,
+ const std::string &name,
+ const prop_names_t &subdev_names
+){
+ //regular registration for ids
+ register_dboard(rx_dboard_id, dboard_ctor, name + " RX", subdev_names);
+ register_dboard(tx_dboard_id, dboard_ctor, name + " TX", subdev_names);
+
+ //register xcvr mapping for ids
+ get_xcvr_id_to_id_map()[rx_dboard_id] = tx_dboard_id;
+ get_xcvr_id_to_id_map()[tx_dboard_id] = rx_dboard_id;
+}
+
std::string dboard_id_t::to_pp_string(void) const{
std::string name = "unknown";
if (get_id_to_args_map().has_key(*this)){
@@ -168,26 +188,27 @@ dboard_manager::sptr dboard_manager::make(
**********************************************************************/
static args_t get_dboard_args(
dboard_iface::unit_t unit,
- dboard_id_t dboard_id
+ dboard_id_t dboard_id,
+ bool force_to_unknown = false
){
//special case, the none id was provided, use the following ids
- if (dboard_id == dboard_id_t::none()){
+ if (dboard_id == dboard_id_t::none() or force_to_unknown){
std::cerr << boost::format(
- "Warning: unregistered dboard id: %s"
- " -> defaulting to a basic board"
+ "Warning: unknown dboard-id or dboard-id combination: %s\n"
+ " -> defaulting to the unknown board type"
) % dboard_id.to_pp_string() << std::endl;
- UHD_ASSERT_THROW(get_id_to_args_map().has_key(0x0001));
- UHD_ASSERT_THROW(get_id_to_args_map().has_key(0x0000));
+ UHD_ASSERT_THROW(get_id_to_args_map().has_key(0xfff1));
+ UHD_ASSERT_THROW(get_id_to_args_map().has_key(0xfff0));
switch(unit){
- case dboard_iface::UNIT_RX: return get_dboard_args(unit, 0x0001);
- case dboard_iface::UNIT_TX: return get_dboard_args(unit, 0x0000);
+ case dboard_iface::UNIT_RX: return get_dboard_args(unit, 0xfff1);
+ case dboard_iface::UNIT_TX: return get_dboard_args(unit, 0xfff0);
default: UHD_THROW_INVALID_CODE_PATH();
}
}
//verify that there is a registered constructor for this id
if (not get_id_to_args_map().has_key(dboard_id)){
- return get_dboard_args(unit, dboard_id_t::none());
+ return get_dboard_args(unit, dboard_id, true);
}
//return the dboard args for this id
@@ -201,11 +222,21 @@ dboard_manager_impl::dboard_manager_impl(
){
_iface = iface;
+ //determine xcvr status
+ bool rx_dboard_is_xcvr = get_xcvr_id_to_id_map().has_key(rx_dboard_id);
+ bool tx_dboard_is_xcvr = get_xcvr_id_to_id_map().has_key(tx_dboard_id);
+ bool this_dboard_is_xcvr = (
+ rx_dboard_is_xcvr and tx_dboard_is_xcvr and
+ (get_xcvr_id_to_id_map()[rx_dboard_id] == tx_dboard_id) and
+ (get_xcvr_id_to_id_map()[tx_dboard_id] == rx_dboard_id)
+ );
+
+ //extract dboard constructor and settings (force to unknown for messed up xcvr status)
dboard_ctor_t rx_dboard_ctor; std::string rx_name; prop_names_t rx_subdevs;
- boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_dboard_args(dboard_iface::UNIT_RX, rx_dboard_id);
+ boost::tie(rx_dboard_ctor, rx_name, rx_subdevs) = get_dboard_args(dboard_iface::UNIT_RX, rx_dboard_id, rx_dboard_is_xcvr != this_dboard_is_xcvr);
dboard_ctor_t tx_dboard_ctor; std::string tx_name; prop_names_t tx_subdevs;
- boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_dboard_args(dboard_iface::UNIT_TX, tx_dboard_id);
+ boost::tie(tx_dboard_ctor, tx_name, tx_subdevs) = get_dboard_args(dboard_iface::UNIT_TX, tx_dboard_id, tx_dboard_is_xcvr != this_dboard_is_xcvr);
//initialize the gpio pins before creating subdevs
set_nice_dboard_if();
@@ -215,7 +246,8 @@ dboard_manager_impl::dboard_manager_impl(
db_ctor_args.db_iface = iface;
//make xcvr subdevs (make one subdev for both rx and tx dboards)
- if (rx_dboard_ctor == tx_dboard_ctor){
+ if (this_dboard_is_xcvr){
+ UHD_ASSERT_THROW(rx_dboard_ctor == tx_dboard_ctor);
UHD_ASSERT_THROW(rx_subdevs == tx_subdevs);
BOOST_FOREACH(const std::string &subdev, rx_subdevs){
db_ctor_args.sd_name = subdev;
diff --git a/host/utils/uhd_burn_db_eeprom.cpp b/host/utils/uhd_burn_db_eeprom.cpp
index dfd9decba..ba7aa6cec 100644
--- a/host/utils/uhd_burn_db_eeprom.cpp
+++ b/host/utils/uhd_burn_db_eeprom.cpp
@@ -32,16 +32,6 @@ using namespace uhd;
using namespace uhd::usrp;
namespace po = boost::program_options;
-//used with lexical cast to parse a hex string
-template <class T> struct to_hex{
- T value;
- operator T() const {return value;}
- friend std::istream& operator>>(std::istream& in, to_hex& out){
- in >> std::hex >> out.value;
- return in;
- }
-};
-
int UHD_SAFE_MAIN(int argc, char *argv[]){
//command line variables
std::string args, db_name, unit;
@@ -55,7 +45,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
("args", po::value<std::string>(&args)->default_value(""), "device address args [default = \"\"]")
("db", po::value<std::string>(&db_name)->default_value(""), "dboard name [default = \"\"]")
("unit", po::value<std::string>(&unit)->default_value(""), "which unit [RX or TX]")
- ("id", po::value<std::string>(), "dboard id to burn (hex string), omit for readback")
+ ("id", po::value<std::string>(), "dboard id to burn, omit for readback")
;
po::variables_map vm;