aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/types
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2011-01-06 11:56:35 -0800
committerJosh Blum <josh@joshknows.com>2011-01-06 11:56:35 -0800
commitfd9962af9ed6682117c3ab224548298907f59c49 (patch)
tree1043bb61e6613148d45b8c83cf65978384ab70d8 /host/lib/types
parent6619a40b48029dae1ee1f46db81ba470debaffd2 (diff)
downloaduhd-fd9962af9ed6682117c3ab224548298907f59c49.tar.gz
uhd-fd9962af9ed6682117c3ab224548298907f59c49.tar.bz2
uhd-fd9962af9ed6682117c3ab224548298907f59c49.zip
uhd: created sensors value, made lib/types and moved files
Diffstat (limited to 'host/lib/types')
-rw-r--r--host/lib/types/CMakeLists.txt25
-rw-r--r--host/lib/types/ranges.cpp163
-rw-r--r--host/lib/types/sensors.cpp69
-rw-r--r--host/lib/types/types.cpp359
4 files changed, 616 insertions, 0 deletions
diff --git a/host/lib/types/CMakeLists.txt b/host/lib/types/CMakeLists.txt
new file mode 100644
index 000000000..7a8093ed5
--- /dev/null
+++ b/host/lib/types/CMakeLists.txt
@@ -0,0 +1,25 @@
+#
+# Copyright 2011 Ettus Research LLC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+LIBUHD_APPEND_SOURCES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/ranges.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/sensors.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/types.cpp
+)
diff --git a/host/lib/types/ranges.cpp b/host/lib/types/ranges.cpp
new file mode 100644
index 000000000..4a0d05d80
--- /dev/null
+++ b/host/lib/types/ranges.cpp
@@ -0,0 +1,163 @@
+//
+// Copyright 2011-2011 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/types/ranges.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <boost/foreach.hpp>
+#include <algorithm>
+#include <stdexcept>
+#include <sstream>
+
+using namespace uhd;
+
+/***********************************************************************
+ * range_t implementation code
+ **********************************************************************/
+struct range_t::impl{
+ impl(double start, double stop, double step):
+ start(start), stop(stop), step(step)
+ {
+ /* NOP */
+ }
+ double start, stop, step;
+};
+
+range_t::range_t(double value):
+ _impl(UHD_PIMPL_MAKE(impl, (value, value, 0)))
+{
+ /* NOP */
+}
+
+range_t::range_t(
+ double start, double stop, double step
+):
+ _impl(UHD_PIMPL_MAKE(impl, (start, stop, step)))
+{
+ if (stop < start){
+ throw std::invalid_argument("cannot make range where stop < start");
+ }
+}
+
+double range_t::start(void) const{
+ return _impl->start;
+}
+
+double range_t::stop(void) const{
+ return _impl->stop;
+}
+
+double range_t::step(void) const{
+ return _impl->step;
+}
+
+const std::string range_t::to_pp_string(void) const{
+ std::stringstream ss;
+ ss << "(" << this->start();
+ if (this->start() != this->stop()) ss << ", " << this->stop();
+ if (this->step() != 0) ss << ", " << this->step();
+ ss << ")";
+ return ss.str();
+}
+
+/***********************************************************************
+ * meta_range_t implementation code
+ **********************************************************************/
+void check_meta_range_monotonic(const meta_range_t &mr){
+ if (mr.empty()){
+ throw std::runtime_error("meta-range cannot be empty");
+ }
+ for (size_t i = 1; i < mr.size(); i++){
+ if (mr.at(i).start() < mr.at(i-1).stop()){
+ throw std::runtime_error("meta-range is not monotonic");
+ }
+ }
+}
+
+meta_range_t::meta_range_t(void){
+ /* NOP */
+}
+
+meta_range_t::meta_range_t(
+ double start, double stop, double step
+):
+ std::vector<range_t > (1, range_t(start, stop, step))
+{
+ /* NOP */
+}
+
+double meta_range_t::start(void) const{
+ check_meta_range_monotonic(*this);
+ double min_start = this->front().start();
+ BOOST_FOREACH(const range_t &r, (*this)){
+ min_start = std::min(min_start, r.start());
+ }
+ return min_start;
+}
+
+double meta_range_t::stop(void) const{
+ check_meta_range_monotonic(*this);
+ double max_stop = this->front().stop();
+ BOOST_FOREACH(const range_t &r, (*this)){
+ max_stop = std::max(max_stop, r.stop());
+ }
+ return max_stop;
+}
+
+double meta_range_t::step(void) const{
+ check_meta_range_monotonic(*this);
+ std::vector<double> non_zero_steps;
+ range_t last = this->front();
+ BOOST_FOREACH(const range_t &r, (*this)){
+ //steps at each range
+ if (r.step() > 0) non_zero_steps.push_back(r.step());
+ //and steps in-between ranges
+ double ibtw_step = r.start() - last.stop();
+ if (ibtw_step > 0) non_zero_steps.push_back(ibtw_step);
+ //store ref to last
+ last = r;
+ }
+ if (non_zero_steps.empty()) return 0; //all zero steps, its zero...
+ return *std::min_element(non_zero_steps.begin(), non_zero_steps.end());
+}
+
+double meta_range_t::clip(double value, bool clip_step) const{
+ check_meta_range_monotonic(*this);
+ double last_stop = this->front().stop();
+ BOOST_FOREACH(const range_t &r, (*this)){
+ //in-between ranges, clip to nearest
+ if (value < r.start()){
+ return (std::abs(value - r.start()) < std::abs(value - last_stop))?
+ r.start() : last_stop;
+ }
+ //in this range, clip here
+ if (value <= r.stop()){
+ if (not clip_step or r.step() == 0) return value;
+ return boost::math::round((value - r.start())/r.step())*r.step() + r.start();
+ }
+ //continue on to the next range
+ last_stop = r.stop();
+ }
+ return last_stop;
+}
+
+const std::string meta_range_t::to_pp_string(void) const{
+ std::stringstream ss;
+ BOOST_FOREACH(const range_t &r, (*this)){
+ ss << r.to_pp_string() << std::endl;
+ }
+ return ss.str();
+}
diff --git a/host/lib/types/sensors.cpp b/host/lib/types/sensors.cpp
new file mode 100644
index 000000000..497f4bfd5
--- /dev/null
+++ b/host/lib/types/sensors.cpp
@@ -0,0 +1,69 @@
+//
+// Copyright 2011-2011 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/types/sensors.hpp>
+#include <uhd/utils/exception.hpp>
+#include <boost/format.hpp>
+
+using namespace uhd;
+
+sensor_value_t::sensor_value_t(
+ const std::string &name,
+ bool value,
+ const std::string &ufalse,
+ const std::string &utrue
+):
+ name(name), value(value?"true":"false"),
+ unit(value?utrue:ufalse), type(BOOLEAN)
+{
+ /* NOP */
+}
+
+sensor_value_t::sensor_value_t(
+ const std::string &name,
+ int_type value,
+ const std::string &unit,
+ const std::string &formatter
+):
+ name(name), value(str(boost::format(formatter) % value)),
+ unit(unit), type(INTEGER)
+{
+ /* NOP */
+}
+
+sensor_value_t::sensor_value_t(
+ const std::string &name,
+ real_type value,
+ const std::string &unit,
+ const std::string &formatter
+):
+ name(name), value(str(boost::format(formatter) % value)),
+ unit(unit), type(REALNUM)
+{
+ /* NOP */
+}
+
+std::string sensor_value_t::to_pp_string(void) const{
+ switch(type){
+ case BOOLEAN:
+ return str(boost::format("%s: %s") % name % unit);
+ case INTEGER:
+ case REALNUM:
+ return str(boost::format("%s: %s %s") % name % value % unit);
+ }
+ UHD_THROW_INVALID_CODE_PATH();
+}
diff --git a/host/lib/types/types.cpp b/host/lib/types/types.cpp
new file mode 100644
index 000000000..dce8d0828
--- /dev/null
+++ b/host/lib/types/types.cpp
@@ -0,0 +1,359 @@
+//
+// Copyright 2010-2011 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include <uhd/utils/assert.hpp>
+#include <uhd/types/tune_request.hpp>
+#include <uhd/types/tune_result.hpp>
+#include <uhd/types/clock_config.hpp>
+#include <uhd/types/stream_cmd.hpp>
+#include <uhd/types/metadata.hpp>
+#include <uhd/types/time_spec.hpp>
+#include <uhd/types/device_addr.hpp>
+#include <uhd/types/mac_addr.hpp>
+#include <uhd/types/otw_type.hpp>
+#include <uhd/types/io_type.hpp>
+#include <uhd/types/serial.hpp>
+#include <boost/math/special_functions/round.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/thread.hpp>
+#include <stdexcept>
+#include <complex>
+#include <sstream>
+
+using namespace uhd;
+
+/***********************************************************************
+ * 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),
+ inter_freq_policy(POLICY_MANUAL),
+ inter_freq(target_freq + lo_off),
+ dsp_freq_policy(POLICY_AUTO)
+{
+ /* NOP */
+}
+
+/***********************************************************************
+ * tune result
+ **********************************************************************/
+std::string tune_result_t::to_pp_string(void) const{
+ return str(boost::format(
+ "Tune Result:\n"
+ " Target Intermediate Freq: %f (MHz)\n"
+ " Actual Intermediate Freq: %f (MHz)\n"
+ " Target DSP Freq Shift: %f (MHz)\n"
+ " Actual DSP Freq Shift: %f (MHz)\n"
+ )
+ % (target_inter_freq/1e6) % (actual_inter_freq/1e6)
+ % (target_dsp_freq/1e6) % (actual_dsp_freq/1e6)
+ );
+}
+
+/***********************************************************************
+ * clock config
+ **********************************************************************/
+clock_config_t clock_config_t::external(void){
+ clock_config_t clock_config;
+ clock_config.ref_source = clock_config_t::REF_SMA;
+ clock_config.pps_source = clock_config_t::PPS_SMA;
+ clock_config.pps_polarity = clock_config_t::PPS_POS;
+ return clock_config;
+}
+
+clock_config_t clock_config_t::internal(void){
+ clock_config_t clock_config;
+ clock_config.ref_source = clock_config_t::REF_INT;
+ clock_config.pps_source = clock_config_t::PPS_INT;
+ clock_config.pps_polarity = clock_config_t::PPS_POS;
+ return clock_config;
+}
+
+clock_config_t::clock_config_t(void):
+ ref_source(REF_INT),
+ pps_source(PPS_INT),
+ pps_polarity(PPS_POS)
+{
+ /* NOP */
+}
+
+/***********************************************************************
+ * stream command
+ **********************************************************************/
+stream_cmd_t::stream_cmd_t(const stream_mode_t &stream_mode):
+ stream_mode(stream_mode),
+ num_samps(0),
+ stream_now(true)
+{
+ /* NOP */
+}
+
+/***********************************************************************
+ * metadata
+ **********************************************************************/
+tx_metadata_t::tx_metadata_t(void):
+ has_time_spec(false),
+ time_spec(time_spec_t()),
+ start_of_burst(false),
+ end_of_burst(false)
+{
+ /* NOP */
+}
+
+/***********************************************************************
+ * time spec
+ **********************************************************************/
+time_spec_t::time_spec_t(double secs):
+ _full_secs(0),
+ _frac_secs(secs)
+{
+ /* NOP */
+}
+
+time_spec_t::time_spec_t(time_t full_secs, double frac_secs):
+ _full_secs(full_secs),
+ _frac_secs(frac_secs)
+{
+ /* NOP */
+}
+
+time_spec_t::time_spec_t(time_t full_secs, long tick_count, double tick_rate):
+ _full_secs(full_secs),
+ _frac_secs(double(tick_count)/tick_rate)
+{
+ /* NOP */
+}
+
+long time_spec_t::get_tick_count(double tick_rate) const{
+ return boost::math::iround(this->get_frac_secs()*tick_rate);
+}
+
+double time_spec_t::get_real_secs(void) const{
+ return this->_full_secs + this->_frac_secs;
+}
+
+time_t time_spec_t::get_full_secs(void) const{
+ double intpart;
+ std::modf(this->_frac_secs, &intpart);
+ return this->_full_secs + time_t(intpart);
+}
+
+double time_spec_t::get_frac_secs(void) const{
+ return std::fmod(this->_frac_secs, 1.0);
+}
+
+time_spec_t &time_spec_t::operator+=(const time_spec_t &rhs){
+ this->_full_secs += rhs.get_full_secs();
+ this->_frac_secs += rhs.get_frac_secs();
+ return *this;
+}
+
+time_spec_t &time_spec_t::operator-=(const time_spec_t &rhs){
+ this->_full_secs -= rhs.get_full_secs();
+ this->_frac_secs -= rhs.get_frac_secs();
+ return *this;
+}
+
+bool uhd::operator==(const time_spec_t &lhs, const time_spec_t &rhs){
+ return
+ lhs.get_full_secs() == rhs.get_full_secs() and
+ lhs.get_frac_secs() == rhs.get_frac_secs()
+ ;
+}
+
+bool uhd::operator<(const time_spec_t &lhs, const time_spec_t &rhs){
+ return (
+ (lhs.get_full_secs() < rhs.get_full_secs()) or (
+ (lhs.get_full_secs() == rhs.get_full_secs()) and
+ (lhs.get_frac_secs() < rhs.get_frac_secs())
+ ));
+}
+
+/***********************************************************************
+ * device addr
+ **********************************************************************/
+static const std::string arg_delim = ",";
+static const std::string pair_delim = "=";
+
+static std::string trim(const std::string &in){
+ return boost::algorithm::trim_copy(in);
+}
+
+device_addr_t::device_addr_t(const std::string &args){
+ BOOST_FOREACH(const std::string &pair, std::split_string(args, arg_delim)){
+ if (trim(pair) == "") continue;
+
+ std::vector<std::string> key_val = std::split_string(pair, pair_delim);
+ if (key_val.size() != 2) throw std::runtime_error("invalid args string: "+args);
+ (*this)[trim(key_val.front())] = trim(key_val.back());
+ }
+}
+
+std::string device_addr_t::to_pp_string(void) const{
+ if (this->size() == 0) return "Empty Device Address";
+
+ std::stringstream ss;
+ ss << "Device Address:" << std::endl;
+ BOOST_FOREACH(std::string key, this->keys()){
+ ss << boost::format(" %s: %s") % key % (*this)[key] << std::endl;
+ }
+ return ss.str();
+}
+
+std::string device_addr_t::to_string(void) const{
+ std::string args_str;
+ size_t count = 0;
+ BOOST_FOREACH(const std::string &key, this->keys()){
+ args_str += ((count++)? arg_delim : "") + key + pair_delim + (*this)[key];
+ }
+ return args_str;
+}
+
+/***********************************************************************
+ * mac addr
+ **********************************************************************/
+mac_addr_t::mac_addr_t(const byte_vector_t &bytes) : _bytes(bytes){
+ UHD_ASSERT_THROW(_bytes.size() == 6);
+}
+
+mac_addr_t mac_addr_t::from_bytes(const byte_vector_t &bytes){
+ return mac_addr_t(bytes);
+}
+
+mac_addr_t mac_addr_t::from_string(const std::string &mac_addr_str){
+
+ byte_vector_t bytes;
+
+ try{
+ if (mac_addr_str.size() != 17){
+ throw std::runtime_error("expected exactly 17 characters");
+ }
+
+ //split the mac addr hex string at the colons
+ BOOST_FOREACH(const std::string &hex_str, std::split_string(mac_addr_str, ":")){
+ int hex_num;
+ std::istringstream iss(hex_str);
+ iss >> std::hex >> hex_num;
+ bytes.push_back(boost::uint8_t(hex_num));
+ }
+
+ }
+ catch(std::exception const& e){
+ throw std::runtime_error(str(
+ boost::format("Invalid mac address: %s\n\t%s") % mac_addr_str % e.what()
+ ));
+ }
+
+ return mac_addr_t::from_bytes(bytes);
+}
+
+byte_vector_t mac_addr_t::to_bytes(void) const{
+ return _bytes;
+}
+
+std::string mac_addr_t::to_string(void) const{
+ std::string addr = "";
+ BOOST_FOREACH(boost::uint8_t byte, this->to_bytes()){
+ addr += str(boost::format("%s%02x") % ((addr == "")?"":":") % int(byte));
+ }
+ return addr;
+}
+
+/***********************************************************************
+ * otw type
+ **********************************************************************/
+size_t otw_type_t::get_sample_size(void) const{
+ return (this->width * 2) / 8;
+}
+
+otw_type_t::otw_type_t(void):
+ width(0),
+ shift(0),
+ byteorder(BO_NATIVE)
+{
+ /* NOP */
+}
+
+/***********************************************************************
+ * io type
+ **********************************************************************/
+static size_t tid_to_size(io_type_t::tid_t tid){
+ switch(tid){
+ case io_type_t::COMPLEX_FLOAT32: return sizeof(std::complex<float>);
+ case io_type_t::COMPLEX_INT16: return sizeof(std::complex<boost::int16_t>);
+ case io_type_t::COMPLEX_INT8: return sizeof(std::complex<boost::int8_t>);
+ default: throw std::runtime_error("unknown io type tid");
+ }
+}
+
+io_type_t::io_type_t(tid_t tid)
+: size(tid_to_size(tid)), tid(tid){
+ /* NOP */
+}
+
+io_type_t::io_type_t(size_t size)
+: size(size), tid(CUSTOM_TYPE){
+ /* NOP */
+}
+
+/***********************************************************************
+ * serial
+ **********************************************************************/
+spi_config_t::spi_config_t(edge_t edge):
+ mosi_edge(edge),
+ miso_edge(edge)
+{
+ /* NOP */
+}
+
+void i2c_iface::write_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ const byte_vector_t &bytes
+){
+ for (size_t i = 0; i < bytes.size(); i++){
+ //write a byte at a time, its easy that way
+ byte_vector_t cmd = boost::assign::list_of(offset+i)(bytes[i]);
+ this->write_i2c(addr, cmd);
+ boost::this_thread::sleep(boost::posix_time::milliseconds(10)); //worst case write
+ }
+}
+
+byte_vector_t i2c_iface::read_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ size_t num_bytes
+){
+ byte_vector_t bytes;
+ for (size_t i = 0; i < num_bytes; i++){
+ //do a zero byte write to start read cycle
+ this->write_i2c(addr, byte_vector_t(1, offset+i));
+ bytes.push_back(this->read_i2c(addr, 1).at(0));
+ }
+ return bytes;
+}