From 359c4e16b2d2748a97ce33073c64502a7f190aa6 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 25 Oct 2010 13:41:40 -0700 Subject: uhd: created tune request struct and implemented more fine grained tuning calls --- host/include/uhd/types/CMakeLists.txt | 1 + host/include/uhd/types/tune_request.hpp | 97 ++++++++++++++++++++++ host/include/uhd/usrp/mimo_usrp.hpp | 16 ++-- host/include/uhd/usrp/multi_usrp.hpp | 31 +++---- host/include/uhd/usrp/simple_usrp.hpp | 16 ++-- host/include/uhd/usrp/single_usrp.hpp | 31 +++---- host/include/uhd/usrp/tune_helper.hpp | 31 ++----- host/lib/types.cpp | 20 +++++ host/lib/usrp/multi_usrp.cpp | 24 ++---- host/lib/usrp/single_usrp.cpp | 24 ++---- host/lib/usrp/tune_helper.cpp | 138 ++++++++++++++++++-------------- 11 files changed, 247 insertions(+), 182 deletions(-) create mode 100644 host/include/uhd/types/tune_request.hpp diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index dbce21c98..661dd2d39 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -28,6 +28,7 @@ INSTALL(FILES serial.hpp stream_cmd.hpp time_spec.hpp + tune_request.hpp tune_result.hpp DESTINATION ${INCLUDE_DIR}/uhd/types ) diff --git a/host/include/uhd/types/tune_request.hpp b/host/include/uhd/types/tune_request.hpp new file mode 100644 index 000000000..f80d2cb15 --- /dev/null +++ b/host/include/uhd/types/tune_request.hpp @@ -0,0 +1,97 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP +#define INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP + +#include + +namespace uhd{ + + /*! + * A tune request instructs the implementation how to tune the RF chain. + * The policies can be used to select automatic tuning or + * fined control over the daughterboard IF and DSP tuning. + * Not all combinations of policies are applicable. + * Convenience constructors are supplied for most use cases. + */ + struct UHD_API tune_request_t{ + /*! + * Make a new tune request for a particular center frequency. + * Use an automatic policy for the intermediate and DSP frequency + * to tune the chain as close as possible to the target frequency. + * \param target_freq the target frequency in Hz + */ + tune_request_t(double target_freq = 0); + + /*! + * Make a new tune request for a particular center frequency. + * Use a manual policy for the intermediate frequency, + * and an automatic policy for the DSP frequency, + * to tune the chain as close as possible to the target frequency. + * \param target_freq the target frequency in Hz + * \param lo_off the LO offset frequency in Hz + */ + tune_request_t(double target_freq, double lo_off); + + /*! + * Policy types for tune arguments: + * - None: do not set this argument, use current setting + * - Auto: automatically determine the argument's value + * - Manual: use the argument's value for the setting + */ + enum policy_t { + POLICY_NONE = 'N', + POLICY_AUTO = 'A', + POLICY_MANUAL = 'M' + }; + + /*! + * The target frequency of the overall chain in Hz. + * Use when one of the policies is set to automatic. + */ + double target_freq; + + /*! + * The policy for the intermediate frequency. + * Automatic behavior: the target frequency + default LO offset. + */ + policy_t inter_freq_policy; + + /*! + * The intermediate frequency in Hz. + * Set when the policy is set to manual. + */ + double inter_freq; + + /*! + * The policy for the DSP frequency. + * Automatic behavior: the difference between the target and IF. + */ + policy_t dsp_freq_policy; + + /*! + * The DSP frequency in Hz. + * Set when the policy is set to manual. + */ + double dsp_freq; + + }; + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_TUNE_REQUEST_HPP */ diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp index 78833e24e..b5acf84e1 100644 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -127,7 +127,7 @@ public: virtual double get_rx_rate_all(void) = 0; virtual tune_result_t set_rx_freq(size_t chan, double freq) = 0; - virtual tune_result_t set_rx_freq(size_t chan, double freq, double lo_off) = 0; + //virtual tune_result_t set_rx_freq(size_t chan, double freq, double lo_off) = 0; virtual double get_rx_freq(size_t chan) = 0; virtual freq_range_t get_rx_freq_range(size_t chan) = 0; @@ -161,7 +161,7 @@ public: virtual double get_tx_rate_all(void) = 0; virtual tune_result_t set_tx_freq(size_t chan, double freq) = 0; - virtual tune_result_t set_tx_freq(size_t chan, double freq, double lo_off) = 0; + //virtual tune_result_t set_tx_freq(size_t chan, double freq, double lo_off) = 0; virtual double get_tx_freq(size_t chan) = 0; virtual freq_range_t get_tx_freq_range(size_t chan) = 0; @@ -345,9 +345,9 @@ public: return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0, target_freq); } - tune_result_t set_rx_freq(size_t chan, double target_freq, double lo_off){ - return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0, target_freq, lo_off); - } + //tune_result_t set_rx_freq(size_t chan, double target_freq, double lo_off){ + // return tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0, target_freq, lo_off); + //} double get_rx_freq(size_t chan){ return derive_freq_from_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan), 0); @@ -425,9 +425,9 @@ public: return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0, target_freq); } - tune_result_t set_tx_freq(size_t chan, double target_freq, double lo_off){ - return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0, target_freq, lo_off); - } + //tune_result_t set_tx_freq(size_t chan, double target_freq, double lo_off){ + // return tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0, target_freq, lo_off); + //} double get_tx_freq(size_t chan){ return derive_freq_from_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan), 0); diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 2f71f80b1..5380d177d 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -213,20 +214,13 @@ public: /*! * Set the RX center frequency. - * \param freq the frequency in Hz + * \param tune_request tune request instructions * \param chan the channel index 0 to N-1 * \return a tune result object */ - virtual tune_result_t set_rx_freq(double freq, size_t chan) = 0; - - /*! - * Set the RX center frequency. - * \param freq the frequency in Hz - * \param lo_off an LO offset in Hz - * \param chan the channel index 0 to N-1 - * \return a tune result object - */ - virtual tune_result_t set_rx_freq(double freq, double lo_off, size_t chan) = 0; + virtual tune_result_t set_rx_freq( + const tune_request_t &tune_request, size_t chan = 0 + ) = 0; /*! * Get the RX center frequency. @@ -399,20 +393,13 @@ public: /*! * Set the TX center frequency. - * \param freq the frequency in Hz - * \param chan the channel index 0 to N-1 - * \return a tune result object - */ - virtual tune_result_t set_tx_freq(double freq, size_t chan) = 0; - - /*! - * Set the TX center frequency. - * \param freq the frequency in Hz - * \param lo_off an LO offset in Hz + * \param tune_request tune request instructions * \param chan the channel index 0 to N-1 * \return a tune result object */ - virtual tune_result_t set_tx_freq(double freq, double lo_off, size_t chan) = 0; + virtual tune_result_t set_tx_freq( + const tune_request_t &tune_request, size_t chan = 0 + ) = 0; /*! * Get the TX center frequency. diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp index 22f4d64ba..59fd9bb09 100644 --- a/host/include/uhd/usrp/simple_usrp.hpp +++ b/host/include/uhd/usrp/simple_usrp.hpp @@ -117,7 +117,7 @@ public: virtual double get_rx_rate(void) = 0; virtual tune_result_t set_rx_freq(double freq) = 0; - virtual tune_result_t set_rx_freq(double freq, double lo_off) = 0; + //virtual tune_result_t set_rx_freq(double freq, double lo_off) = 0; virtual double get_rx_freq(void) = 0; virtual freq_range_t get_rx_freq_range(void) = 0; @@ -152,7 +152,7 @@ public: virtual double get_tx_rate(void) = 0; virtual tune_result_t set_tx_freq(double freq) = 0; - virtual tune_result_t set_tx_freq(double freq, double lo_off) = 0; + //virtual tune_result_t set_tx_freq(double freq, double lo_off) = 0; virtual double get_tx_freq(void) = 0; virtual freq_range_t get_tx_freq_range(void) = 0; @@ -243,9 +243,9 @@ public: return _sdev->set_rx_freq(target_freq); } - tune_result_t set_rx_freq(double target_freq, double lo_off){ - return _sdev->set_rx_freq(target_freq, lo_off); - } + //tune_result_t set_rx_freq(double target_freq, double lo_off){ + // return _sdev->set_rx_freq(target_freq, lo_off); + //} double get_rx_freq(void){ return _sdev->get_rx_freq(); @@ -318,9 +318,9 @@ public: return _sdev->set_tx_freq(target_freq); } - tune_result_t set_tx_freq(double target_freq, double lo_off){ - return _sdev->set_tx_freq(target_freq, lo_off); - } + //tune_result_t set_tx_freq(double target_freq, double lo_off){ + // return _sdev->set_tx_freq(target_freq, lo_off); + //} double get_tx_freq(void){ return _sdev->get_tx_freq(); diff --git a/host/include/uhd/usrp/single_usrp.hpp b/host/include/uhd/usrp/single_usrp.hpp index a068fbed8..26303fe10 100644 --- a/host/include/uhd/usrp/single_usrp.hpp +++ b/host/include/uhd/usrp/single_usrp.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -154,20 +155,13 @@ public: /*! * Set the RX center frequency. - * \param freq the frequency in Hz + * \param tune_request tune request instructions * \param chan the channel index 0 to N-1 * \return a tune result object */ - virtual tune_result_t set_rx_freq(double freq, size_t chan = 0) = 0; - - /*! - * Set the RX center frequency. - * \param freq the frequency in Hz - * \param lo_off an LO offset in Hz - * \param chan the channel index 0 to N-1 - * \return a tune result object - */ - virtual tune_result_t set_rx_freq(double freq, double lo_off, size_t chan = 0) = 0; + virtual tune_result_t set_rx_freq( + const tune_request_t &tune_request, size_t chan = 0 + ) = 0; /*! * Get the RX center frequency. @@ -330,20 +324,13 @@ public: /*! * Set the TX center frequency. - * \param freq the frequency in Hz - * \param chan the channel index 0 to N-1 - * \return a tune result object - */ - virtual tune_result_t set_tx_freq(double freq, size_t chan = 0) = 0; - - /*! - * Set the TX center frequency. - * \param freq the frequency in Hz - * \param lo_off an LO offset in Hz + * \param tune_request tune request instructions * \param chan the channel index 0 to N-1 * \return a tune result object */ - virtual tune_result_t set_tx_freq(double freq, double lo_off, size_t chan = 0) = 0; + virtual tune_result_t set_tx_freq( + const tune_request_t &tune_request, size_t chan = 0 + ) = 0; /*! * Get the TX center frequency. diff --git a/host/include/uhd/usrp/tune_helper.hpp b/host/include/uhd/usrp/tune_helper.hpp index ec133fa08..db12241c1 100644 --- a/host/include/uhd/usrp/tune_helper.hpp +++ b/host/include/uhd/usrp/tune_helper.hpp @@ -20,6 +20,7 @@ #include #include +#include #include namespace uhd{ namespace usrp{ @@ -32,23 +33,12 @@ namespace uhd{ namespace usrp{ * \param subdev the dboard subdevice object with properties * \param ddc the mboard dsp object with properties * \param chan the channel of the dsp to tune - * \param target_freq the desired center frequency - * \param lo_offset an offset for the subdevice IF from center + * \param tune_request tune request instructions * \return a tune result struct */ UHD_API tune_result_t tune_rx_subdev_and_dsp( wax::obj subdev, wax::obj ddc, size_t chan, - double target_freq, double lo_offset - ); - - /*! - * Tune a rx chain to the desired frequency: - * Same as the above, except the LO offset - * is calculated based on the subdevice and BW. - */ - UHD_API tune_result_t tune_rx_subdev_and_dsp( - wax::obj subdev, wax::obj ddc, - size_t chan, double target_freq + const tune_request_t &tune_request ); /*! @@ -70,23 +60,12 @@ namespace uhd{ namespace usrp{ * \param subdev the dboard subdevice object with properties * \param duc the mboard dsp object with properties * \param chan the channel of the dsp to tune - * \param target_freq the desired center frequency - * \param lo_offset an offset for the subdevice IF from center + * \param tune_request tune request instructions * \return a tune result struct */ UHD_API tune_result_t tune_tx_subdev_and_dsp( wax::obj subdev, wax::obj duc, size_t chan, - double target_freq, double lo_offset - ); - - /*! - * Tune a tx chain to the desired frequency: - * Same as the above, except the LO offset - * is calculated based on the subdevice and BW. - */ - UHD_API tune_result_t tune_tx_subdev_and_dsp( - wax::obj subdev, wax::obj duc, - size_t chan, double target_freq + const tune_request_t &tune_request ); /*! diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 6aa82b012..a8062b6ae 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,25 @@ freq_range_t::freq_range_t(double min, double max): /* NOP */ } +/*********************************************************************** + * tune request + **********************************************************************/ +tune_request_t::tune_request_t(double target_freq): + target_freq(target_freq), + inter_freq_policy(POLICY_AUTO), + dsp_freq_policy(POLICY_AUTO) +{ + /* NOP */ +} + +tune_request_t::tune_request_t(double target_freq, double lo_off): + target_freq(target_freq + lo_off), + inter_freq_policy(POLICY_MANUAL), + dsp_freq_policy(POLICY_AUTO) +{ + /* NOP */ +} + /*********************************************************************** * tune result **********************************************************************/ diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 443b91594..8b82502ba 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -210,15 +210,9 @@ public: return _rx_dsp(0)[DSP_PROP_HOST_RATE].as(); } - tune_result_t set_rx_freq(double target_freq, size_t chan){ - tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan/rx_cpm()), chan%rx_cpm(), target_freq); - do_tune_freq_warning_message(target_freq, get_rx_freq(chan), "RX"); - return r; - } - - tune_result_t set_rx_freq(double target_freq, double lo_off, size_t chan){ - tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan/rx_cpm()), chan%rx_cpm(), target_freq, lo_off); - do_tune_freq_warning_message(target_freq, get_rx_freq(chan), "RX"); + tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){ + tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(chan/rx_cpm()), chan%rx_cpm(), tune_request); + do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX"); return r; } @@ -314,15 +308,9 @@ public: return _tx_dsp(0)[DSP_PROP_HOST_RATE].as(); } - tune_result_t set_tx_freq(double target_freq, size_t chan){ - tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan/tx_cpm()), chan%tx_cpm(), target_freq); - do_tune_freq_warning_message(target_freq, get_tx_freq(chan), "TX"); - return r; - } - - tune_result_t set_tx_freq(double target_freq, double lo_off, size_t chan){ - tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan/tx_cpm()), chan%tx_cpm(), target_freq, lo_off); - do_tune_freq_warning_message(target_freq, get_tx_freq(chan), "TX"); + tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){ + tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(chan/tx_cpm()), chan%tx_cpm(), tune_request); + do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "TX"); return r; } diff --git a/host/lib/usrp/single_usrp.cpp b/host/lib/usrp/single_usrp.cpp index 5e57849b8..a0456d1f0 100644 --- a/host/lib/usrp/single_usrp.cpp +++ b/host/lib/usrp/single_usrp.cpp @@ -146,15 +146,9 @@ public: return _rx_dsp()[DSP_PROP_HOST_RATE].as(); } - tune_result_t set_rx_freq(double target_freq, size_t chan){ - tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(), chan, target_freq); - do_tune_freq_warning_message(target_freq, get_rx_freq(chan), "RX"); - return r; - } - - tune_result_t set_rx_freq(double target_freq, double lo_off, size_t chan){ - tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(), chan, target_freq, lo_off); - do_tune_freq_warning_message(target_freq, get_rx_freq(chan), "RX"); + tune_result_t set_rx_freq(const tune_request_t &tune_request, size_t chan){ + tune_result_t r = tune_rx_subdev_and_dsp(_rx_subdev(chan), _rx_dsp(), chan, tune_request); + do_tune_freq_warning_message(tune_request.target_freq, get_rx_freq(chan), "RX"); return r; } @@ -238,15 +232,9 @@ public: return _tx_dsp()[DSP_PROP_HOST_RATE].as(); } - tune_result_t set_tx_freq(double target_freq, size_t chan){ - tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(), chan, target_freq); - do_tune_freq_warning_message(target_freq, get_tx_freq(chan), "TX"); - return r; - } - - tune_result_t set_tx_freq(double target_freq, double lo_off, size_t chan){ - tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(), chan, target_freq, lo_off); - do_tune_freq_warning_message(target_freq, get_tx_freq(chan), "TX"); + tune_result_t set_tx_freq(const tune_request_t &tune_request, size_t chan){ + tune_result_t r = tune_tx_subdev_and_dsp(_tx_subdev(chan), _tx_dsp(), chan, tune_request); + do_tune_freq_warning_message(tune_request.target_freq, get_tx_freq(chan), "TX"); return r; } diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 7633c67f2..8c57cc428 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -28,55 +28,97 @@ using namespace uhd::usrp; /*********************************************************************** * Tune Helper Functions **********************************************************************/ -static tune_result_t tune_xx_subdev_and_dxc( +static tune_result_t tune_xx_subdev_and_dsp( dboard_iface::unit_t unit, - wax::obj subdev, wax::obj dxc, size_t chan, - double target_freq, double lo_offset + wax::obj subdev, wax::obj dsp, size_t chan, + const tune_request_t &tune_request ){ wax::obj subdev_freq_proxy = subdev[SUBDEV_PROP_FREQ]; - std::string freq_name = dxc[DSP_PROP_FREQ_SHIFT_NAMES].as().at(chan); - wax::obj dxc_freq_proxy = dxc[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)]; - double dxc_sample_rate = dxc[DSP_PROP_CODEC_RATE].as(); + std::string freq_name = dsp[DSP_PROP_FREQ_SHIFT_NAMES].as().at(chan); + wax::obj dsp_freq_proxy = dsp[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)]; + double dsp_sample_rate = dsp[DSP_PROP_CODEC_RATE].as(); - // Ask the d'board to tune as closely as it can to target_freq+lo_offset - double target_inter_freq = target_freq + lo_offset; - subdev_freq_proxy = target_inter_freq; - double actual_inter_freq = subdev_freq_proxy.as(); - - //perform the correction correction for dxc rates outside of nyquist - double delta_freq = std::fmod(target_freq - actual_inter_freq, dxc_sample_rate); - bool outside_of_nyquist = std::abs(delta_freq) > dxc_sample_rate/2.0; - double target_dxc_freq = (outside_of_nyquist)? - boost::math::sign(delta_freq)*dxc_sample_rate - delta_freq : -delta_freq; + //------------------------------------------------------------------ + //-- calculate the LO offset, only used with automatic policy + //------------------------------------------------------------------ + double lo_offset = 0.0; + if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as()){ + //if the local oscillator will be in the passband, use an offset + //TODO make this nicer, use bandwidth property to clip bounds + lo_offset = 2.0*dsp[DSP_PROP_HOST_RATE].as(); + } - //invert the sign on the dxc freq given the following conditions - if (unit == dboard_iface::UNIT_TX) target_dxc_freq *= -1.0; + //------------------------------------------------------------------ + //-- set the intermediate frequency depending upon the IF policy + //------------------------------------------------------------------ + double target_inter_freq = 0.0; + switch (tune_request.inter_freq_policy){ + case tune_request_t::POLICY_AUTO: + target_inter_freq = tune_request.target_freq + lo_offset; + subdev_freq_proxy = target_inter_freq; + break; + + case tune_request_t::POLICY_MANUAL: + target_inter_freq = tune_request.inter_freq; + subdev_freq_proxy = target_inter_freq; + break; + + case tune_request_t::POLICY_NONE: break; //does not set + } + double actual_inter_freq = subdev_freq_proxy.as(); - dxc_freq_proxy = target_dxc_freq; - double actual_dxc_freq = dxc_freq_proxy.as(); + //------------------------------------------------------------------ + //-- calculate the dsp freq, only used with automatic policy + //------------------------------------------------------------------ + double delta_freq = std::fmod(target_inter_freq - actual_inter_freq, dsp_sample_rate); + bool outside_of_nyquist = std::abs(delta_freq) > dsp_sample_rate/2.0; + double target_dsp_freq = (outside_of_nyquist)? + boost::math::sign(delta_freq)*dsp_sample_rate - delta_freq : -delta_freq; + + //invert the sign on the dsp freq given the following conditions + if (unit == dboard_iface::UNIT_TX) target_dsp_freq *= -1.0; + + //------------------------------------------------------------------ + //-- set the dsp frequency depending upon the dsp frequency policy + //------------------------------------------------------------------ + switch (tune_request.dsp_freq_policy){ + case tune_request_t::POLICY_AUTO: + dsp_freq_proxy = target_dsp_freq; + break; + + case tune_request_t::POLICY_MANUAL: + target_dsp_freq = tune_request.dsp_freq; + dsp_freq_proxy = target_dsp_freq; + break; + + case tune_request_t::POLICY_NONE: break; //does not set + } + double actual_dsp_freq = dsp_freq_proxy.as(); - //load and return the tune result + //------------------------------------------------------------------ + //-- load and return the tune result + //------------------------------------------------------------------ tune_result_t tune_result; tune_result.target_inter_freq = target_inter_freq; tune_result.actual_inter_freq = actual_inter_freq; - tune_result.target_dsp_freq = target_dxc_freq; - tune_result.actual_dsp_freq = actual_dxc_freq; + tune_result.target_dsp_freq = target_dsp_freq; + tune_result.actual_dsp_freq = actual_dsp_freq; return tune_result; } -static double derive_freq_from_xx_subdev_and_dxc( +static double derive_freq_from_xx_subdev_and_dsp( dboard_iface::unit_t unit, - wax::obj subdev, wax::obj dxc, size_t chan + wax::obj subdev, wax::obj dsp, size_t chan ){ //extract actual dsp and IF frequencies double actual_inter_freq = subdev[SUBDEV_PROP_FREQ].as(); - std::string freq_name = dxc[DSP_PROP_FREQ_SHIFT_NAMES].as().at(chan); - double actual_dxc_freq = dxc[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)].as(); + std::string freq_name = dsp[DSP_PROP_FREQ_SHIFT_NAMES].as().at(chan); + double actual_dsp_freq = dsp[named_prop_t(DSP_PROP_FREQ_SHIFT, freq_name)].as(); - //invert the sign on the dxc freq given the following conditions - if (unit == dboard_iface::UNIT_TX) actual_dxc_freq *= -1.0; + //invert the sign on the dsp freq given the following conditions + if (unit == dboard_iface::UNIT_TX) actual_dsp_freq *= -1.0; - return actual_inter_freq - actual_dxc_freq; + return actual_inter_freq - actual_dsp_freq; } /*********************************************************************** @@ -84,27 +126,15 @@ static double derive_freq_from_xx_subdev_and_dxc( **********************************************************************/ tune_result_t usrp::tune_rx_subdev_and_dsp( wax::obj subdev, wax::obj ddc, size_t chan, - double target_freq, double lo_offset -){ - return tune_xx_subdev_and_dxc(dboard_iface::UNIT_RX, subdev, ddc, chan, target_freq, lo_offset); -} - -tune_result_t usrp::tune_rx_subdev_and_dsp( - wax::obj subdev, wax::obj ddc, - size_t chan, double target_freq + const tune_request_t &tune_request ){ - double lo_offset = 0.0; - //if the local oscillator will be in the passband, use an offset - if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as()){ - lo_offset = 2.0*ddc[DSP_PROP_HOST_RATE].as(); - } - return tune_rx_subdev_and_dsp(subdev, ddc, chan, target_freq, lo_offset); + return tune_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, chan, tune_request); } double usrp::derive_freq_from_rx_subdev_and_dsp( wax::obj subdev, wax::obj ddc, size_t chan ){ - return derive_freq_from_xx_subdev_and_dxc(dboard_iface::UNIT_RX, subdev, ddc, chan); + return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_RX, subdev, ddc, chan); } /*********************************************************************** @@ -112,25 +142,13 @@ double usrp::derive_freq_from_rx_subdev_and_dsp( **********************************************************************/ tune_result_t usrp::tune_tx_subdev_and_dsp( wax::obj subdev, wax::obj duc, size_t chan, - double target_freq, double lo_offset + const tune_request_t &tune_request ){ - return tune_xx_subdev_and_dxc(dboard_iface::UNIT_TX, subdev, duc, chan, target_freq, lo_offset); -} - -tune_result_t usrp::tune_tx_subdev_and_dsp( - wax::obj subdev, wax::obj duc, - size_t chan, double target_freq -){ - double lo_offset = 0.0; - //if the local oscillator will be in the passband, use an offset - if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as()){ - lo_offset = 2.0*duc[DSP_PROP_HOST_RATE].as(); - } - return tune_tx_subdev_and_dsp(subdev, duc, chan, target_freq, lo_offset); + return tune_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, chan, tune_request); } double usrp::derive_freq_from_tx_subdev_and_dsp( wax::obj subdev, wax::obj duc, size_t chan ){ - return derive_freq_from_xx_subdev_and_dxc(dboard_iface::UNIT_TX, subdev, duc, chan); + return derive_freq_from_xx_subdev_and_dsp(dboard_iface::UNIT_TX, subdev, duc, chan); } -- cgit v1.2.3 From bb82453a77c4bb8ff585fc498b300cd83bb62314 Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Mon, 25 Oct 2010 15:42:08 -0700 Subject: Added bandwidth property to all daughterboards Updated existing bandwidth property to reflect double-sided bandwidth rather than lowpass bandwidth --- host/lib/usrp/dboard/db_basic_and_lf.cpp | 29 +++++++++++++++++++++++++++-- host/lib/usrp/dboard/db_dbsrx.cpp | 4 ++-- host/lib/usrp/dboard/db_rfx.cpp | 21 +++++++++++++++++++++ host/lib/usrp/dboard/db_tvrx.cpp | 10 ++++++++++ host/lib/usrp/dboard/db_unknown.cpp | 23 ++++++++++++++++++++++- host/lib/usrp/dboard/db_wbx.cpp | 21 +++++++++++++++++++++ host/lib/usrp/dboard/db_xcvr2450.cpp | 8 ++++---- 7 files changed, 107 insertions(+), 9 deletions(-) diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 41f6f8002..5a87f4ecf 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -68,11 +69,11 @@ static const uhd::dict sd_name_to_conn = map_list_of * Register the basic and LF dboards **********************************************************************/ static dboard_base::sptr make_basic_rx(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new basic_rx(args, 90e9)); + return dboard_base::sptr(new basic_rx(args, 250e6)); } static dboard_base::sptr make_basic_tx(dboard_base::ctor_args_t args){ - return dboard_base::sptr(new basic_tx(args, 90e9)); + return dboard_base::sptr(new basic_tx(args, 250e6)); } static dboard_base::sptr make_lf_rx(dboard_base::ctor_args_t args){ @@ -161,6 +162,10 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = true; //there is no LO, so it must be true! return; + case SUBDEV_PROP_BANDWIDTH: + val = 2*_max_freq; //we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -185,6 +190,14 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("%s: No tunable bandwidth, fixed filtered to %0.2fMHz") + % get_rx_id().to_pp_string() % _max_freq + ) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } @@ -260,6 +273,10 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = true; //there is no LO, so it must be true! return; + case SUBDEV_PROP_BANDWIDTH: + val = 2*_max_freq; //we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -284,6 +301,14 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("%s: No tunable bandwidth, fixed filtered to %0.2fMHz") + % get_tx_id().to_pp_string() % _max_freq + ) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index aecd7249d..10e7f292b 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -563,7 +563,7 @@ void dbsrx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = _bandwidth; + val = 2*_bandwidth; //_bandwidth is low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); @@ -588,7 +588,7 @@ void dbsrx::rx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - this->set_bandwidth(val.as()); + this->set_bandwidth(val.as()/2.0); //complex double-sided, we want low-pass return; default: UHD_THROW_PROP_SET_ERROR(); diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 3c24d90db..0eeb0bfdf 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -456,6 +457,10 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = this->get_locked(dboard_iface::UNIT_RX); return; + case SUBDEV_PROP_BANDWIDTH: + val = 2*20.0e6; //30MHz low-pass, we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -481,6 +486,12 @@ void rfx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("RFX: No tunable bandwidth, fixed filtered to 40MHz")) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } @@ -543,6 +554,10 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = this->get_locked(dboard_iface::UNIT_TX); return; + case SUBDEV_PROP_BANDWIDTH: + val = 2*20.0e6; //30MHz low-pass, we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -568,6 +583,12 @@ void rfx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("RFX: No tunable bandwidth, fixed filtered to 40MHz")) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index d39dc3bf8..c7aecf195 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -459,6 +459,10 @@ void tvrx::rx_get(const wax::obj &key_, wax::obj &val){ val = true; return; + case SUBDEV_PROP_BANDWIDTH: + val = 6.0e6; //30MHz low-pass, we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -479,6 +483,12 @@ void tvrx::rx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("TVRX: No tunable bandwidth, fixed filtered to 6MHz")) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index ec7ab440b..11293a1ba 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,10 @@ void unknown_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = true; //there is no LO, so it must be true! return; + case SUBDEV_PROP_BANDWIDTH: + val = 0.0; + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -158,12 +163,18 @@ void unknown_rx::rx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("Unknown Daughterboard: No tunable bandwidth, fixed filtered to 0.0MHz")) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } /*********************************************************************** - * Basic and LF TX dboard + * Unknown TX dboard **********************************************************************/ unknown_tx::unknown_tx(ctor_args_t args) : tx_dboard_base(args){ /* NOP */ @@ -230,6 +241,10 @@ void unknown_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = true; //there is no LO, so it must be true! return; + case SUBDEV_PROP_BANDWIDTH: + val = 0.0; + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -254,6 +269,12 @@ void unknown_tx::tx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("Unknown Daughterboard: No tunable bandwidth, fixed filtered to 0.0MHz")) + ); + return; + 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 907268aac..b07f179a3 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -525,6 +526,10 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = this->get_locked(dboard_iface::UNIT_RX); return; + case SUBDEV_PROP_BANDWIDTH: + val = 2*30.0e6; //20MHz low-pass, we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -550,6 +555,12 @@ void wbx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("WBX: No tunable bandwidth, fixed filtered to 40MHz")) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } @@ -616,6 +627,10 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = this->get_locked(dboard_iface::UNIT_TX); return; + case SUBDEV_PROP_BANDWIDTH: + val = 2*30.0e6; //20MHz low-pass, we want complex double-sided + return; + default: UHD_THROW_PROP_GET_ERROR(); } } @@ -641,6 +656,12 @@ void wbx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ case SUBDEV_PROP_ENABLED: return; //always enabled + case SUBDEV_PROP_BANDWIDTH: + uhd::print_warning( + str(boost::format("WBX: No tunable bandwidth, fixed filtered to 40MHz")) + ); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } diff --git a/host/lib/usrp/dboard/db_xcvr2450.cpp b/host/lib/usrp/dboard/db_xcvr2450.cpp index fb1367113..be0e42b92 100644 --- a/host/lib/usrp/dboard/db_xcvr2450.cpp +++ b/host/lib/usrp/dboard/db_xcvr2450.cpp @@ -626,7 +626,7 @@ void xcvr2450::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = _rx_bandwidth; + val = 2*_rx_bandwidth; //_tx_bandwidth is low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); @@ -652,7 +652,7 @@ void xcvr2450::rx_set(const wax::obj &key_, const wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - this->set_rx_bandwidth(val.as()); + this->set_rx_bandwidth(val.as()/2.0); //complex double-sided, we want low-pass return; case SUBDEV_PROP_ENABLED: @@ -725,7 +725,7 @@ void xcvr2450::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = _tx_bandwidth; + val = 2*_tx_bandwidth; //_tx_bandwidth is low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); @@ -747,7 +747,7 @@ void xcvr2450::tx_set(const wax::obj &key_, const wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - this->set_tx_bandwidth(val.as()); + this->set_tx_bandwidth(val.as()/2.0); //complex double-sided, we want low-pass return; case SUBDEV_PROP_ANTENNA: -- cgit v1.2.3 From c398e8f437cd21ca9132f7227546060f8dcf9e5c Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Mon, 25 Oct 2010 16:45:09 -0700 Subject: Updated bandwidths in daughterboard docs --- host/docs/dboards.rst | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst index 080117651..d93fb9d6a 100644 --- a/host/docs/dboards.rst +++ b/host/docs/dboards.rst @@ -26,6 +26,10 @@ The boards have no tunable elements or programmable gains. Though the magic of aliasing, you can down-convert signals greater than the Nyquist rate of the ADC. +BasicRX Bandwidth (Hz): 250M + +LFRX Bandwidth (Hz): 30M + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Basic TX and and LFTX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,6 +44,10 @@ The boards have no tunable elements or programmable gains. Though the magic of aliasing, you can up-convert signals greater than the Nyquist rate of the DAC. +BasicTX Bandwidth (Hz): 250M + +LFTX Bandwidth (Hz): 30M + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ DBSRX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,7 +61,7 @@ Receive Gains: **GC1**, Range: 0-56dB **GC2**, Range: 0-24dB -Low-Pass Filter Bandwidth (Hz): 4M-33M +Bandwidth (Hz): 8M-66M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ RFX Series @@ -68,6 +76,10 @@ the receive antenna will always be set to RX2, regardless of the settings. Receive Gains: **PGA0**, Range: 0-70dB (except RFX400 range is 0-45dB) +Bandwidths (Hz): + * **RX**: 40M + * **TX**: 40M + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ XCVR 2450 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,9 +105,9 @@ Receive Gains: * **LNA**, Range: 0-30.5dB * **VGA**, Range: 0-62dB -Low-Pass Filter Bandwidths (Hz): - * **RX**: 7.5M, 9.5M, 14M, 18M; (each +-0, 5, or 10%) - * **TX**: 12M, 18M, 24M +Bandwidths (Hz): + * **RX**: 15M, 19M, 28M, 36M; (each +-0, 5, or 10%) + * **TX**: 24M, 36M, 48M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ WBX Series @@ -112,9 +124,9 @@ Transmit Gains: **PGA0**, Range: 0-25dB Receive Gains: **PGA0**, Range: 0-31.5dB -Low-Pass Filter Bandwidths (Hz): - * **RX**: 20M (Fixed) - * **TX**: 20M (Fixed) +Bandwidths (Hz): + * **RX**: 40M + * **TX**: 40M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ TVRX @@ -125,7 +137,7 @@ Receive Gains: * **RF**, Range: -13.3-50.3dB (frequency-dependent) * **IF**, Range: -1.5-32.5dB -Bandpass Filter Bandwidth: 6MHz +Bandwidth: 6MHz ------------------------------------------------------------------------ Daughterboard Modifications -- cgit v1.2.3 From 2d21958e1b7ecc9ff083f2e60b0b5d06ccb3c638 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 25 Oct 2010 17:04:51 -0700 Subject: uhd: tune helper + request, forgot to use and set target freq --- host/lib/types.cpp | 3 ++- host/lib/usrp/tune_helper.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/host/lib/types.cpp b/host/lib/types.cpp index a8062b6ae..4188568aa 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -70,8 +70,9 @@ tune_request_t::tune_request_t(double target_freq): } tune_request_t::tune_request_t(double target_freq, double lo_off): - target_freq(target_freq + lo_off), + target_freq(target_freq), inter_freq_policy(POLICY_MANUAL), + inter_freq(target_freq + lo_off), dsp_freq_policy(POLICY_AUTO) { /* NOP */ diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index 8c57cc428..a6b615926 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -70,7 +70,7 @@ static tune_result_t tune_xx_subdev_and_dsp( //------------------------------------------------------------------ //-- calculate the dsp freq, only used with automatic policy //------------------------------------------------------------------ - double delta_freq = std::fmod(target_inter_freq - actual_inter_freq, dsp_sample_rate); + double delta_freq = std::fmod(tune_request.target_freq - actual_inter_freq, dsp_sample_rate); bool outside_of_nyquist = std::abs(delta_freq) > dsp_sample_rate/2.0; double target_dsp_freq = (outside_of_nyquist)? boost::math::sign(delta_freq)*dsp_sample_rate - delta_freq : -delta_freq; -- cgit v1.2.3 From 01f670e81c615a16fb5a931d3842f92b56cc6c09 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 25 Oct 2010 18:09:48 -0700 Subject: uhd: doxygen comments, moved enum comments, added to metadata for all entities --- host/include/uhd/types/metadata.hpp | 76 ++++++++++++++++----------------- host/include/uhd/types/tune_request.hpp | 12 +++--- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index 65952941c..3f250d13e 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -19,7 +19,6 @@ #define INCLUDED_UHD_TYPES_METADATA_HPP #include -#include #include namespace uhd{ @@ -30,58 +29,59 @@ namespace uhd{ * The receive routines will convert IF data headers into metadata. */ struct UHD_API rx_metadata_t{ - /*! - * Time specification: - * Set from timestamps on incoming data when provided. - */ + //! Has time specification? bool has_time_spec; + + //! Time of the first sample. time_spec_t time_spec; /*! - * Fragmentation flag and offset: + * Fragmentation flag: * Similar to IPv4 fragmentation: http://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly * More fragments is true when the input buffer has insufficient size to fit * an entire received packet. More fragments will be false for the last fragment. - * The fragment offset is the sample number at the start of the receive buffer. - * For non-fragmented receives, the fragment offset should always be zero. */ bool more_fragments; - size_t fragment_offset; /*! - * Burst flags: - * Start of burst will be true for the first packet in the chain. - * End of burst will be true for the last packet in the chain. + * Fragmentation offset: + * The fragment offset is the sample number at the start of the receive buffer. + * For non-fragmented receives, the fragment offset should always be zero. */ + size_t fragment_offset; + + //! Start of burst will be true for the first packet in the chain. bool start_of_burst; + + //! End of burst will be true for the last packet in the chain. bool end_of_burst; /*! - * Error conditions: - * - none: no error associated with this metadata - * - timeout: no packet received, underlying code timed-out - * - late command: a stream command was issued in the past - * - broken chain: expected another stream command - * - overflow: an internal receive buffer has filled - * - bad packet: the buffer was unrecognizable as a vrt packet + * The error condition on a receive call. * * Note: When an overrun occurs in continuous streaming mode, * the device will continue to send samples to the host. * For other streaming modes, streaming will discontinue * until the user issues a new stream command. * - * Note: The metadata fields have meaning for the following error codes: + * The metadata fields have meaning for the following error codes: * - none * - late command * - broken chain * - overflow */ enum error_code_t { + //! No error associated with this metadata. ERROR_CODE_NONE = 0x0, + //! No packet received, implementation timed-out. ERROR_CODE_TIMEOUT = 0x1, + //! A stream command was issued in the past. ERROR_CODE_LATE_COMMAND = 0x2, + //! Expected another stream command. ERROR_CODE_BROKEN_CHAIN = 0x4, + //! An internal receive buffer has filled. ERROR_CODE_OVERFLOW = 0x8, + //! The packet could not be parsed. ERROR_CODE_BAD_PACKET = 0xf } error_code; }; @@ -93,19 +93,19 @@ namespace uhd{ */ struct UHD_API tx_metadata_t{ /*! - * Time specification: - * Set has time spec to false to perform a send "now". - * Or, set to true, and fill in time spec for a send "at". + * Has time specification? + * - Set false to send immediately. + * - Set true to send at the time specified by time spec. */ bool has_time_spec; + + //! When to send the first sample. time_spec_t time_spec; - /*! - * Burst flags: - * Set start of burst to true for the first packet in the chain. - * Set end of burst to true for the last packet in the chain. - */ + //! Set start of burst to true for the first packet in the chain. bool start_of_burst; + + //! Set end of burst to true for the last packet in the chain. bool end_of_burst; /*! @@ -122,27 +122,27 @@ namespace uhd{ //! The channel number in a mimo configuration size_t channel; - /*! - * Time specification: when the async event occurred. - */ + //! Has time specification? bool has_time_spec; + + //! When the async event occurred. time_spec_t time_spec; /*! - * Event codes: - * - success: a packet was successfully transmitted - * - underflow: an internal send buffer has emptied - * - sequence error: packet loss between host and device - * - time error: packet had time that was late (or too early) - * - underflow in packet: underflow occurred inside a packet - * - sequence error in burst: packet loss within a burst + * The type of event for a receive async message call. */ enum event_code_t { + //! A packet was successfully transmitted. EVENT_CODE_SUCCESS = 0x1, + //! An internal send buffer has emptied. EVENT_CODE_UNDERFLOW = 0x2, + //! Packet loss between host and device. EVENT_CODE_SEQ_ERROR = 0x4, + //! Packet had time that was late (or too early). EVENT_CODE_TIME_ERROR = 0x8, + //! Underflow occurred inside a packet. EVENT_CODE_UNDERFLOW_IN_PACKET = 0x10, + //! Packet loss within a burst. EVENT_CODE_SEQ_ERROR_IN_BURST = 0x20 } event_code; }; diff --git a/host/include/uhd/types/tune_request.hpp b/host/include/uhd/types/tune_request.hpp index f80d2cb15..b05ab5cc7 100644 --- a/host/include/uhd/types/tune_request.hpp +++ b/host/include/uhd/types/tune_request.hpp @@ -48,21 +48,19 @@ namespace uhd{ */ tune_request_t(double target_freq, double lo_off); - /*! - * Policy types for tune arguments: - * - None: do not set this argument, use current setting - * - Auto: automatically determine the argument's value - * - Manual: use the argument's value for the setting - */ + //! Policy options for tunable elements in the RF chain. enum policy_t { + //! Do not set this argument, use current setting. POLICY_NONE = 'N', + //! Automatically determine the argument's value. POLICY_AUTO = 'A', + //! Use the argument's value for the setting. POLICY_MANUAL = 'M' }; /*! * The target frequency of the overall chain in Hz. - * Use when one of the policies is set to automatic. + * Use in conjunction with the automatic policies. */ double target_freq; -- cgit v1.2.3 From 0168bff835371140c0d75cc381e3228f8093fe70 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 25 Oct 2010 19:22:51 -0700 Subject: usrp: rework lo offset logic to use bandwidth, add test case --- host/lib/usrp/tune_helper.cpp | 9 +++-- host/test/tune_helper_test.cpp | 79 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/host/lib/usrp/tune_helper.cpp b/host/lib/usrp/tune_helper.cpp index a6b615926..fa40a8a26 100644 --- a/host/lib/usrp/tune_helper.cpp +++ b/host/lib/usrp/tune_helper.cpp @@ -19,6 +19,7 @@ #include #include #include //unit_t +#include #include #include @@ -43,9 +44,11 @@ static tune_result_t tune_xx_subdev_and_dsp( //------------------------------------------------------------------ double lo_offset = 0.0; if (subdev[SUBDEV_PROP_USE_LO_OFFSET].as()){ - //if the local oscillator will be in the passband, use an offset - //TODO make this nicer, use bandwidth property to clip bounds - lo_offset = 2.0*dsp[DSP_PROP_HOST_RATE].as(); + //If the local oscillator will be in the passband, use an offset. + //But constrain the LO offset by the width of the filter bandwidth. + double rate = dsp[DSP_PROP_HOST_RATE].as(); + double bw = subdev[SUBDEV_PROP_BANDWIDTH].as(); + if (bw > rate) lo_offset = std::min((bw - rate)/2, rate/2); } //------------------------------------------------------------------ diff --git a/host/test/tune_helper_test.cpp b/host/test/tune_helper_test.cpp index 1ef4af330..e0500ae3f 100644 --- a/host/test/tune_helper_test.cpp +++ b/host/test/tune_helper_test.cpp @@ -91,6 +91,44 @@ private: } }; +class dummy_subdev_bw : public wax::obj{ +private: + void get(const wax::obj &key, wax::obj &val){ + switch(key.as()){ + + case SUBDEV_PROP_FREQ: + val = _freq; + return; + + case SUBDEV_PROP_USE_LO_OFFSET: + val = true; + return; + + case SUBDEV_PROP_BANDWIDTH: + val = _bandwidth; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } + } + + void set(const wax::obj &key, const wax::obj &val){ + switch(key.as()){ + case SUBDEV_PROP_FREQ: + _freq = val.as(); + return; + + case SUBDEV_PROP_BANDWIDTH: + _bandwidth = val.as(); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } + } + + double _freq, _bandwidth; +}; + class dummy_dsp : public wax::obj{ public: dummy_dsp(double codec_rate): @@ -106,6 +144,10 @@ private: val = _codec_rate; return; + case DSP_PROP_HOST_RATE: + val = _host_rate; + return; + case DSP_PROP_FREQ_SHIFT: val = _freq_shift; return; @@ -125,11 +167,15 @@ private: _freq_shift = val.as(); return; + case DSP_PROP_HOST_RATE: + _host_rate = val.as(); + return; + default: UHD_THROW_PROP_SET_ERROR(); } } - double _codec_rate, _freq_shift; + double _codec_rate, _freq_shift, _host_rate; }; /*********************************************************************** @@ -141,7 +187,7 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ dummy_subdev subdev(1e6); dummy_dsp dsp(100e6); - std::cout << "Testing tune helper RX automatic LO offset" << std::endl; + std::cout << "Testing tune helper RX automatic IF offset" << std::endl; tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.3451e9); std::cout << tr.to_pp_string() << std::endl; BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance); @@ -155,7 +201,7 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_tx){ dummy_subdev subdev(1e6); dummy_dsp dsp(100e6); - std::cout << "Testing tune helper TX automatic LO offset" << std::endl; + std::cout << "Testing tune helper TX automatic IF offset" << std::endl; tune_result_t tr = tune_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.3451e9); std::cout << tr.to_pp_string() << std::endl; BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance); @@ -178,3 +224,30 @@ BOOST_AUTO_TEST_CASE(test_tune_helper_rx_nyquist){ double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0); BOOST_CHECK_CLOSE(freq_derived, -45e6, tolerance); } + +BOOST_AUTO_TEST_CASE(test_tune_helper_rx_lo_off){ + dummy_subdev_bw subdev; + dummy_dsp dsp(100e6); + tune_result_t tr; + + std::cout << "Testing tune helper RX automatic LO offset B >> fs" << std::endl; + subdev[SUBDEV_PROP_BANDWIDTH] = double(40e6); + dsp[DSP_PROP_HOST_RATE] = double(4e6); + tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9+4e6/2, tolerance); + + std::cout << "Testing tune helper RX automatic LO offset B > fs" << std::endl; + subdev[SUBDEV_PROP_BANDWIDTH] = double(40e6); + dsp[DSP_PROP_HOST_RATE] = double(25e6); + tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9+(40e6-25e6)/2, tolerance); + + std::cout << "Testing tune helper RX automatic LO offset B < fs" << std::endl; + subdev[SUBDEV_PROP_BANDWIDTH] = double(20e6); + dsp[DSP_PROP_HOST_RATE] = double(25e6); + tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9, tolerance); +} -- cgit v1.2.3 From cea3d05095202413be12cd4792ab9f781cbccef7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 26 Oct 2010 14:14:01 -0700 Subject: uhd: replaced print warning with a post warning call and registry renamed print warning calls in the implementation fixed issue with dict::pop so it now works even if the value is not comparable --- host/include/uhd/types/dict.hpp | 23 ++++++++---- host/include/uhd/types/tune_request.hpp | 2 +- host/include/uhd/usrp/mimo_usrp.hpp | 4 +-- host/include/uhd/usrp/simple_usrp.hpp | 2 +- host/include/uhd/utils/warning.hpp | 36 ++++++++++++++++--- host/lib/transport/udp_zero_copy_asio.cpp | 2 +- host/lib/usrp/dboard/db_basic_and_lf.cpp | 4 +-- host/lib/usrp/dboard/db_dbsrx.cpp | 8 ++--- host/lib/usrp/dboard/db_rfx.cpp | 4 +-- host/lib/usrp/dboard/db_tvrx.cpp | 2 +- host/lib/usrp/dboard/db_unknown.cpp | 4 +-- host/lib/usrp/dboard/db_wbx.cpp | 4 +-- host/lib/usrp/dboard_manager.cpp | 4 +-- host/lib/usrp/multi_usrp.cpp | 2 +- host/lib/usrp/usrp1/mboard_impl.cpp | 2 +- host/lib/usrp/usrp1/usrp1_impl.cpp | 2 +- host/lib/usrp/wrapper_utils.hpp | 4 +-- host/lib/utils/thread_priority.cpp | 2 +- host/lib/utils/warning.cpp | 59 ++++++++++++++++++++++++++++--- host/test/warning_test.cpp | 4 +-- 20 files changed, 131 insertions(+), 43 deletions(-) diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp index de96ea768..3d0acf888 100644 --- a/host/include/uhd/types/dict.hpp +++ b/host/include/uhd/types/dict.hpp @@ -120,10 +120,7 @@ namespace uhd{ BOOST_FOREACH(const pair_t &p, _map){ if (p.first == key) return p.second; } - throw std::invalid_argument(str(boost::format( - "key \"%s\" not found in dict(%s, %s)" - ) % boost::lexical_cast(key) - % typeid(Key).name() % typeid(Val).name())); + throw key_not_found_in_dict(key); } /*! @@ -147,12 +144,24 @@ namespace uhd{ * \throw an exception when not found */ Val pop(const Key &key){ - Val val = (*this)[key]; - _map.remove(pair_t(key, val)); - return val; + typename std::list::iterator it; + for (it = _map.begin(); it != _map.end(); it++){ + if (it->first != key) continue; + Val val = it->second; + _map.erase(it); + return val; + } + throw key_not_found_in_dict(key); } private: + std::exception key_not_found_in_dict(const Key &key) const{ + return std::out_of_range(str(boost::format( + "key \"%s\" not found in dict(%s, %s)" + ) % boost::lexical_cast(key) + % typeid(Key).name() % typeid(Val).name())); + } + std::list _map; //private container }; diff --git a/host/include/uhd/types/tune_request.hpp b/host/include/uhd/types/tune_request.hpp index b05ab5cc7..942b93251 100644 --- a/host/include/uhd/types/tune_request.hpp +++ b/host/include/uhd/types/tune_request.hpp @@ -60,7 +60,7 @@ namespace uhd{ /*! * The target frequency of the overall chain in Hz. - * Use in conjunction with the automatic policies. + * Set this even if all policies are set to manual. */ double target_freq; diff --git a/host/include/uhd/usrp/mimo_usrp.hpp b/host/include/uhd/usrp/mimo_usrp.hpp index b5acf84e1..a2092f04f 100644 --- a/host/include/uhd/usrp/mimo_usrp.hpp +++ b/host/include/uhd/usrp/mimo_usrp.hpp @@ -298,7 +298,7 @@ public: time_spec_t time_0 = _mboard(0)[MBOARD_PROP_TIME_NOW].as(); time_spec_t time_i = _mboard(chan)[MBOARD_PROP_TIME_NOW].as(); if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)){ //10 ms: greater than RTT but not too big - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "Detected time deviation between board %d and board 0.\n" "Board 0 time is %f seconds.\n" "Board %d time is %f seconds.\n" @@ -512,7 +512,7 @@ namespace uhd{ namespace usrp{ * The Make Function **********************************************************************/ inline mimo_usrp::sptr mimo_usrp::make(const device_addr_t &dev_addr){ - uhd::print_warning( + uhd::warning::post( "The mimo USRP interface has been deprecated.\n" "Please switch to the multi USRP interface.\n" "#include \n" diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp index 59fd9bb09..77416dbbd 100644 --- a/host/include/uhd/usrp/simple_usrp.hpp +++ b/host/include/uhd/usrp/simple_usrp.hpp @@ -374,7 +374,7 @@ namespace uhd{ namespace usrp{ * The Make Function **********************************************************************/ inline simple_usrp::sptr simple_usrp::make(const device_addr_t &dev_addr){ - uhd::print_warning( + uhd::warning::post( "The simple USRP interface has been deprecated.\n" "Please switch to the single USRP interface.\n" "#include \n" diff --git a/host/include/uhd/utils/warning.hpp b/host/include/uhd/utils/warning.hpp index 91d8400ab..a1e3f0d1e 100644 --- a/host/include/uhd/utils/warning.hpp +++ b/host/include/uhd/utils/warning.hpp @@ -19,16 +19,44 @@ #define INCLUDED_UHD_UTILS_WARNING_HPP #include +#include +#include #include -namespace uhd{ +namespace uhd{ namespace warning{ + + //! Callback function type for a message handler + typedef boost::function handler_t; /*! - * Print a formatted warning string to stderr. + * Post a warning message to all registered handlers. * \param msg the multiline warning message */ - UHD_API void print_warning(const std::string &msg); + UHD_API void post(const std::string &msg); + + /*! + * Register a new handler with this name. + * If the name was already registered for this name, + * the old registered handler will be replaced. + * \param name a unique name for this handler + * \param handler the callback handler function + */ + UHD_API void register_handler(const std::string &name, const handler_t &handler); + + /*! + * Unregister a handler for this name. + * \param name a unique name for a registered handler + * \return the handler that was registered + * \throw error when the name was not found in the registry + */ + UHD_API handler_t unregister_handler(const std::string &name); + + /*! + * Get a list of registered handler names. + * \return a vector of unique string names + */ + UHD_API const std::vector registry_names(void); -} //namespace uhd +}} //namespace uhd::warning #endif /* INCLUDED_UHD_UTILS_WARNING_HPP */ diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp index d84aeefdd..ed29864e9 100644 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ b/host/lib/transport/udp_zero_copy_asio.cpp @@ -336,7 +336,7 @@ template static void resize_buff_helper( else std::cout << boost::format( "Current %s sock buff size: %d bytes" ) % name % actual_size << std::endl; - if (actual_size < target_size) uhd::print_warning(str(boost::format( + if (actual_size < target_size) uhd::warning::post(str(boost::format( "The %s buffer is smaller than the requested size.\n" "The minimum recommended buffer size is %d bytes.\n" "See the transport application notes on buffer resizing.\n%s" diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 5a87f4ecf..4c49b3bff 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -191,7 +191,7 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("%s: No tunable bandwidth, fixed filtered to %0.2fMHz") % get_rx_id().to_pp_string() % _max_freq ) @@ -302,7 +302,7 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("%s: No tunable bandwidth, fixed filtered to %0.2fMHz") % get_tx_id().to_pp_string() % _max_freq ) diff --git a/host/lib/usrp/dboard/db_dbsrx.cpp b/host/lib/usrp/dboard/db_dbsrx.cpp index 10e7f292b..85251bdf9 100644 --- a/host/lib/usrp/dboard/db_dbsrx.cpp +++ b/host/lib/usrp/dboard/db_dbsrx.cpp @@ -175,7 +175,7 @@ UHD_STATIC_BLOCK(reg_dbsrx_dboard){ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ //warn user about incorrect DBID on USRP1, requires R193 populated if (this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x000D) - uhd::print_warning( + uhd::warning::post( str(boost::format( "DBSRX: incorrect dbid\n" "Expected dbid 0x0002 and R193\n" @@ -186,7 +186,7 @@ dbsrx::dbsrx(ctor_args_t args) : rx_dboard_base(args){ //warn user about incorrect DBID on non-USRP1, requires R194 populated if (not this->get_iface()->get_special_props().soft_clock_divider and this->get_rx_id() == 0x0002) - uhd::print_warning( + uhd::warning::post( str(boost::format( "DBSRX: incorrect dbid\n" "Expected dbid 0x000D and R194\n" @@ -342,7 +342,7 @@ void dbsrx::set_lo_freq(double target_freq){ //vtune is too low, try lower frequency vco if (_max2118_read_regs.adc == 0){ if (_max2118_write_regs.osc_band == 0){ - uhd::print_warning( + uhd::warning::post( str(boost::format( "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" ) % int(_max2118_write_regs.osc_band)) @@ -356,7 +356,7 @@ void dbsrx::set_lo_freq(double target_freq){ //vtune is too high, try higher frequency vco if (_max2118_read_regs.adc == 7){ if (_max2118_write_regs.osc_band == 7){ - uhd::print_warning( + uhd::warning::post( str(boost::format( "DBSRX: Tuning exceeded vco range, _max2118_write_regs.osc_band == %d\n" ) % int(_max2118_write_regs.osc_band)) diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 0eeb0bfdf..12e458d8c 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -487,7 +487,7 @@ void rfx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("RFX: No tunable bandwidth, fixed filtered to 40MHz")) ); return; @@ -584,7 +584,7 @@ void rfx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("RFX: No tunable bandwidth, fixed filtered to 40MHz")) ); return; diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index c7aecf195..1f3c76556 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -484,7 +484,7 @@ void tvrx::rx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("TVRX: No tunable bandwidth, fixed filtered to 6MHz")) ); return; diff --git a/host/lib/usrp/dboard/db_unknown.cpp b/host/lib/usrp/dboard/db_unknown.cpp index 11293a1ba..a342471c4 100644 --- a/host/lib/usrp/dboard/db_unknown.cpp +++ b/host/lib/usrp/dboard/db_unknown.cpp @@ -164,7 +164,7 @@ void unknown_rx::rx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("Unknown Daughterboard: No tunable bandwidth, fixed filtered to 0.0MHz")) ); return; @@ -270,7 +270,7 @@ void unknown_tx::tx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("Unknown Daughterboard: No tunable bandwidth, fixed filtered to 0.0MHz")) ); return; diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index b07f179a3..647f1b975 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -556,7 +556,7 @@ void wbx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("WBX: No tunable bandwidth, fixed filtered to 40MHz")) ); return; @@ -657,7 +657,7 @@ void wbx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ return; //always enabled case SUBDEV_PROP_BANDWIDTH: - uhd::print_warning( + uhd::warning::post( str(boost::format("WBX: No tunable bandwidth, fixed filtered to 40MHz")) ); return; diff --git a/host/lib/usrp/dboard_manager.cpp b/host/lib/usrp/dboard_manager.cpp index d73a698ae..5a98bb8eb 100644 --- a/host/lib/usrp/dboard_manager.cpp +++ b/host/lib/usrp/dboard_manager.cpp @@ -189,7 +189,7 @@ static args_t get_dboard_args( //verify that there is a registered constructor for this id if (not get_id_to_args_map().has_key(dboard_id)){ - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "Unknown dboard ID: %s.\n" ) % dboard_id.to_pp_string())); return get_dboard_args(unit, dboard_id, true); @@ -217,7 +217,7 @@ dboard_manager_impl::dboard_manager_impl( //warn for invalid dboard id xcvr combinations if (rx_dboard_is_xcvr != this_dboard_is_xcvr or tx_dboard_is_xcvr != this_dboard_is_xcvr){ - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "Unknown transceiver board ID combination...\n" "RX dboard ID: %s\n" "TX dboard ID: %s\n" diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 8b82502ba..024a6152d 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -145,7 +145,7 @@ public: time_spec_t time_0 = _mboard(0)[MBOARD_PROP_TIME_NOW].as(); time_spec_t time_i = _mboard(m)[MBOARD_PROP_TIME_NOW].as(); if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)){ //10 ms: greater than RTT but not too big - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "Detected time deviation between board %d and board 0.\n" "Board 0 time is %f seconds.\n" "Board %d time is %f seconds.\n" diff --git a/host/lib/usrp/usrp1/mboard_impl.cpp b/host/lib/usrp/usrp1/mboard_impl.cpp index fe3774eb4..669b20efa 100644 --- a/host/lib/usrp/usrp1/mboard_impl.cpp +++ b/host/lib/usrp/usrp1/mboard_impl.cpp @@ -98,7 +98,7 @@ static boost::uint32_t calc_rx_mux( // for all quadrature sources: Z = 0 // for mixed sources: warning + Z = 0 int Z = (num_quads > 0)? 0 : 1; - if (num_quads != 0 and num_reals != 0) uhd::print_warning( + if (num_quads != 0 and num_reals != 0) uhd::warning::post( "Mixing real and quadrature rx subdevices is not supported.\n" "The Q input to the real source(s) will be non-zero.\n" ); diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp index 276ca86f6..314384e72 100644 --- a/host/lib/usrp/usrp1/usrp1_impl.cpp +++ b/host/lib/usrp/usrp1/usrp1_impl.cpp @@ -64,7 +64,7 @@ static device_addrs_t usrp1_find(const device_addr_t &hint) ); } catch(...){ - uhd::print_warning( + uhd::warning::post( "Could not locate USRP1 firmware.\n" "Please install the images package.\n" ); diff --git a/host/lib/usrp/wrapper_utils.hpp b/host/lib/usrp/wrapper_utils.hpp index aee230fc0..6f9fdbfca 100644 --- a/host/lib/usrp/wrapper_utils.hpp +++ b/host/lib/usrp/wrapper_utils.hpp @@ -40,7 +40,7 @@ static inline void do_samp_rate_warning_message( ){ static const double max_allowed_error = 1.0; //Sps if (std::abs(target_rate - actual_rate) > max_allowed_error){ - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "The hardware does not support the requested %s sample rate:\n" "Target sample rate: %f MSps\n" "Actual sample rate: %f MSps\n" @@ -55,7 +55,7 @@ static inline void do_tune_freq_warning_message( ){ static const double max_allowed_error = 1.0; //Hz if (std::abs(target_freq - actual_freq) > max_allowed_error){ - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "The hardware does not support the requested %s frequency:\n" "Target frequency: %f MHz\n" "Actual frequency: %f MHz\n" diff --git a/host/lib/utils/thread_priority.cpp b/host/lib/utils/thread_priority.cpp index f09d1b1d6..40b74f655 100644 --- a/host/lib/utils/thread_priority.cpp +++ b/host/lib/utils/thread_priority.cpp @@ -26,7 +26,7 @@ bool uhd::set_thread_priority_safe(float priority, bool realtime){ set_thread_priority(priority, realtime); return true; }catch(const std::exception &e){ - uhd::print_warning(str(boost::format( + uhd::warning::post(str(boost::format( "%s\n" "Failed to set thread priority %d (%s):\n" "Performance may be negatively affected.\n" diff --git a/host/lib/utils/warning.cpp b/host/lib/utils/warning.cpp index 8a7d35a23..05be7ae4d 100644 --- a/host/lib/utils/warning.cpp +++ b/host/lib/utils/warning.cpp @@ -17,16 +17,67 @@ #include #include +#include +#include #include +#include +#include #include #include using namespace uhd; -void uhd::print_warning(const std::string &msg){ - //print the warning message - std::cerr << std::endl << "Warning:" << std::endl; +/*********************************************************************** + * Registry implementation + **********************************************************************/ +//create the registry for the handlers +typedef uhd::dict registry_t; +UHD_SINGLETON_FCN(registry_t, get_registry) + +//the default warning handler +static void stderr_warning(const std::string &msg){ + std::cerr << msg; +} + +//register a default handler +UHD_STATIC_BLOCK(warning_register_default){ + warning::register_handler("default", &stderr_warning); +} + +/*********************************************************************** + * Post + format + **********************************************************************/ +void warning::post(const std::string &msg){ + std::stringstream ss; + + //format the warning message + ss << std::endl << "Warning:" << std::endl; BOOST_FOREACH(const std::string &line, std::split_string(msg, "\n")){ - std::cerr << " " << line << std::endl; + ss << " " << line << std::endl; + } + + //post the formatted message + BOOST_FOREACH(const std::string &name, get_registry().keys()){ + get_registry()[name](ss.str()); } } + +/*********************************************************************** + * Registry accessor functions + **********************************************************************/ +void warning::register_handler( + const std::string &name, const handler_t &handler +){ + get_registry()[name] = handler; +} + +warning::handler_t warning::unregister_handler(const std::string &name){ + if (not get_registry().has_key(name)) throw std::runtime_error( + "The warning registry does not have a handler registered to " + name + ); + return get_registry().pop(name); +} + +const std::vector warning::registry_names(void){ + return get_registry().keys(); +} diff --git a/host/test/warning_test.cpp b/host/test/warning_test.cpp index 6202c4270..db19955de 100644 --- a/host/test/warning_test.cpp +++ b/host/test/warning_test.cpp @@ -19,9 +19,9 @@ #include #include -BOOST_AUTO_TEST_CASE(test_print_warning){ +BOOST_AUTO_TEST_CASE(test_warning_post){ std::cerr << "---begin print test ---" << std::endl; - uhd::print_warning( + uhd::warning::post( "This is a test print for a warning message.\n" "And this is the second line of the test print.\n" ); -- cgit v1.2.3 From a7840ebb3f7d7f807d05059e2809eb45cff04899 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 26 Oct 2010 18:11:40 -0700 Subject: uhd: moved templated dict implementation into ipp file --- host/include/uhd/types/CMakeLists.txt | 1 + host/include/uhd/types/dict.hpp | 87 ++++-------------------- host/include/uhd/types/dict.ipp | 120 ++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 75 deletions(-) create mode 100644 host/include/uhd/types/dict.ipp diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt index 661dd2d39..a96976b5e 100644 --- a/host/include/uhd/types/CMakeLists.txt +++ b/host/include/uhd/types/CMakeLists.txt @@ -19,6 +19,7 @@ INSTALL(FILES clock_config.hpp device_addr.hpp + dict.ipp dict.hpp io_type.hpp mac_addr.hpp diff --git a/host/include/uhd/types/dict.hpp b/host/include/uhd/types/dict.hpp index 3d0acf888..b14fc5425 100644 --- a/host/include/uhd/types/dict.hpp +++ b/host/include/uhd/types/dict.hpp @@ -19,11 +19,6 @@ #define INCLUDED_UHD_TYPES_DICT_HPP #include -#include -#include -#include -#include -#include #include #include @@ -34,14 +29,10 @@ namespace uhd{ */ template class dict{ public: - typedef std::pair pair_t; - /*! * Create a new empty dictionary. */ - dict(void){ - /* NOP */ - } + dict(void); /*! * Input iterator constructor: @@ -50,64 +41,34 @@ namespace uhd{ * \param last the end iterator */ template - dict(InputIterator first, InputIterator last){ - for(InputIterator it = first; it != last; it++){ - _map.push_back(*it); - } - } - - /*! - * Destroy this dict. - */ - ~dict(void){ - /* NOP */ - } + dict(InputIterator first, InputIterator last); /*! * Get the number of elements in this dict. * \return the number of elements */ - std::size_t size(void) const{ - return _map.size(); - } + std::size_t size(void) const; /*! * Get a list of the keys in this dict. * Key order depends on insertion precedence. * \return vector of keys */ - const std::vector keys(void) const{ - std::vector keys; - BOOST_FOREACH(const pair_t &p, _map){ - keys.push_back(p.first); - } - return keys; - } + const std::vector keys(void) const; /*! * Get a list of the values in this dict. * Value order depends on insertion precedence. * \return vector of values */ - const std::vector vals(void) const{ - std::vector vals; - BOOST_FOREACH(const pair_t &p, _map){ - vals.push_back(p.second); - } - return vals; - } + const std::vector vals(void) const; /*! * Does the dictionary contain this key? * \param key the key to look for * \return true if found */ - bool has_key(const Key &key) const{ - BOOST_FOREACH(const pair_t &p, _map){ - if (p.first == key) return true; - } - return false; - } + bool has_key(const Key &key) const; /*! * Get a value for the given key if it exists. @@ -116,12 +77,7 @@ namespace uhd{ * \return the value at the key * \throw an exception when not found */ - const Val &operator[](const Key &key) const{ - BOOST_FOREACH(const pair_t &p, _map){ - if (p.first == key) return p.second; - } - throw key_not_found_in_dict(key); - } + const Val &operator[](const Key &key) const; /*! * Set a value for the given key, however, in reality @@ -129,13 +85,7 @@ namespace uhd{ * \param key the key to set to * \return a reference to the value */ - Val &operator[](const Key &key){ - BOOST_FOREACH(pair_t &p, _map){ - if (p.first == key) return p.second; - } - _map.push_back(std::make_pair(key, Val())); - return _map.back().second; - } + Val &operator[](const Key &key); /*! * Pop an item out of the dictionary. @@ -143,28 +93,15 @@ namespace uhd{ * \return the value of the item * \throw an exception when not found */ - Val pop(const Key &key){ - typename std::list::iterator it; - for (it = _map.begin(); it != _map.end(); it++){ - if (it->first != key) continue; - Val val = it->second; - _map.erase(it); - return val; - } - throw key_not_found_in_dict(key); - } + Val pop(const Key &key); private: - std::exception key_not_found_in_dict(const Key &key) const{ - return std::out_of_range(str(boost::format( - "key \"%s\" not found in dict(%s, %s)" - ) % boost::lexical_cast(key) - % typeid(Key).name() % typeid(Val).name())); - } - + typedef std::pair pair_t; std::list _map; //private container }; } //namespace uhd +#include + #endif /* INCLUDED_UHD_TYPES_DICT_HPP */ diff --git a/host/include/uhd/types/dict.ipp b/host/include/uhd/types/dict.ipp new file mode 100644 index 000000000..85071e6fd --- /dev/null +++ b/host/include/uhd/types/dict.ipp @@ -0,0 +1,120 @@ +// +// 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 . +// + +#ifndef INCLUDED_UHD_TYPES_DICT_IPP +#define INCLUDED_UHD_TYPES_DICT_IPP + +#include +#include +#include +#include +#include + +namespace uhd{ + + namespace /*anon*/{ + template + struct UHD_API key_not_found: std::out_of_range{ + key_not_found(const Key &key): std::out_of_range( + str(boost::format( + "key \"%s\" not found in dict(%s, %s)" + ) % boost::lexical_cast(key) + % typeid(Key).name() % typeid(Val).name() + ) + ){ + /* NOP */ + } + }; + } // namespace /*anon*/ + + template + dict::dict(void){ + /* NOP */ + } + + template + template + dict::dict(InputIterator first, InputIterator last){ + for(InputIterator it = first; it != last; it++){ + _map.push_back(*it); + } + } + + template + std::size_t dict::size(void) const{ + return _map.size(); + } + + template + const std::vector dict::keys(void) const{ + std::vector keys; + BOOST_FOREACH(const pair_t &p, _map){ + keys.push_back(p.first); + } + return keys; + } + + template + const std::vector dict::vals(void) const{ + std::vector vals; + BOOST_FOREACH(const pair_t &p, _map){ + vals.push_back(p.second); + } + return vals; + } + + template + bool dict::has_key(const Key &key) const{ + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return true; + } + return false; + } + + template + const Val &dict::operator[](const Key &key) const{ + BOOST_FOREACH(const pair_t &p, _map){ + if (p.first == key) return p.second; + } + throw key_not_found(key); + } + + template + Val &dict::operator[](const Key &key){ + BOOST_FOREACH(pair_t &p, _map){ + if (p.first == key) return p.second; + } + _map.push_back(std::make_pair(key, Val())); + return _map.back().second; + } + + template + Val dict::pop(const Key &key){ + typename std::list::iterator it; + for (it = _map.begin(); it != _map.end(); it++){ + if (it->first == key){ + Val val = it->second; + _map.erase(it); + return val; + } + } + throw key_not_found(key); + } + +} //namespace uhd + +#endif /* INCLUDED_UHD_TYPES_DICT_IPP */ -- cgit v1.2.3 From 211e190619652be145fdcd79cd54eda0e84d3313 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 10:45:15 -0700 Subject: usrp: added a time sync check for multi usrp --- host/include/uhd/usrp/multi_usrp.hpp | 8 ++++++++ host/lib/usrp/multi_usrp.cpp | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/host/include/uhd/usrp/multi_usrp.hpp b/host/include/uhd/usrp/multi_usrp.hpp index 5380d177d..98ba07fc0 100644 --- a/host/include/uhd/usrp/multi_usrp.hpp +++ b/host/include/uhd/usrp/multi_usrp.hpp @@ -144,6 +144,14 @@ public: */ virtual void set_time_unknown_pps(const time_spec_t &time_spec) = 0; + /*! + * Are the times across all motherboards in this configuration synchronized? + * Checks that all time registers are approximately close but not exact, + * given that the RTT may varying for a control packet transaction. + * \return true when all motherboards time registers are in sync + */ + virtual bool get_time_synchronized(void) = 0; + /*! * Issue a stream command to the usrp device. * This tells the usrp to send samples into the host. diff --git a/host/lib/usrp/multi_usrp.cpp b/host/lib/usrp/multi_usrp.cpp index 024a6152d..876f1a3fc 100644 --- a/host/lib/usrp/multi_usrp.cpp +++ b/host/lib/usrp/multi_usrp.cpp @@ -154,6 +154,15 @@ public: } } + bool get_time_synchronized(void){ + for (size_t m = 1; m < get_num_mboards(); m++){ + time_spec_t time_0 = _mboard(0)[MBOARD_PROP_TIME_NOW].as(); + time_spec_t time_i = _mboard(m)[MBOARD_PROP_TIME_NOW].as(); + if (time_i < time_0 or (time_i - time_0) > time_spec_t(0.01)) return false; + } + return true; + } + void issue_stream_cmd(const stream_cmd_t &stream_cmd){ for (size_t m = 0; m < get_num_mboards(); m++){ _mboard(m)[MBOARD_PROP_STREAM_CMD] = stream_cmd; -- cgit v1.2.3 From 630c007bbbabce90ffe3578d47ad7acc187bdc30 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 11:15:37 -0700 Subject: usrp: added to subdev spec comments/docs --- host/include/uhd/usrp/subdev_spec.hpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/host/include/uhd/usrp/subdev_spec.hpp b/host/include/uhd/usrp/subdev_spec.hpp index 5de3bb3b8..b189724c9 100644 --- a/host/include/uhd/usrp/subdev_spec.hpp +++ b/host/include/uhd/usrp/subdev_spec.hpp @@ -26,10 +26,10 @@ namespace uhd{ namespace usrp{ /*! - * A subdevice specification (daughterboard, subdevice) name pairing. + * A subdevice specification (daughterboard slot, subdevice) name pairing. */ struct UHD_API subdev_spec_pair_t : boost::equality_comparable{ - //! The daughterboard name + //! The daughterboard slot name std::string db_name; //! The subdevice name @@ -50,7 +50,7 @@ namespace uhd{ namespace usrp{ UHD_API bool operator==(const subdev_spec_pair_t &, const subdev_spec_pair_t &); /*! - * A list of (daughterboard name, subdevice name) pairs: + * A list of (daughterboard slot name, subdevice name) pairs: * * A subdevice specification represents a list of subdevices on a motherboard. * The subdevices specified may span across multiple daughterboards; @@ -62,6 +62,11 @@ namespace uhd{ namespace usrp{ * The markup-string is a whitespace separated list of dboard:subdev pairs. * The first pair represents the subdevice for channel zero, * the second pair represents the subdevice for channel one, and so on. + * + * Special handling for empty conditions: + * - An empty subdevice specification means: select the first subdevice found in the configuration + * - An empty daughterboard name means: select the only daughterboard slot or error if multiple exist + * - An empty subdevice name means: select the only subdevice on that board or error if multiple exist */ class UHD_API subdev_spec_t : public std::vector{ public: -- cgit v1.2.3 From f820cce9be9bcea9723cf7b4e85a4ded2f1d2c62 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 18:55:35 -0700 Subject: uhd: added rx to file example, simplified cmake file for examples --- host/examples/CMakeLists.txt | 44 ++++++------- host/examples/rx_to_file.cpp | 144 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 26 deletions(-) create mode 100644 host/examples/rx_to_file.cpp diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index a8873f8d3..e355ce241 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -16,34 +16,26 @@ # ######################################################################## -ADD_EXECUTABLE(benchmark_rx_rate benchmark_rx_rate.cpp) -TARGET_LINK_LIBRARIES(benchmark_rx_rate uhd) - -ADD_EXECUTABLE(rx_timed_samples rx_timed_samples.cpp) -TARGET_LINK_LIBRARIES(rx_timed_samples uhd) - -ADD_EXECUTABLE(test_async_messages test_async_messages.cpp) -TARGET_LINK_LIBRARIES(test_async_messages uhd) - -ADD_EXECUTABLE(test_pps_input test_pps_input.cpp) -TARGET_LINK_LIBRARIES(test_pps_input uhd) - -ADD_EXECUTABLE(tx_timed_samples tx_timed_samples.cpp) -TARGET_LINK_LIBRARIES(tx_timed_samples uhd) - -ADD_EXECUTABLE(tx_waveforms tx_waveforms.cpp) -TARGET_LINK_LIBRARIES(tx_waveforms uhd) - -INSTALL(TARGETS - benchmark_rx_rate - rx_timed_samples - test_async_messages - test_pps_input - tx_timed_samples - tx_waveforms - RUNTIME DESTINATION ${PKG_DATA_DIR}/examples +# example applications +######################################################################## +SET(example_sources + benchmark_rx_rate.cpp + rx_timed_samples.cpp + rx_to_file.cpp + test_async_messages.cpp + test_pps_input.cpp + tx_timed_samples.cpp + tx_waveforms.cpp ) +#for each source: build an executable and install +FOREACH(example_source ${example_sources}) + GET_FILENAME_COMPONENT(example_name ${example_source} NAME_WE) + ADD_EXECUTABLE(${example_name} ${example_source}) + TARGET_LINK_LIBRARIES(${example_name} uhd) + INSTALL(TARGETS ${example_name} RUNTIME DESTINATION ${PKG_DATA_DIR}/examples) +ENDFOREACH(example_source) + ######################################################################## # ASCII Art DFT - requires curses, so this part is optional ######################################################################## diff --git a/host/examples/rx_to_file.cpp b/host/examples/rx_to_file.cpp new file mode 100644 index 000000000..25727a7d3 --- /dev/null +++ b/host/examples/rx_to_file.cpp @@ -0,0 +1,144 @@ +// +// 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 . +// + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args, file; + time_t seconds_in_future; + size_t total_num_samps; + double rx_rate, freq; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("file", po::value(&file)->default_value("out.16sc.dat"), "name of the file to write binary samples to") + ("secs", po::value(&seconds_in_future)->default_value(1), "number of seconds in the future to receive") + ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") + ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD RX to File %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set properties on the device + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; + sdev->set_rx_rate(rx_rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + sdev->set_rx_freq(freq); + sdev->set_time_now(uhd::time_spec_t(0.0)); + + uhd::gain_range_t rx_gain = sdev->get_rx_gain_range(); + std::cout << "Setting RX Gain to: " << rx_gain.max << std::endl; + sdev->set_rx_gain(rx_gain.max); + + sleep(1); + std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; + + //setup streaming + std::cout << std::endl; + std::cout << boost::format( + "Begin streaming %u samples, %d seconds in the future..." + ) % total_num_samps % seconds_in_future << std::endl; + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = total_num_samps; + stream_cmd.stream_now = false; + stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); + sdev->issue_stream_cmd(stream_cmd); + + //loop until total number of samples reached + size_t num_acc_samps = 0; //number of accumulated samples + uhd::rx_metadata_t md; + std::vector > buff(dev->get_max_recv_samps_per_packet()); + std::ofstream outfile(file.c_str(), std::ofstream::binary); + + while(num_acc_samps < total_num_samps){ + size_t num_rx_samps = dev->recv( + &buff.front(), buff.size(), md, + uhd::io_type_t::COMPLEX_INT16, + uhd::device::RECV_MODE_ONE_PACKET + ); + + //handle the error codes + switch(md.error_code){ + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) continue; + std::cout << boost::format( + "Got timeout before all samples received, possible packet loss, exiting loop..." + ) << std::endl; + goto done_loop; + + default: + std::cout << boost::format( + "Got error code 0x%x, exiting loop..." + ) % md.error_code << std::endl; + goto done_loop; + } + + //write complex short integer samples to the binary file + outfile.write((const char*)&buff[0], num_rx_samps * sizeof(std::complex)); + + if(verbose) std::cout << boost::format( + "Got packet: %u samples, %u full secs, %f frac secs" + ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + + num_acc_samps += num_rx_samps; + } done_loop: + + outfile.close(); + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return 0; +} -- cgit v1.2.3 From dc9f22c9a7989e4485d6f03b0ccf6ea19e6ae42d Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 19:18:26 -0700 Subject: uhd: added rx samples to udp example, cleaned up other examples, added gain options --- host/examples/CMakeLists.txt | 3 +- host/examples/rx_samples_to_file.cpp | 142 ++++++++++++++++++++++++++++++++++ host/examples/rx_samples_to_udp.cpp | 142 ++++++++++++++++++++++++++++++++++ host/examples/rx_timed_samples.cpp | 19 +++-- host/examples/rx_to_file.cpp | 144 ----------------------------------- host/examples/tx_timed_samples.cpp | 19 +++-- 6 files changed, 310 insertions(+), 159 deletions(-) create mode 100644 host/examples/rx_samples_to_file.cpp create mode 100644 host/examples/rx_samples_to_udp.cpp delete mode 100644 host/examples/rx_to_file.cpp diff --git a/host/examples/CMakeLists.txt b/host/examples/CMakeLists.txt index e355ce241..ce2ca9640 100644 --- a/host/examples/CMakeLists.txt +++ b/host/examples/CMakeLists.txt @@ -20,8 +20,9 @@ ######################################################################## SET(example_sources benchmark_rx_rate.cpp + rx_samples_to_file.cpp + rx_samples_to_udp.cpp rx_timed_samples.cpp - rx_to_file.cpp test_async_messages.cpp test_pps_input.cpp tx_timed_samples.cpp diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp new file mode 100644 index 000000000..6671644fa --- /dev/null +++ b/host/examples/rx_samples_to_file.cpp @@ -0,0 +1,142 @@ +// +// 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 . +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args, file; + size_t total_num_samps; + double rate, freq; + float gain; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("file", po::value(&file)->default_value("out.16sc.dat"), "name of the file to write binary samples to") + ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") + ("rate", po::value(&rate)->default_value(100e6/16), "rate of incoming samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("gain", po::value(&gain)->default_value(0), "gain for the RF chain") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD RX to File %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set the rx sample rate + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + sdev->set_rx_rate(rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << std::endl; + + //set the rx center frequency + std::cout << boost::format("Setting RX Freq: %f Mhz...") % (freq/1e6) << std::endl; + sdev->set_rx_freq(freq); + std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; + + //set the rx rf gain + std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; + sdev->set_rx_gain(gain); + std::cout << boost::format("Actual RX Gain: %f dB...") % sdev->get_rx_gain() << std::endl << std::endl; + + boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time + std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; + + //setup streaming + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = total_num_samps; + stream_cmd.stream_now = true; + sdev->issue_stream_cmd(stream_cmd); + + //loop until total number of samples reached + size_t num_acc_samps = 0; //number of accumulated samples + uhd::rx_metadata_t md; + std::vector > buff(dev->get_max_recv_samps_per_packet()); + std::ofstream outfile(file.c_str(), std::ofstream::binary); + + while(num_acc_samps < total_num_samps){ + size_t num_rx_samps = dev->recv( + &buff.front(), buff.size(), md, + uhd::io_type_t::COMPLEX_INT16, + uhd::device::RECV_MODE_ONE_PACKET + ); + + //handle the error codes + switch(md.error_code){ + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) continue; + std::cout << boost::format( + "Got timeout before all samples received, possible packet loss, exiting loop..." + ) << std::endl; + goto done_loop; + + default: + std::cout << boost::format( + "Got error code 0x%x, exiting loop..." + ) % md.error_code << std::endl; + goto done_loop; + } + + //write complex short integer samples to the binary file + outfile.write((const char*)&buff[0], num_rx_samps * sizeof(std::complex)); + + if(verbose) std::cout << boost::format( + "Got packet: %u samples, %u full secs, %f frac secs" + ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + + num_acc_samps += num_rx_samps; + } done_loop: + + outfile.close(); + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return 0; +} diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp new file mode 100644 index 000000000..c81b43ee3 --- /dev/null +++ b/host/examples/rx_samples_to_udp.cpp @@ -0,0 +1,142 @@ +// +// 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 . +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + uhd::set_thread_priority_safe(); + + //variables to be set by po + std::string args; + size_t total_num_samps; + double rate, freq; + float gain; + std::string addr, port; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("args", po::value(&args)->default_value(""), "single uhd device address args") + ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") + ("rate", po::value(&rate)->default_value(100e6/16), "rate of incoming samples") + ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") + ("gain", po::value(&gain)->default_value(0), "gain for the RF chain") + ("port", po::value(&port)->default_value("7124"), "server udp port") + ("addr", po::value(&addr)->default_value("192.168.1.10"), "resolvable server address") + ("dilv", "specify to disable inner-loop verbose") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout << boost::format("UHD RX to UDP %s") % desc << std::endl; + return ~0; + } + + bool verbose = vm.count("dilv") == 0; + + //create a usrp device + std::cout << std::endl; + std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; + uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); + uhd::device::sptr dev = sdev->get_device(); + std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; + + //set the rx sample rate + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + sdev->set_rx_rate(rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << std::endl; + + //set the rx center frequency + std::cout << boost::format("Setting RX Freq: %f Mhz...") % (freq/1e6) << std::endl; + sdev->set_rx_freq(freq); + std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; + + //set the rx rf gain + std::cout << boost::format("Setting RX Gain: %f dB...") % gain << std::endl; + sdev->set_rx_gain(gain); + std::cout << boost::format("Actual RX Gain: %f dB...") % sdev->get_rx_gain() << std::endl << std::endl; + + boost::this_thread::sleep(boost::posix_time::seconds(1)); //allow for some setup time + std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; + + //setup streaming + uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); + stream_cmd.num_samps = total_num_samps; + stream_cmd.stream_now = true; + sdev->issue_stream_cmd(stream_cmd); + + //loop until total number of samples reached + size_t num_acc_samps = 0; //number of accumulated samples + uhd::rx_metadata_t md; + std::vector > buff(dev->get_max_recv_samps_per_packet()); + uhd::transport::udp_simple::sptr udp_xport = uhd::transport::udp_simple::make_connected(addr, port); + + while(num_acc_samps < total_num_samps){ + size_t num_rx_samps = dev->recv( + &buff.front(), buff.size(), md, + uhd::io_type_t::COMPLEX_FLOAT32, + uhd::device::RECV_MODE_ONE_PACKET + ); + + //handle the error codes + switch(md.error_code){ + case uhd::rx_metadata_t::ERROR_CODE_NONE: + break; + + case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: + if (num_acc_samps == 0) continue; + std::cout << boost::format( + "Got timeout before all samples received, possible packet loss, exiting loop..." + ) << std::endl; + goto done_loop; + + default: + std::cout << boost::format( + "Got error code 0x%x, exiting loop..." + ) % md.error_code << std::endl; + goto done_loop; + } + + //send complex single precision floating point samples over udp + udp_xport->send(boost::asio::buffer(buff, num_rx_samps)); + + if(verbose) std::cout << boost::format( + "Got packet: %u samples, %u full secs, %f frac secs" + ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; + + num_acc_samps += num_rx_samps; + } done_loop: + + //finished + std::cout << std::endl << "Done!" << std::endl << std::endl; + + return 0; +} diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index 441665900..8a810811f 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -32,7 +32,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ std::string args; time_t seconds_in_future; size_t total_num_samps; - double rx_rate, freq; + double rate, freq; //setup the program options po::options_description desc("Allowed options"); @@ -41,7 +41,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("args", po::value(&args)->default_value(""), "single uhd device address args") ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to receive") ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") - ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") + ("rate", po::value(&rate)->default_value(100e6/16), "rate of incoming samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") ("dilv", "specify to disable inner-loop verbose") ; @@ -64,12 +64,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::device::sptr dev = sdev->get_device(); std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; - //set properties on the device - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; - sdev->set_rx_rate(rx_rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; - std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + //set the rx sample rate + std::cout << boost::format("Setting RX Rate: %f Msps...") % (rate/1e6) << std::endl; + sdev->set_rx_rate(rate); + std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl << std::endl; + + //set the rx center frequency + std::cout << boost::format("Setting RX Freq: %f Mhz...") % (freq/1e6) << std::endl; sdev->set_rx_freq(freq); + std::cout << boost::format("Actual RX Freq: %f Mhz...") % (sdev->get_rx_freq()/1e6) << std::endl << std::endl; + + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; sdev->set_time_now(uhd::time_spec_t(0.0)); //setup streaming diff --git a/host/examples/rx_to_file.cpp b/host/examples/rx_to_file.cpp deleted file mode 100644 index 25727a7d3..000000000 --- a/host/examples/rx_to_file.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// 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 . -// - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace po = boost::program_options; - - -int UHD_SAFE_MAIN(int argc, char *argv[]){ - uhd::set_thread_priority_safe(); - - //variables to be set by po - std::string args, file; - time_t seconds_in_future; - size_t total_num_samps; - double rx_rate, freq; - - //setup the program options - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "help message") - ("args", po::value(&args)->default_value(""), "single uhd device address args") - ("file", po::value(&file)->default_value("out.16sc.dat"), "name of the file to write binary samples to") - ("secs", po::value(&seconds_in_future)->default_value(1), "number of seconds in the future to receive") - ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to receive") - ("rxrate", po::value(&rx_rate)->default_value(100e6/16), "rate of incoming samples") - ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") - ("dilv", "specify to disable inner-loop verbose") - ; - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - //print the help message - if (vm.count("help")){ - std::cout << boost::format("UHD RX to File %s") % desc << std::endl; - return ~0; - } - - bool verbose = vm.count("dilv") == 0; - - //create a usrp device - std::cout << std::endl; - std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; - uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args); - uhd::device::sptr dev = sdev->get_device(); - std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; - - //set properties on the device - std::cout << boost::format("Setting RX Rate: %f Msps...") % (rx_rate/1e6) << std::endl; - sdev->set_rx_rate(rx_rate); - std::cout << boost::format("Actual RX Rate: %f Msps...") % (sdev->get_rx_rate()/1e6) << std::endl; - std::cout << boost::format("Setting device timestamp to 0...") << std::endl; - sdev->set_rx_freq(freq); - sdev->set_time_now(uhd::time_spec_t(0.0)); - - uhd::gain_range_t rx_gain = sdev->get_rx_gain_range(); - std::cout << "Setting RX Gain to: " << rx_gain.max << std::endl; - sdev->set_rx_gain(rx_gain.max); - - sleep(1); - std::cout << "LO Locked = " << sdev->get_rx_lo_locked() << std::endl; - - //setup streaming - std::cout << std::endl; - std::cout << boost::format( - "Begin streaming %u samples, %d seconds in the future..." - ) % total_num_samps % seconds_in_future << std::endl; - uhd::stream_cmd_t stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE); - stream_cmd.num_samps = total_num_samps; - stream_cmd.stream_now = false; - stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future); - sdev->issue_stream_cmd(stream_cmd); - - //loop until total number of samples reached - size_t num_acc_samps = 0; //number of accumulated samples - uhd::rx_metadata_t md; - std::vector > buff(dev->get_max_recv_samps_per_packet()); - std::ofstream outfile(file.c_str(), std::ofstream::binary); - - while(num_acc_samps < total_num_samps){ - size_t num_rx_samps = dev->recv( - &buff.front(), buff.size(), md, - uhd::io_type_t::COMPLEX_INT16, - uhd::device::RECV_MODE_ONE_PACKET - ); - - //handle the error codes - switch(md.error_code){ - case uhd::rx_metadata_t::ERROR_CODE_NONE: - break; - - case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: - if (num_acc_samps == 0) continue; - std::cout << boost::format( - "Got timeout before all samples received, possible packet loss, exiting loop..." - ) << std::endl; - goto done_loop; - - default: - std::cout << boost::format( - "Got error code 0x%x, exiting loop..." - ) % md.error_code << std::endl; - goto done_loop; - } - - //write complex short integer samples to the binary file - outfile.write((const char*)&buff[0], num_rx_samps * sizeof(std::complex)); - - if(verbose) std::cout << boost::format( - "Got packet: %u samples, %u full secs, %f frac secs" - ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; - - num_acc_samps += num_rx_samps; - } done_loop: - - outfile.close(); - - //finished - std::cout << std::endl << "Done!" << std::endl << std::endl; - - return 0; -} diff --git a/host/examples/tx_timed_samples.cpp b/host/examples/tx_timed_samples.cpp index 863446682..799da37e0 100644 --- a/host/examples/tx_timed_samples.cpp +++ b/host/examples/tx_timed_samples.cpp @@ -33,7 +33,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ time_t seconds_in_future; size_t total_num_samps; size_t samps_per_packet; - double tx_rate, freq; + double rate, freq; float ampl; //setup the program options @@ -44,7 +44,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("secs", po::value(&seconds_in_future)->default_value(3), "number of seconds in the future to transmit") ("nsamps", po::value(&total_num_samps)->default_value(1000), "total number of samples to transmit") ("spp", po::value(&samps_per_packet)->default_value(1000), "number of samples per packet") - ("txrate", po::value(&tx_rate)->default_value(100e6/16), "rate of outgoing samples") + ("rate", po::value(&rate)->default_value(100e6/16), "rate of outgoing samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") ("ampl", po::value(&l)->default_value(float(0.3)), "amplitude of each sample") ("dilv", "specify to disable inner-loop verbose") @@ -68,12 +68,17 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ uhd::device::sptr dev = sdev->get_device(); std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; - //set properties on the device - std::cout << boost::format("Setting TX Rate: %f Msps...") % (tx_rate/1e6) << std::endl; - sdev->set_tx_rate(tx_rate); - std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl; - std::cout << boost::format("Setting device timestamp to 0...") << std::endl; + //set the tx sample rate + std::cout << boost::format("Setting TX Rate: %f Msps...") % (rate/1e6) << std::endl; + sdev->set_tx_rate(rate); + std::cout << boost::format("Actual TX Rate: %f Msps...") % (sdev->get_tx_rate()/1e6) << std::endl << std::endl; + + //set the tx center frequency + std::cout << boost::format("Setting TX Freq: %f Mhz...") % (freq/1e6) << std::endl; sdev->set_tx_freq(freq); + std::cout << boost::format("Actual TX Freq: %f Mhz...") % (sdev->get_tx_freq()/1e6) << std::endl << std::endl; + + std::cout << boost::format("Setting device timestamp to 0...") << std::endl; sdev->set_time_now(uhd::time_spec_t(0.0)); //allocate data to send -- cgit v1.2.3 From d7c7351bb66cb4c455e77f83edd581d6afbcef9c Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 27 Oct 2010 19:30:45 -0700 Subject: uhd: removed dilv in rx files examples --- host/examples/rx_samples_to_file.cpp | 7 ------- host/examples/rx_samples_to_udp.cpp | 7 ------- 2 files changed, 14 deletions(-) diff --git a/host/examples/rx_samples_to_file.cpp b/host/examples/rx_samples_to_file.cpp index 6671644fa..c80d2a6de 100644 --- a/host/examples/rx_samples_to_file.cpp +++ b/host/examples/rx_samples_to_file.cpp @@ -46,7 +46,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("rate", po::value(&rate)->default_value(100e6/16), "rate of incoming samples") ("freq", po::value(&freq)->default_value(0), "rf center frequency in Hz") ("gain", po::value(&gain)->default_value(0), "gain for the RF chain") - ("dilv", "specify to disable inner-loop verbose") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -58,8 +57,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ return ~0; } - bool verbose = vm.count("dilv") == 0; - //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; @@ -126,10 +123,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //write complex short integer samples to the binary file outfile.write((const char*)&buff[0], num_rx_samps * sizeof(std::complex)); - if(verbose) std::cout << boost::format( - "Got packet: %u samples, %u full secs, %f frac secs" - ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; - num_acc_samps += num_rx_samps; } done_loop: diff --git a/host/examples/rx_samples_to_udp.cpp b/host/examples/rx_samples_to_udp.cpp index c81b43ee3..488c95494 100644 --- a/host/examples/rx_samples_to_udp.cpp +++ b/host/examples/rx_samples_to_udp.cpp @@ -48,7 +48,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ("gain", po::value(&gain)->default_value(0), "gain for the RF chain") ("port", po::value(&port)->default_value("7124"), "server udp port") ("addr", po::value(&addr)->default_value("192.168.1.10"), "resolvable server address") - ("dilv", "specify to disable inner-loop verbose") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); @@ -60,8 +59,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ return ~0; } - bool verbose = vm.count("dilv") == 0; - //create a usrp device std::cout << std::endl; std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; @@ -128,10 +125,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ //send complex single precision floating point samples over udp udp_xport->send(boost::asio::buffer(buff, num_rx_samps)); - if(verbose) std::cout << boost::format( - "Got packet: %u samples, %u full secs, %f frac secs" - ) % num_rx_samps % md.time_spec.get_full_secs() % md.time_spec.get_frac_secs() << std::endl; - num_acc_samps += num_rx_samps; } done_loop: -- cgit v1.2.3 From 904332c7ba8b66877b8ca56e43ed2e5cfdbc661b Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 28 Oct 2010 10:26:12 -0700 Subject: uhd: added to python module check macro, move check to lib dir --- host/config/Python.cmake | 25 +++++++++++-------------- host/lib/CMakeLists.txt | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/host/config/Python.cmake b/host/config/Python.cmake index 55ef6acca..a5080fc40 100644 --- a/host/config/Python.cmake +++ b/host/config/Python.cmake @@ -24,26 +24,23 @@ IF(NOT PYTHONINTERP_FOUND) MESSAGE(FATAL_ERROR "Error: Python interpretor required by the build system.") ENDIF(NOT PYTHONINTERP_FOUND) -MACRO(PYTHON_CHECK_MODULE module have) - MESSAGE(STATUS "Checking for python module ${module}") +MACRO(PYTHON_CHECK_MODULE desc mod cmd have) + MESSAGE(STATUS "Python checking for ${desc}") EXECUTE_PROCESS( - COMMAND ${PYTHON_EXECUTABLE} -c "import ${module}" + COMMAND ${PYTHON_EXECUTABLE} -c " +######################################### +try: import ${mod} +except: exit(-1) +try: assert ${cmd} +except: exit(-1) +#########################################" RESULT_VARIABLE ${have} ) IF(${have} EQUAL 0) - MESSAGE(STATUS "Checking for python module ${module} - found") + MESSAGE(STATUS "Python checking for ${desc} - found") SET(${have} TRUE) ELSE(${have} EQUAL 0) - MESSAGE(STATUS "Checking for python module ${module} - not found") + MESSAGE(STATUS "Python checking for ${desc} - not found") SET(${have} FALSE) ENDIF(${have} EQUAL 0) ENDMACRO(PYTHON_CHECK_MODULE) - -######################################################################## -# Check Modules -######################################################################## -PYTHON_CHECK_MODULE("Cheetah" HAVE_PYTHON_MODULE_CHEETAH) - -IF(NOT HAVE_PYTHON_MODULE_CHEETAH) - MESSAGE(FATAL_ERROR "Error: Cheetah Templates required by the build system.") -ENDIF(NOT HAVE_PYTHON_MODULE_CHEETAH) diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 81845de21..b0e610d41 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -15,6 +15,25 @@ # along with this program. If not, see . # +######################################################################## +# Check Python Modules +######################################################################## +PYTHON_CHECK_MODULE( + "Python version >= 2.6" + "platform" "platform.python_version() >= '2.6'" + HAVE_PYTHON_PLAT_MIN_VERSION +) + +PYTHON_CHECK_MODULE( + "Cheetah templates >= 2.0.0" + "Cheetah" "Cheetah.Version >= '2.0.0'" + HAVE_PYTHON_MODULE_CHEETAH +) + +IF(NOT HAVE_PYTHON_PLAT_MIN_VERSION OR NOT HAVE_PYTHON_MODULE_CHEETAH) + MESSAGE(FATAL_ERROR "Error: python requirements not met for the build system.") +ENDIF(NOT HAVE_PYTHON_PLAT_MIN_VERSION OR NOT HAVE_PYTHON_MODULE_CHEETAH) + ######################################################################## # Helpful Macros ######################################################################## -- cgit v1.2.3 From 689778831d204b443beb0f5435aa0b540f97b105 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 28 Oct 2010 10:40:37 -0700 Subject: uhd: change python module check descriptions to use words --- host/lib/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index b0e610d41..e4de7bcc7 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -19,13 +19,13 @@ # Check Python Modules ######################################################################## PYTHON_CHECK_MODULE( - "Python version >= 2.6" + "Python version 2.6 or greater" "platform" "platform.python_version() >= '2.6'" HAVE_PYTHON_PLAT_MIN_VERSION ) PYTHON_CHECK_MODULE( - "Cheetah templates >= 2.0.0" + "Cheetah templates 2.0.0 or greater" "Cheetah" "Cheetah.Version >= '2.0.0'" HAVE_PYTHON_MODULE_CHEETAH ) -- cgit v1.2.3 From 5f0c948ecc501ff03ba242f64edbdfaa9f748f38 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 28 Oct 2010 17:24:13 -0700 Subject: usrp2: documented LED E --- host/docs/usrp2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/docs/usrp2.rst b/host/docs/usrp2.rst index 0ddcaa4e5..ada98000d 100644 --- a/host/docs/usrp2.rst +++ b/host/docs/usrp2.rst @@ -179,7 +179,7 @@ The LEDs reveal the following about the state of the device: * **LED B:** undocumented * **LED C:** receiving * **LED D:** firmware loaded -* **LED E:** undocumented +* **LED E:** reference lock * **LED F:** FPGA loaded -- cgit v1.2.3 From 6a3e499f586513d48ef648aa910e252b7d8b046b Mon Sep 17 00:00:00 2001 From: Jason Abele Date: Thu, 28 Oct 2010 18:06:01 -0700 Subject: Fix Bandwidth for IQ subdevs on Basic/LF Additional typo cleanup and fix WBX bandwidth --- host/docs/dboards.rst | 14 +++++++++++--- host/lib/usrp/dboard/db_basic_and_lf.cpp | 14 ++++++++++++-- host/lib/usrp/dboard/db_rfx.cpp | 4 ++-- host/lib/usrp/dboard/db_tvrx.cpp | 2 +- host/lib/usrp/dboard/db_wbx.cpp | 4 ++-- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/host/docs/dboards.rst b/host/docs/dboards.rst index d93fb9d6a..b39c587f6 100644 --- a/host/docs/dboards.rst +++ b/host/docs/dboards.rst @@ -26,9 +26,13 @@ The boards have no tunable elements or programmable gains. Though the magic of aliasing, you can down-convert signals greater than the Nyquist rate of the ADC. -BasicRX Bandwidth (Hz): 250M +BasicRX Bandwidth (Hz): + For Real-Mode (A or B subdevice): 250M + For Complex (AB or BA subdevice): 500M -LFRX Bandwidth (Hz): 30M +LFRX Bandwidth (Hz): + For Real-Mode (A or B subdevice): 33M + For Complex (AB or BA subdevice): 66M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Basic TX and and LFTX @@ -45,8 +49,12 @@ Though the magic of aliasing, you can up-convert signals greater than the Nyquist rate of the DAC. BasicTX Bandwidth (Hz): 250M + For Real-Mode (A or B subdevice): 250M + For Complex (AB or BA subdevice): 500M -LFTX Bandwidth (Hz): 30M +LFTX Bandwidth (Hz): 33M + For Real-Mode (A or B subdevice): 33M + For Complex (AB or BA subdevice): 66M ^^^^^^^^^^^^^^^^^^^^^^^^^^^ DBSRX diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index 4c49b3bff..f03dd43d1 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -30,6 +30,16 @@ using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; +/*********************************************************************** + * Constants + **********************************************************************/ +static const uhd::dict subdev_bandwidth_scalar = map_list_of + ("A", 1.0) + ("B", 1.0) + ("AB", 2.0) + ("BA", 2.0) +; + /*********************************************************************** * The basic and lf boards: * They share a common class because only the frequency bounds differ. @@ -163,7 +173,7 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 2*_max_freq; //we want complex double-sided + val = subdev_bandwidth_scalar[get_subdev_name()]*_max_freq; return; default: UHD_THROW_PROP_GET_ERROR(); @@ -274,7 +284,7 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 2*_max_freq; //we want complex double-sided + val = subdev_bandwidth_scalar[get_subdev_name()]*_max_freq; return; default: UHD_THROW_PROP_GET_ERROR(); diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 12e458d8c..152198c3a 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -458,7 +458,7 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 2*20.0e6; //30MHz low-pass, we want complex double-sided + val = 2*20.0e6; //20MHz low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); @@ -555,7 +555,7 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 2*20.0e6; //30MHz low-pass, we want complex double-sided + val = 2*20.0e6; //20MHz low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); diff --git a/host/lib/usrp/dboard/db_tvrx.cpp b/host/lib/usrp/dboard/db_tvrx.cpp index 1f3c76556..2873e3d54 100644 --- a/host/lib/usrp/dboard/db_tvrx.cpp +++ b/host/lib/usrp/dboard/db_tvrx.cpp @@ -460,7 +460,7 @@ void tvrx::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 6.0e6; //30MHz low-pass, we want complex double-sided + val = 6.0e6; return; default: UHD_THROW_PROP_GET_ERROR(); diff --git a/host/lib/usrp/dboard/db_wbx.cpp b/host/lib/usrp/dboard/db_wbx.cpp index 647f1b975..572f5de97 100644 --- a/host/lib/usrp/dboard/db_wbx.cpp +++ b/host/lib/usrp/dboard/db_wbx.cpp @@ -527,7 +527,7 @@ void wbx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 2*30.0e6; //20MHz low-pass, we want complex double-sided + val = 2*20.0e6; //20MHz low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); @@ -628,7 +628,7 @@ void wbx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ return; case SUBDEV_PROP_BANDWIDTH: - val = 2*30.0e6; //20MHz low-pass, we want complex double-sided + val = 2*20.0e6; //20MHz low-pass, we want complex double-sided return; default: UHD_THROW_PROP_GET_ERROR(); -- cgit v1.2.3