From 275b29e07f97cdf638ecb22c602d26b7d340547a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 2 Apr 2010 17:54:06 -0700 Subject: some work on rfx board code --- host/include/uhd/usrp/subdev_props.hpp | 2 +- host/lib/CMakeLists.txt | 1 + host/lib/usrp/dboard/db_basic_and_lf.cpp | 16 +- host/lib/usrp/dboard/db_rfx.cpp | 300 +++++++++++++++++++++++++++++++ 4 files changed, 303 insertions(+), 16 deletions(-) create mode 100644 host/lib/usrp/dboard/db_rfx.cpp diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp index 92d18340b..b7d22b777 100644 --- a/host/include/uhd/usrp/subdev_props.hpp +++ b/host/include/uhd/usrp/subdev_props.hpp @@ -35,7 +35,7 @@ namespace uhd{ namespace usrp{ SUBDEV_PROP_FREQ_RANGE = 'F', //ro, freq_range_t SUBDEV_PROP_ANTENNA = 'a', //rw, std::string SUBDEV_PROP_ANTENNA_NAMES = 'A', //ro, prop_names_t - SUBDEV_PROP_ENABLED = 'e', //rw, bool + //SUBDEV_PROP_ENABLED = 'e', //rw, bool //---> dont need, we have atr SUBDEV_PROP_QUADRATURE = 'q', //ro, bool SUBDEV_PROP_IQ_SWAPPED = 'i', //ro, bool SUBDEV_PROP_SPECTRUM_INVERTED = 's', //ro, bool diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a5345cae4..a4bf46f1a 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -28,6 +28,7 @@ SET(libuhd_sources transport/udp_simple.cpp transport/vrt.cpp usrp/dboard/db_basic_and_lf.cpp + usrp/dboard/db_rfx.cpp usrp/dboard_base.cpp usrp/dboard_interface.cpp usrp/simple_usrp.cpp diff --git a/host/lib/usrp/dboard/db_basic_and_lf.cpp b/host/lib/usrp/dboard/db_basic_and_lf.cpp index be4e646ed..2f6890b25 100644 --- a/host/lib/usrp/dboard/db_basic_and_lf.cpp +++ b/host/lib/usrp/dboard/db_basic_and_lf.cpp @@ -75,7 +75,7 @@ static dboard_base::sptr make_lf_tx(dboard_base::ctor_args_t const& args){ return dboard_base::sptr(new basic_tx(args, 32e6)); } -UHD_STATIC_BLOCK(reg_dboards){ +UHD_STATIC_BLOCK(reg_basic_and_lf_dboards){ dboard_manager::register_dboard(0x0000, &make_basic_tx, "Basic TX"); dboard_manager::register_dboard(0x0001, &make_basic_rx, "Basic RX", list_of("ab")("a")("b")); dboard_manager::register_dboard(0x000e, &make_lf_tx, "LF TX"); @@ -140,10 +140,6 @@ void basic_rx::rx_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of 1 empty string return; - case SUBDEV_PROP_ENABLED: - val = true; //always enabled - return; - case SUBDEV_PROP_QUADRATURE: val = (get_subdev_name() == "ab"); //only quadrature in ab mode return; @@ -171,9 +167,6 @@ void basic_rx::rx_set(const wax::obj &key_, const wax::obj &val){ ASSERT_THROW(val.as() == std::string("")); return; - case SUBDEV_PROP_ENABLED: - return; // it wont do you much good, but you can set it - case SUBDEV_PROP_FREQ: return; // it wont do you much good, but you can set it @@ -248,10 +241,6 @@ void basic_tx::tx_get(const wax::obj &key_, wax::obj &val){ val = prop_names_t(1, ""); //vector of 1 empty string return; - case SUBDEV_PROP_ENABLED: - val = true; //always enabled - return; - case SUBDEV_PROP_QUADRATURE: val = true; return; @@ -279,9 +268,6 @@ void basic_tx::tx_set(const wax::obj &key_, const wax::obj &val){ ASSERT_THROW(val.as() == std::string("")); return; - case SUBDEV_PROP_ENABLED: - return; // it wont do you much good, but you can set it - case SUBDEV_PROP_FREQ: return; // it wont do you much good, but you can set it diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp new file mode 100644 index 000000000..4fb036d38 --- /dev/null +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -0,0 +1,300 @@ +// +// 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 + +using namespace uhd; +using namespace uhd::usrp; +using namespace boost::assign; + +/*********************************************************************** + * The RFX series of dboards + **********************************************************************/ +class rfx_xcvr : public xcvr_dboard_base{ +public: + rfx_xcvr(ctor_args_t const& args, const freq_range_t &freq_range); + ~rfx_xcvr(void); + + void rx_get(const wax::obj &key, wax::obj &val); + void rx_set(const wax::obj &key, const wax::obj &val); + + void tx_get(const wax::obj &key, wax::obj &val); + void tx_set(const wax::obj &key, const wax::obj &val); + +private: + freq_range_t _freq_range; + double _lo_freq; + std::string _rx_ant; + float _rx_pga0_gain; + + void set_lo_freq(double freq); + void set_rx_ant(const std::string &ant); + void set_rx_pga0_gain(float gain); +}; + +/*********************************************************************** + * Register the RFX dboards + **********************************************************************/ +static dboard_base::sptr make_rfx_flex400(dboard_base::ctor_args_t const& args){ + return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(400e6, 500e6))); +} + +static dboard_base::sptr make_rfx_flex900(dboard_base::ctor_args_t const& args){ + return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(750e6, 1050e6))); +} + +static dboard_base::sptr make_rfx_flex1200(dboard_base::ctor_args_t const& args){ + return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1150e6, 1450e6))); +} + +static dboard_base::sptr make_rfx_flex1800(dboard_base::ctor_args_t const& args){ + return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(1500e6, 2100e6))); +} + +static dboard_base::sptr make_rfx_flex2400(dboard_base::ctor_args_t const& args){ + return dboard_base::sptr(new rfx_xcvr(args, freq_range_t(2300e6, 2900e6))); +} + +UHD_STATIC_BLOCK(reg_rfx_dboards){ + dboard_manager::register_dboard(0x0024, &make_rfx_flex400, "Flex 400 Rx MIMO B"); + dboard_manager::register_dboard(0x0028, &make_rfx_flex400, "Flex 400 Tx MIMO B"); + + dboard_manager::register_dboard(0x0025, &make_rfx_flex900, "Flex 900 Rx MIMO B"); + dboard_manager::register_dboard(0x0029, &make_rfx_flex900, "Flex 900 Tx MIMO B"); + + dboard_manager::register_dboard(0x0026, &make_rfx_flex1200, "Flex 1200 Rx MIMO B"); + dboard_manager::register_dboard(0x002a, &make_rfx_flex1200, "Flex 1200 Tx MIMO B"); + + dboard_manager::register_dboard(0x0034, &make_rfx_flex1800, "Flex 1800 Rx MIMO B"); + dboard_manager::register_dboard(0x0035, &make_rfx_flex1800, "Flex 1800 Tx MIMO B"); + + dboard_manager::register_dboard(0x0027, &make_rfx_flex2400, "Flex 2400 Rx MIMO B"); + dboard_manager::register_dboard(0x002b, &make_rfx_flex2400, "Flex 2400 Tx MIMO B"); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +rfx_xcvr::rfx_xcvr( + ctor_args_t const& args, + const freq_range_t &freq_range +) : xcvr_dboard_base(args){ + _freq_range = freq_range; + set_lo_freq((_freq_range.min + _freq_range.max)/2.0); + set_rx_ant("rx2"); + set_rx_pga0_gain(0); +} + +rfx_xcvr::~rfx_xcvr(void){ + /* NOP */ +} + +/*********************************************************************** + * Helper Methods + **********************************************************************/ +void rfx_xcvr::set_lo_freq(double freq){ + /* NOP */ +} + +void rfx_xcvr::set_rx_ant(const std::string &ant){ + /* NOP */ +} + +void rfx_xcvr::set_rx_pga0_gain(float gain){ + /* NOP */ +} + +/*********************************************************************** + * RX Get and Set + **********************************************************************/ +void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case SUBDEV_PROP_NAME: + val = dboard_id::to_string(get_rx_id()); + return; + + case SUBDEV_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case SUBDEV_PROP_GAIN: + val = _rx_pga0_gain; + return; + + case SUBDEV_PROP_GAIN_RANGE: + val = gain_range_t(0, 45, float(0.022)); + return; + + case SUBDEV_PROP_GAIN_NAMES: + val = prop_names_t(1, "pga0"); + return; + + case SUBDEV_PROP_FREQ: + val = _lo_freq; + return; + + case SUBDEV_PROP_FREQ_RANGE: + val = _freq_range; + return; + + case SUBDEV_PROP_ANTENNA: + val = _rx_ant; + return; + + case SUBDEV_PROP_ANTENNA_NAMES:{ + prop_names_t ants = list_of("tx/rx")("rx2"); + val = ants; + } + return; + + case SUBDEV_PROP_QUADRATURE: + val = true; + return; + + case SUBDEV_PROP_IQ_SWAPPED: + val = true; + return; + + case SUBDEV_PROP_SPECTRUM_INVERTED: + val = false; + return; + + case SUBDEV_PROP_LO_INTERFERES: + val = false; + return; + } +} + +void rfx_xcvr::rx_set(const wax::obj &key_, const wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + + case SUBDEV_PROP_GAIN: + ASSERT_THROW(name == "pga0"); + set_rx_pga0_gain(val.as()); + return; + + case SUBDEV_PROP_ANTENNA: + set_rx_ant(val.as()); + return; + + default: + throw std::runtime_error(str(boost::format( + "Error: trying to set read-only property on %s subdev" + ) % dboard_id::to_string(get_rx_id()))); + } +} + +/*********************************************************************** + * TX Get and Set + **********************************************************************/ +void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case SUBDEV_PROP_NAME: + val = dboard_id::to_string(get_tx_id()); + return; + + case SUBDEV_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case SUBDEV_PROP_GAIN: + val = float(0); + return; + + case SUBDEV_PROP_GAIN_RANGE: + val = gain_range_t(0, 0, 0); + return; + + case SUBDEV_PROP_GAIN_NAMES: + val = prop_names_t(); //empty + return; + + case SUBDEV_PROP_FREQ: + val = _lo_freq; + return; + + case SUBDEV_PROP_FREQ_RANGE: + val = _freq_range; + return; + + case SUBDEV_PROP_ANTENNA: + val = std::string("tx/rx"); + return; + + case SUBDEV_PROP_ANTENNA_NAMES: + val = prop_names_t(1, "tx/rx"); + return; + + case SUBDEV_PROP_QUADRATURE: + val = true; + return; + + case SUBDEV_PROP_IQ_SWAPPED: + val = false; + return; + + case SUBDEV_PROP_SPECTRUM_INVERTED: + val = false; + return; + + case SUBDEV_PROP_LO_INTERFERES: + val = true; + return; + } +} + +void rfx_xcvr::tx_set(const wax::obj &key_, const wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + + case SUBDEV_PROP_GAIN: + //no gains to set! + return; + + case SUBDEV_PROP_ANTENNA: + //its always set to tx/rx, so we only allow this value + ASSERT_THROW(val.as() == "tx/rx"); + return; + + default: + throw std::runtime_error(str(boost::format( + "Error: trying to set read-only property on %s subdev" + ) % dboard_id::to_string(get_tx_id()))); + } +} -- cgit v1.2.3 From e6151334096167d1d26609f7233105020af91f40 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 6 Apr 2010 19:05:02 -0700 Subject: added code for adf4360 chip --- host/lib/usrp/dboard/adf4360_regs.hpp | 185 +++++++++++++++++++++++++++++++ host/lib/usrp/dboard/db_rfx.cpp | 29 ++++- host/lib/usrp/dboard/gen_adf4360_regs.py | 168 ++++++++++++++++++++++++++++ 3 files changed, 380 insertions(+), 2 deletions(-) create mode 100644 host/lib/usrp/dboard/adf4360_regs.hpp create mode 100755 host/lib/usrp/dboard/gen_adf4360_regs.py diff --git a/host/lib/usrp/dboard/adf4360_regs.hpp b/host/lib/usrp/dboard/adf4360_regs.hpp new file mode 100644 index 000000000..309ff50e9 --- /dev/null +++ b/host/lib/usrp/dboard/adf4360_regs.hpp @@ -0,0 +1,185 @@ + + +/*********************************************************************** + * This file was generated by gen_adf4360_regs.py on Tue Apr 6 18:40:51 2010 + **********************************************************************/ + +#ifndef INCLUDED_ADF4360_REGS_HPP +#define INCLUDED_ADF4360_REGS_HPP + +#include + +struct adf4360_regs_t{ + enum core_power_level_t{ + CORE_POWER_LEVEL_5MA = 0, + CORE_POWER_LEVEL_10MA = 1, + CORE_POWER_LEVEL_15MA = 2, + CORE_POWER_LEVEL_20MA = 3 + } core_power_level; + enum counter_reset_t{ + COUNTER_RESET_NORMAL = 0, + COUNTER_RESET_RESET = 1 + } counter_reset; + enum muxout_control_t{ + MUXOUT_CONTROL_3STATE = 0, + MUXOUT_CONTROL_DLD = 1, + MUXOUT_CONTROL_NDIV = 2, + MUXOUT_CONTROL_DVDD = 3, + MUXOUT_CONTROL_RDIV = 4, + MUXOUT_CONTROL_NCHAN_OD_LD = 5, + MUXOUT_CONTROL_SDO = 6, + MUXOUT_CONTROL_DGND = 7 + } muxout_control; + enum phase_detector_polarity_t{ + PHASE_DETECTOR_POLARITY_NEG = 0, + PHASE_DETECTOR_POLARITY_POS = 1 + } phase_detector_polarity; + enum cp_three_state_t{ + CP_THREE_STATE_NORMAL = 0, + CP_THREE_STATE_3STATE = 1 + } cp_three_state; + enum cp_gain_0_t{ + CP_GAIN_0_SET1 = 0, + CP_GAIN_0_SET2 = 1 + } cp_gain_0; + enum mute_till_ld_t{ + MUTE_TILL_LD_DIS = 0, + MUTE_TILL_LD_ENB = 1 + } mute_till_ld; + enum output_power_level_t{ + OUTPUT_POWER_LEVEL_3_5MA = 0, + OUTPUT_POWER_LEVEL_5_0MA = 1, + OUTPUT_POWER_LEVEL_7_5MA = 2, + OUTPUT_POWER_LEVEL_11_0MA = 3 + } output_power_level; + enum current_setting1_t{ + CURRENT_SETTING1_0_31 = 0, + CURRENT_SETTING1_0_62 = 1, + CURRENT_SETTING1_0_93 = 2, + CURRENT_SETTING1_1_25 = 3, + CURRENT_SETTING1_1_56 = 4, + CURRENT_SETTING1_1_87 = 5, + CURRENT_SETTING1_2_18 = 6, + CURRENT_SETTING1_2_50 = 7 + } current_setting1; + enum current_setting2_t{ + CURRENT_SETTING2_0_31 = 0, + CURRENT_SETTING2_0_62 = 1, + CURRENT_SETTING2_0_93 = 2, + CURRENT_SETTING2_1_25 = 3, + CURRENT_SETTING2_1_56 = 4, + CURRENT_SETTING2_1_87 = 5, + CURRENT_SETTING2_2_18 = 6, + CURRENT_SETTING2_2_50 = 7 + } current_setting2; + enum power_down_t{ + POWER_DOWN_NORMAL_OP = 0, + POWER_DOWN_ASYNC_PD = 1, + POWER_DOWN_SYNC_PD = 3 + } power_down; + enum prescaler_value_t{ + PRESCALER_VALUE_8_9 = 0, + PRESCALER_VALUE_16_17 = 1, + PRESCALER_VALUE_32_33 = 2 + } prescaler_value; + boost::uint8_t a_counter; + boost::uint16_t b_counter; + enum cp_gain_1_t{ + CP_GAIN_1_SET1 = 0, + CP_GAIN_1_SET2 = 1 + } cp_gain_1; + enum divide_by_2_output_t{ + DIVIDE_BY_2_OUTPUT_FUND = 0, + DIVIDE_BY_2_OUTPUT_DIV2 = 1 + } divide_by_2_output; + enum divide_by_2_prescaler_t{ + DIVIDE_BY_2_PRESCALER_FUND = 0, + DIVIDE_BY_2_PRESCALER_DIV2 = 1 + } divide_by_2_prescaler; + boost::uint16_t r_counter; + enum ablpw_t{ + ABLPW_3_0NS = 0, + ABLPW_1_3NS = 1, + ABLPW_6_0NS = 2 + } ablpw; + enum lock_detect_precision_t{ + LOCK_DETECT_PRECISION_3CYCLES = 0, + LOCK_DETECT_PRECISION_5CYCLES = 1 + } lock_detect_precision; + boost::uint8_t test_mode_bit; + enum band_select_clock_div_t{ + BAND_SELECT_CLOCK_DIV_1 = 0, + BAND_SELECT_CLOCK_DIV_2 = 1, + BAND_SELECT_CLOCK_DIV_4 = 2, + BAND_SELECT_CLOCK_DIV_8 = 3 + } band_select_clock_div; + + adf4360_regs_t(void){ + core_power_level = CORE_POWER_LEVEL_5MA; + counter_reset = COUNTER_RESET_NORMAL; + muxout_control = MUXOUT_CONTROL_3STATE; + phase_detector_polarity = PHASE_DETECTOR_POLARITY_NEG; + cp_three_state = CP_THREE_STATE_NORMAL; + cp_gain_0 = CP_GAIN_0_SET1; + mute_till_ld = MUTE_TILL_LD_DIS; + output_power_level = OUTPUT_POWER_LEVEL_3_5MA; + current_setting1 = CURRENT_SETTING1_0_31; + current_setting2 = CURRENT_SETTING2_0_31; + power_down = POWER_DOWN_NORMAL_OP; + prescaler_value = PRESCALER_VALUE_8_9; + a_counter = 0; + b_counter = 0; + cp_gain_1 = CP_GAIN_1_SET1; + divide_by_2_output = DIVIDE_BY_2_OUTPUT_FUND; + divide_by_2_prescaler = DIVIDE_BY_2_PRESCALER_FUND; + r_counter = 0; + ablpw = ABLPW_3_0NS; + lock_detect_precision = LOCK_DETECT_PRECISION_3CYCLES; + test_mode_bit = 0; + band_select_clock_div = BAND_SELECT_CLOCK_DIV_1; + } + + enum addr_t{ + ADDR_CONTROL = 0, + ADDR_NCOUNTER = 2, + ADDR_RCOUNTER = 1 + }; + + boost::uint32_t get_reg(addr_t addr){ + boost::uint32_t reg = addr & 0x3; + switch(addr){ + case 0: + reg |= (boost::uint32_t(core_power_level) & 0x3) << 2; + reg |= (boost::uint32_t(counter_reset) & 0x1) << 4; + reg |= (boost::uint32_t(muxout_control) & 0x7) << 5; + reg |= (boost::uint32_t(phase_detector_polarity) & 0x1) << 8; + reg |= (boost::uint32_t(cp_three_state) & 0x1) << 9; + reg |= (boost::uint32_t(cp_gain_0) & 0x1) << 10; + reg |= (boost::uint32_t(mute_till_ld) & 0x1) << 11; + reg |= (boost::uint32_t(output_power_level) & 0x3) << 12; + reg |= (boost::uint32_t(current_setting1) & 0x7) << 14; + reg |= (boost::uint32_t(current_setting2) & 0x7) << 17; + reg |= (boost::uint32_t(power_down) & 0x3) << 20; + reg |= (boost::uint32_t(prescaler_value) & 0x3) << 22; + break; + case 1: + reg |= (boost::uint32_t(r_counter) & 0x3fff) << 2; + reg |= (boost::uint32_t(ablpw) & 0x3) << 16; + reg |= (boost::uint32_t(lock_detect_precision) & 0x1) << 18; + reg |= (boost::uint32_t(test_mode_bit) & 0x1) << 19; + reg |= (boost::uint32_t(band_select_clock_div) & 0x3) << 20; + break; + case 2: + reg |= (boost::uint32_t(a_counter) & 0x1f) << 2; + reg |= (boost::uint32_t(b_counter) & 0x1fff) << 8; + reg |= (boost::uint32_t(cp_gain_1) & 0x1) << 21; + reg |= (boost::uint32_t(divide_by_2_output) & 0x1) << 22; + reg |= (boost::uint32_t(divide_by_2_prescaler) & 0x1) << 23; + break; + } + return reg; + } +}; + +#endif /* INCLUDED_ADF4360_REGS_HPP */ + diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 4fb036d38..57ea03da5 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include "adf4360_regs.hpp" #include #include #include @@ -47,10 +48,12 @@ private: double _lo_freq; std::string _rx_ant; float _rx_pga0_gain; + adf4360_regs_t _adf4360_regs; void set_lo_freq(double freq); void set_rx_ant(const std::string &ant); void set_rx_pga0_gain(float gain); + void reload_adf4360_regs(void); }; /*********************************************************************** @@ -115,6 +118,7 @@ rfx_xcvr::~rfx_xcvr(void){ **********************************************************************/ void rfx_xcvr::set_lo_freq(double freq){ /* NOP */ + reload_adf4360_regs(); } void rfx_xcvr::set_rx_ant(const std::string &ant){ @@ -125,6 +129,27 @@ void rfx_xcvr::set_rx_pga0_gain(float gain){ /* NOP */ } +void rfx_xcvr::reload_adf4360_regs(void){ + std::vector addrs = list_of + (adf4360_regs_t::ADDR_CONTROL) + (adf4360_regs_t::ADDR_NCOUNTER) + (adf4360_regs_t::ADDR_RCOUNTER) + ; + BOOST_FOREACH(adf4360_regs_t::addr_t addr, addrs){ + boost::uint32_t reg = _adf4360_regs.get_reg(addr); + dboard_interface::byte_vector_t spi_bytes = list_of + ((reg >> 16) & 0xff) + ((reg >> 8) & 0xff) + ((reg >> 0) & 0xff) + ; + //this->get_interface.write_spi( + // dboard_interface::SPI_DEV_TX, + // dboard_interface::SPI_EDGE_FALL, + // spi_bytes + //); + } +} + /*********************************************************************** * RX Get and Set **********************************************************************/ @@ -184,7 +209,7 @@ void rfx_xcvr::rx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_LO_INTERFERES: + case SUBDEV_PROP_USE_LO_OFFSET: val = false; return; } @@ -270,7 +295,7 @@ void rfx_xcvr::tx_get(const wax::obj &key_, wax::obj &val){ val = false; return; - case SUBDEV_PROP_LO_INTERFERES: + case SUBDEV_PROP_USE_LO_OFFSET: val = true; return; } diff --git a/host/lib/usrp/dboard/gen_adf4360_regs.py b/host/lib/usrp/dboard/gen_adf4360_regs.py new file mode 100755 index 000000000..f16e59e2a --- /dev/null +++ b/host/lib/usrp/dboard/gen_adf4360_regs.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +# +# Copyright 2008,2009 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 asversion 3, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +import re +from Cheetah.Template import Template +def parse_tmpl(_tmpl_text, **kwargs): + return str(Template(_tmpl_text, kwargs)) + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_DATA_TMPL="""\ +######################################################################## +## address 0 +######################################################################## +core_power_level 0[2:3] 0 5ma, 10ma, 15ma, 20ma +counter_reset 0[4] 0 normal, reset +muxout_control 0[5:7] 0 3state, dld, ndiv, dvdd, rdiv, nchan_od_ld, sdo, dgnd +phase_detector_polarity 0[8] 0 neg, pos +cp_three_state 0[9] 0 normal, 3state +cp_gain_0 0[10] 0 set1, set2 +mute_till_ld 0[11] 0 dis, enb +output_power_level 0[12:13] 0 3_5ma, 5_0ma, 7_5ma, 11_0ma +#set $current_setting_enums = "0_31, 0_62, 0_93, 1_25, 1_56, 1_87, 2_18, 2_50" +current_setting1 0[14:16] 0 $current_setting_enums +current_setting2 0[17:19] 0 $current_setting_enums +power_down 0[20:21] 0 normal_op=0, async_pd=1, sync_pd=3 +prescaler_value 0[22:23] 0 8_9, 16_17, 32_33 +######################################################################## +## address 2 +######################################################################## +a_counter 2[2:6] 0 +b_counter 2[8:20] 0 +cp_gain_1 2[21] 0 set1, set2 +divide_by_2_output 2[22] 0 fund, div2 +divide_by_2_prescaler 2[23] 0 fund, div2 +######################################################################## +## address 1 +######################################################################## +r_counter 1[2:15] 0 +ablpw 1[16:17] 0 3_0ns, 1_3ns, 6_0ns +lock_detect_precision 1[18] 0 3cycles, 5cycles +test_mode_bit 1[19] 0 +band_select_clock_div 1[20:21] 0 1, 2, 4, 8 +""" + +######################################################################## +# Header and Source templates below +######################################################################## +HEADER_TEXT=""" +#import time + +/*********************************************************************** + * This file was generated by $file on $time.strftime("%c") + **********************************************************************/ + +\#ifndef INCLUDED_ADF4360_REGS_HPP +\#define INCLUDED_ADF4360_REGS_HPP + +\#include + +struct adf4360_regs_t{ +#for $reg in $regs + #if $reg.get_enums() + enum $(reg.get_name())_t{ + #for $i, $enum in enumerate($reg.get_enums()) + #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' + $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma + #end for + } $reg.get_name(); + #else + boost::$reg.get_stdint_type() $reg.get_name(); + #end if +#end for + + adf4360_regs_t(void){ +#for $reg in $regs + $reg.get_name() = $reg.get_default(); +#end for + } + + enum addr_t{ + ADDR_CONTROL = 0, + ADDR_NCOUNTER = 2, + ADDR_RCOUNTER = 1 + }; + + boost::uint32_t get_reg(addr_t addr){ + boost::uint32_t reg = addr & 0x3; + switch(addr){ + #for $addr in (0, 1, 2) + case $addr: + #for $reg in filter(lambda r: r.get_addr() == addr, $regs) + reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); + #end for + break; + #end for + } + return reg; + } +}; + +\#endif /* INCLUDED_ADF4360_REGS_HPP */ +""" + +class reg: + def __init__(self, reg_des): + x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des) + name, addr, bit_range, default, enums = x.groups() + + #store variables + self._name = name + self._addr = int(addr) + if ':' in bit_range: self._addr_spec = map(int, bit_range.split(':')) + else: self._addr_spec = int(bit_range), int(bit_range) + self._default = int(default) + + #extract enum + self._enums = list() + if enums: + enum_val = 0 + for enum_str in map(str.strip, enums.split(',')): + if '=' in enum_str: + enum_name, enum_val = enum_str.split('=') + enum_val = int(enum_val) + else: enum_name = enum_str + self._enums.append((enum_name, enum_val)) + enum_val += 1 + + def get_addr(self): return self._addr + def get_enums(self): return self._enums + def get_name(self): return self._name + def get_default(self): + for key, val in self.get_enums(): + if val == self._default: return str.upper('%s_%s'%(self.get_name(), key)) + return self._default + def get_stdint_type(self): + if self.get_bit_width() <= 8: return 'uint8_t' + if self.get_bit_width() <= 16: return 'uint16_t' + if self.get_bit_width() <= 32: return 'uint32_t' + if self.get_bit_width() <= 64: return 'uint64_t' + raise Exception, 'too damn big' + def get_shift(self): return self._addr_spec[0] + def get_mask(self): return hex(int('1'*self.get_bit_width(), 2)) + def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 + +if __name__ == '__main__': + regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) + print parse_tmpl(HEADER_TEXT, regs=regs, file=__file__) -- cgit v1.2.3 From b66a74ff1f629af714e26040b410d472c08be522 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 7 Apr 2010 00:46:42 -0700 Subject: Reworked the spi part of the dboard interface. It turns out to be more complicated. The integer type is better for holding the bits. The edges can be different, so the spi config hold 2 edge setting for mosi and miso. --- firmware/microblaze/apps/txrx.c | 25 ++------ host/include/uhd/usrp/dboard_interface.hpp | 100 ++++++++++++++++------------- host/lib/CMakeLists.txt | 1 - host/lib/usrp/dboard/db_rfx.cpp | 16 ++--- host/lib/usrp/dboard_interface.cpp | 53 --------------- host/lib/usrp/usrp2/dboard_interface.cpp | 95 ++++++++++++++++----------- host/lib/usrp/usrp2/fw_common.h | 7 +- 7 files changed, 128 insertions(+), 169 deletions(-) delete mode 100644 host/lib/usrp/dboard_interface.cpp diff --git a/firmware/microblaze/apps/txrx.c b/firmware/microblaze/apps/txrx.c index 69a04d771..561f3148f 100644 --- a/firmware/microblaze/apps/txrx.c +++ b/firmware/microblaze/apps/txrx.c @@ -253,29 +253,18 @@ void handle_udp_ctrl_packet( * SPI ******************************************************************/ case USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO:{ - uint8_t num_bytes = ctrl_data_in->data.spi_args.bytes; - - //load the data from the array of bytes - uint32_t data = 0x0; - for (size_t i = 0; i < num_bytes; i++){ - data = (data << 8) | ctrl_data_in->data.spi_args.data[i]; - } - //transact uint32_t result = spi_transact( (ctrl_data_in->data.spi_args.readback == 0)? SPI_TXONLY : SPI_TXRX, - ctrl_data_in->data.spi_args.dev, - data, num_bytes*8, //length in bits - (ctrl_data_in->data.spi_args.edge == USRP2_CLK_EDGE_RISE)? SPIF_PUSH_RISE : SPIF_PUSH_FALL | - (ctrl_data_in->data.spi_args.edge == USRP2_CLK_EDGE_RISE)? SPIF_LATCH_RISE : SPIF_LATCH_FALL + ctrl_data_in->data.spi_args.dev, //which device + ctrl_data_in->data.spi_args.data, //32 bit data + ctrl_data_in->data.spi_args.num_bits, //length in bits + (ctrl_data_in->data.spi_args.mosi_edge == USRP2_CLK_EDGE_RISE)? SPIF_PUSH_FALL : SPIF_PUSH_RISE | + (ctrl_data_in->data.spi_args.miso_edge == USRP2_CLK_EDGE_RISE)? SPIF_LATCH_RISE : SPIF_LATCH_FALL ); - //load the result into the array of bytes - for (size_t i = 0; i < num_bytes; i++){ - uint8_t byte_shift = num_bytes - i - 1; - ctrl_data_out.data.spi_args.data[i] = (result >> (byte_shift*8)) & 0xff; - } - ctrl_data_out.data.spi_args.bytes = num_bytes; + //load output + ctrl_data_out.data.spi_args.data = result; ctrl_data_out.id = USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE; } break; diff --git a/host/include/uhd/usrp/dboard_interface.hpp b/host/include/uhd/usrp/dboard_interface.hpp index b3bab131d..dab5a2281 100644 --- a/host/include/uhd/usrp/dboard_interface.hpp +++ b/host/include/uhd/usrp/dboard_interface.hpp @@ -42,16 +42,31 @@ public: UNIT_TYPE_TX = 't' }; - //tells the host which device to use - enum spi_dev_t{ - SPI_DEV_RX = 'r', - SPI_DEV_TX = 't' - }; - - //args for spi format - enum spi_edge_t{ - SPI_EDGE_RISE = 'r', - SPI_EDGE_FALL = 'f' + //spi configuration struct + struct UHD_API spi_config_t{ + /*! + * The edge type specifies when data is valid + * relative to the edge of the serial clock. + */ + enum edge_t{ + EDGE_RISE = 'r', + EDGE_FALL = 'f' + }; + + //! on what edge is the mosi data valid? + edge_t mosi_edge; + + //! on what edge is the miso data valid? + edge_t miso_edge; + + /*! + * Create a new spi config. + * \param edge the default edge for mosi and miso + */ + spi_config_t(edge_t edge = EDGE_RISE){ + mosi_edge = edge; + miso_edge = edge; + } }; //tell the host which gpio bank @@ -68,10 +83,6 @@ public: ATR_REG_FULL_DUPLEX = 'f' }; - //structors - dboard_interface(void); - virtual ~dboard_interface(void); - /*! * Write to an aux dac. * \param unit which unit rx or tx @@ -131,61 +142,60 @@ public: /*! * \brief Write data to SPI bus peripheral. * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write + * \param unit which unit, rx or tx + * \param config configuration settings + * \param data the bits to write LSB first + * \param num_bits the number of bits in data */ - void write_spi(spi_dev_t dev, spi_edge_t edge, const byte_vector_t &buf); + virtual void write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; /*! * \brief Read data to SPI bus peripheral. * - * \param dev which spi device - * \param edge args for format - * \param num_bytes number of bytes to read + * \param unit which unit, rx or tx + * \param config configuration settings + * \param num_bits the number of bits * \return the data that was read */ - byte_vector_t read_spi(spi_dev_t dev, spi_edge_t edge, size_t num_bytes); + virtual boost::uint32_t read_spi( + unit_type_t unit, + const spi_config_t &config, + size_t num_bits + ) = 0; /*! * \brief Read and write data to SPI bus peripheral. * The data read back will be the same length as the input buffer. * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write + * \param unit which unit, rx or tx + * \param config configuration settings + * \param data the bits to write LSB first + * \param num_bits the number of bits in data * \return the data that was read */ - byte_vector_t read_write_spi(spi_dev_t dev, spi_edge_t edge, const byte_vector_t &buf); + virtual boost::uint32_t read_write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ) = 0; /*! * \brief Get the rate of the rx dboard clock. - * \return the clock rate + * \return the clock rate in Hz */ virtual double get_rx_clock_rate(void) = 0; /*! * \brief Get the rate of the tx dboard clock. - * \return the clock rate + * \return the clock rate in Hz */ virtual double get_tx_clock_rate(void) = 0; - -private: - /*! - * \brief Read and write data to SPI bus peripheral. - * - * \param dev which spi device - * \param edge args for format - * \param buf the data to write - * \param readback false for write only - * \return the data that was read - */ - virtual byte_vector_t transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, - bool readback - ) = 0; }; }} //namespace diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index a4bf46f1a..f21a4a491 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -30,7 +30,6 @@ SET(libuhd_sources usrp/dboard/db_basic_and_lf.cpp usrp/dboard/db_rfx.cpp usrp/dboard_base.cpp - usrp/dboard_interface.cpp usrp/simple_usrp.cpp usrp/dboard_manager.cpp usrp/tune_helper.cpp diff --git a/host/lib/usrp/dboard/db_rfx.cpp b/host/lib/usrp/dboard/db_rfx.cpp index 57ea03da5..68fa51144 100644 --- a/host/lib/usrp/dboard/db_rfx.cpp +++ b/host/lib/usrp/dboard/db_rfx.cpp @@ -136,17 +136,11 @@ void rfx_xcvr::reload_adf4360_regs(void){ (adf4360_regs_t::ADDR_RCOUNTER) ; BOOST_FOREACH(adf4360_regs_t::addr_t addr, addrs){ - boost::uint32_t reg = _adf4360_regs.get_reg(addr); - dboard_interface::byte_vector_t spi_bytes = list_of - ((reg >> 16) & 0xff) - ((reg >> 8) & 0xff) - ((reg >> 0) & 0xff) - ; - //this->get_interface.write_spi( - // dboard_interface::SPI_DEV_TX, - // dboard_interface::SPI_EDGE_FALL, - // spi_bytes - //); + this->get_interface()->write_spi( + dboard_interface::UNIT_TYPE_TX, + dboard_interface::spi_config_t::EDGE_RISE, + _adf4360_regs.get_reg(addr), 24 + ); } } diff --git a/host/lib/usrp/dboard_interface.cpp b/host/lib/usrp/dboard_interface.cpp deleted file mode 100644 index c40c9b398..000000000 --- a/host/lib/usrp/dboard_interface.cpp +++ /dev/null @@ -1,53 +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 - -using namespace uhd::usrp; - -dboard_interface::dboard_interface(void){ - /* NOP */ -} - -dboard_interface::~dboard_interface(void){ - /* NOP */ -} - -void dboard_interface::write_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf -){ - transact_spi(dev, edge, buf, false); //dont readback -} - -dboard_interface::byte_vector_t dboard_interface::read_spi( - spi_dev_t dev, - spi_edge_t edge, - size_t num_bytes -){ - byte_vector_t buf(num_bytes, 0x00); //dummy data - return transact_spi(dev, edge, buf, true); //readback -} - -dboard_interface::byte_vector_t dboard_interface::read_write_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf -){ - return transact_spi(dev, edge, buf, true); //readback -} diff --git a/host/lib/usrp/usrp2/dboard_interface.cpp b/host/lib/usrp/usrp2/dboard_interface.cpp index 6dd756420..eee7c087a 100644 --- a/host/lib/usrp/usrp2/dboard_interface.cpp +++ b/host/lib/usrp/usrp2/dboard_interface.cpp @@ -42,9 +42,35 @@ public: double get_rx_clock_rate(void); double get_tx_clock_rate(void); + void write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ){ + transact_spi(unit, config, data, num_bits, false /*no rb*/); + } + + boost::uint32_t read_spi( + unit_type_t unit, + const spi_config_t &config, + size_t num_bits + ){ + return transact_spi(unit, config, 0, num_bits, true /*rb*/); + } + + boost::uint32_t read_write_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits + ){ + return transact_spi(unit, config, data, num_bits, true /*rb*/); + } + private: - byte_vector_t transact_spi( - spi_dev_t, spi_edge_t, const byte_vector_t &, bool + boost::uint32_t transact_spi( + unit_type_t, const spi_config_t &, boost::uint32_t, size_t, bool ); usrp2_impl *_impl; @@ -136,17 +162,17 @@ void usrp2_dboard_interface::set_atr_reg(gpio_bank_t bank, atr_reg_t atr, boost: * SPI **********************************************************************/ /*! - * Static function to convert a spi dev enum - * to an over-the-wire value for the usrp2 control. - * \param dev the dboard interface spi dev enum + * Static function to convert a unit type enum + * to an over-the-wire value for the spi device. + * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){ - switch(dev){ - case uhd::usrp::dboard_interface::SPI_DEV_TX: return SPI_SS_TX_DB; - case uhd::usrp::dboard_interface::SPI_DEV_RX: return SPI_SS_RX_DB; +static boost::uint8_t unit_to_otw_dev(dboard_interface::unit_type_t unit){ + switch(unit){ + case dboard_interface::UNIT_TYPE_TX: return SPI_SS_TX_DB; + case dboard_interface::UNIT_TYPE_RX: return SPI_SS_RX_DB; } - throw std::invalid_argument("unknown spi device type"); + throw std::invalid_argument("unknown unit type type"); } /*! @@ -155,43 +181,36 @@ static boost::uint8_t spi_dev_to_otw(dboard_interface::spi_dev_t dev){ * \param edge the dboard interface spi edge enum * \return an over the wire representation */ -static boost::uint8_t spi_edge_to_otw(dboard_interface::spi_edge_t edge){ +static boost::uint8_t spi_edge_to_otw(dboard_interface::spi_config_t::edge_t edge){ switch(edge){ - case uhd::usrp::dboard_interface::SPI_EDGE_RISE: return USRP2_CLK_EDGE_RISE; - case uhd::usrp::dboard_interface::SPI_EDGE_FALL: return USRP2_CLK_EDGE_FALL; + case dboard_interface::spi_config_t::EDGE_RISE: return USRP2_CLK_EDGE_RISE; + case dboard_interface::spi_config_t::EDGE_FALL: return USRP2_CLK_EDGE_FALL; } throw std::invalid_argument("unknown spi edge type"); } -dboard_interface::byte_vector_t usrp2_dboard_interface::transact_spi( - spi_dev_t dev, - spi_edge_t edge, - const byte_vector_t &buf, +boost::uint32_t usrp2_dboard_interface::transact_spi( + unit_type_t unit, + const spi_config_t &config, + boost::uint32_t data, + size_t num_bits, bool readback ){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_TRANSACT_ME_SOME_SPI_BRO); - out_data.data.spi_args.dev = spi_dev_to_otw(dev); - out_data.data.spi_args.edge = spi_edge_to_otw(edge); + out_data.data.spi_args.dev = unit_to_otw_dev(unit); + out_data.data.spi_args.miso_edge = spi_edge_to_otw(config.miso_edge); + out_data.data.spi_args.mosi_edge = spi_edge_to_otw(config.mosi_edge); out_data.data.spi_args.readback = (readback)? 1 : 0; - out_data.data.spi_args.bytes = buf.size(); - - //limitation of spi transaction size - ASSERT_THROW(buf.size() <= sizeof(out_data.data.spi_args.data)); - - //copy in the data - std::copy(buf.begin(), buf.end(), out_data.data.spi_args.data); + out_data.data.spi_args.num_bits = num_bits; + out_data.data.spi_args.data = htonl(data); //send and recv usrp2_ctrl_data_t in_data = _impl->ctrl_send_and_recv(out_data); ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_OMG_TRANSACTED_SPI_DUDE); - ASSERT_THROW(in_data.data.spi_args.bytes == buf.size()); - //copy out the data - byte_vector_t result(buf.size()); - std::copy(in_data.data.spi_args.data, in_data.data.spi_args.data + buf.size(), result.begin()); - return result; + return ntohl(out_data.data.spi_args.data); } /*********************************************************************** @@ -245,19 +264,19 @@ dboard_interface::byte_vector_t usrp2_dboard_interface::read_i2c(int i2c_addr, s * \param unit the dboard interface unit type enum * \return an over the wire representation */ -static boost::uint8_t spi_dev_to_otw(dboard_interface::unit_type_t unit){ +static boost::uint8_t unit_to_otw(dboard_interface::unit_type_t unit){ switch(unit){ - case uhd::usrp::dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX; - case uhd::usrp::dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX; + case dboard_interface::UNIT_TYPE_TX: return USRP2_DIR_TX; + case dboard_interface::UNIT_TYPE_RX: return USRP2_DIR_RX; } throw std::invalid_argument("unknown unit type type"); } -void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ +void usrp2_dboard_interface::write_aux_dac(unit_type_t unit, int which, int value){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_WRITE_THIS_TO_THE_AUX_DAC_BRO); - out_data.data.aux_args.dir = spi_dev_to_otw(unit); + out_data.data.aux_args.dir = unit_to_otw(unit); out_data.data.aux_args.which = which; out_data.data.aux_args.value = htonl(value); @@ -266,11 +285,11 @@ void usrp2_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, i ASSERT_THROW(htonl(in_data.id) == USRP2_CTRL_ID_DONE_WITH_THAT_AUX_DAC_DUDE); } -int usrp2_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ +int usrp2_dboard_interface::read_aux_adc(unit_type_t unit, int which){ //setup the out data usrp2_ctrl_data_t out_data; out_data.id = htonl(USRP2_CTRL_ID_READ_FROM_THIS_AUX_ADC_BRO); - out_data.data.aux_args.dir = spi_dev_to_otw(unit); + out_data.data.aux_args.dir = unit_to_otw(unit); out_data.data.aux_args.which = which; //send and recv diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h index 019f3b931..b600a2a70 100644 --- a/host/lib/usrp/usrp2/fw_common.h +++ b/host/lib/usrp/usrp2/fw_common.h @@ -110,10 +110,11 @@ typedef struct{ } dboard_ids; struct { _SINS_ uint8_t dev; - _SINS_ uint8_t edge; + _SINS_ uint8_t miso_edge; + _SINS_ uint8_t mosi_edge; _SINS_ uint8_t readback; - _SINS_ uint8_t bytes; - _SINS_ uint8_t data[sizeof(_SINS_ uint32_t)]; + _SINS_ uint32_t data; + _SINS_ uint8_t num_bits; } spi_args; struct { _SINS_ uint8_t addr; -- cgit v1.2.3 From d743784919b362d93e6408f05bdef6e543e3fc7e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 8 Apr 2010 10:57:16 -0700 Subject: converted timespec to use nanoseconds for fractional part --- host/CMakeLists.txt | 1 + host/examples/rx_timed_samples.cpp | 4 +- host/include/uhd/transport/vrt.hpp | 8 +++- host/include/uhd/types/metadata.hpp | 1 + host/include/uhd/types/time_spec.hpp | 36 +++++++++++------- host/lib/transport/gen_vrt.py | 10 +++-- host/lib/transport/vrt.cpp | 72 ++++++++++++++++++------------------ host/lib/types.cpp | 27 ++++++-------- host/lib/usrp/usrp2/dboard_impl.cpp | 1 + host/lib/usrp/usrp2/io_impl.cpp | 11 ++++-- host/lib/usrp/usrp2/mboard_impl.cpp | 8 +--- host/test/vrt_test.cpp | 12 +++--- 12 files changed, 105 insertions(+), 86 deletions(-) diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index d2889fe58..baae90861 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -145,6 +145,7 @@ ENDIF(DOXYGEN_FOUND) INSTALL(FILES ${CMAKE_SOURCE_DIR}/README ${CMAKE_SOURCE_DIR}/LICENSE + ${CMAKE_SOURCE_DIR}/AUTHORS DESTINATION ${PKG_DOC_DIR} ) diff --git a/host/examples/rx_timed_samples.cpp b/host/examples/rx_timed_samples.cpp index e971e9f6a..d49f7d182 100644 --- a/host/examples/rx_timed_samples.cpp +++ b/host/examples/rx_timed_samples.cpp @@ -86,8 +86,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ ); if (num_rx_samps == 0) continue; //wait for packets with contents - std::cout << boost::format("Got packet: %u samples, %u secs, %u ticks") - % num_rx_samps % md.time_spec.secs % md.time_spec.ticks << std::endl; + std::cout << boost::format("Got packet: %u samples, %u secs, %u nsecs") + % num_rx_samps % md.time_spec.secs % md.time_spec.nsecs << std::endl; num_acc_samps += num_rx_samps; } diff --git a/host/include/uhd/transport/vrt.hpp b/host/include/uhd/transport/vrt.hpp index 04945b347..137698e57 100644 --- a/host/include/uhd/transport/vrt.hpp +++ b/host/include/uhd/transport/vrt.hpp @@ -36,6 +36,7 @@ namespace vrt{ * \param num_payload_words32 the length of the payload * \param num_packet_words32 the length of the packet * \param packet_count the packet count sequence number + * \param tick_rate ticks per second used in time conversion */ UHD_API void pack( const tx_metadata_t &metadata, //input @@ -43,7 +44,8 @@ namespace vrt{ size_t &num_header_words32, //output size_t num_payload_words32, //input size_t &num_packet_words32, //output - size_t packet_count //input + size_t packet_count, //input + double tick_rate //input ); /*! @@ -54,6 +56,7 @@ namespace vrt{ * \param num_payload_words32 the length of the payload * \param num_packet_words32 the length of the packet * \param packet_count the packet count sequence number + * \param tick_rate ticks per second used in time conversion */ UHD_API void unpack( rx_metadata_t &metadata, //output @@ -61,7 +64,8 @@ namespace vrt{ size_t &num_header_words32, //output size_t &num_payload_words32, //output size_t num_packet_words32, //input - size_t &packet_count //output + size_t &packet_count, //output + double tick_rate //input ); } //namespace vrt diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp index 20f483bed..d93b38b50 100644 --- a/host/include/uhd/types/metadata.hpp +++ b/host/include/uhd/types/metadata.hpp @@ -19,6 +19,7 @@ #define INCLUDED_UHD_TYPES_METADATA_HPP #include +#include #include namespace uhd{ diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp index 8c8f2bc25..f06d27118 100644 --- a/host/include/uhd/types/time_spec.hpp +++ b/host/include/uhd/types/time_spec.hpp @@ -20,33 +20,43 @@ #include #include -#include namespace uhd{ /*! - * A time_spec_t holds a seconds and ticks time value. - * The temporal width of a tick depends on the device's clock rate. - * The time_spec_t can be used when setting the time on devices + * A time_spec_t holds a seconds and fractional seconds time value. + * The time_spec_t can be used when setting the time on devices, + * and for dealing with time stamped samples though the metadata. * and for controlling the start of streaming for applicable dsps. */ struct UHD_API time_spec_t{ + + //! whole seconds count boost::uint32_t secs; - boost::uint32_t ticks; + + //! fractional seconds count in nano-seconds + double nsecs; /*! - * Create a time_spec_t from seconds and ticks. - * \param new_secs the new seconds (default = 0) - * \param new_ticks the new ticks (default = 0) + * Convert the fractional nsecs to clock ticks. + * \param tick_rate the number of ticks per second + * \return the number of ticks in this time spec */ - time_spec_t(boost::uint32_t new_secs = 0, boost::uint32_t new_ticks = 0); + boost::uint32_t get_ticks(double tick_rate) const; /*! - * Create a time_spec_t from boost posix time. - * \param time fine-grained boost posix time - * \param tick_rate the rate of ticks per second + * Set the fractional nsecs from clock ticks. + * \param ticks the fractional seconds tick count + * \param tick_rate the number of ticks per second + */ + void set_ticks(boost::uint32_t ticks, double tick_rate); + + /*! + * Create a time_spec_t from seconds and ticks. + * \param new_secs the new seconds (default = 0) + * \param new_nsecs the new nano-seconds (default = 0) */ - time_spec_t(boost::posix_time::ptime time, double tick_rate); + time_spec_t(boost::uint32_t new_secs = 0, double new_nsecs = 0); }; diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py index 918de3ad7..bc6635d78 100755 --- a/host/lib/transport/gen_vrt.py +++ b/host/lib/transport/gen_vrt.py @@ -54,7 +54,8 @@ void vrt::pack( size_t &num_header_words32, //output size_t num_payload_words32, //input size_t &num_packet_words32, //output - size_t packet_count //input + size_t packet_count, //input + double tick_rate //input ){ boost::uint32_t vrt_hdr_flags; @@ -91,7 +92,7 @@ void vrt::pack( #if $pred & $tsf_p header_buff[$num_header_words] = htonl(0); #set $num_header_words += 1 - header_buff[$num_header_words] = htonl(metadata.time_spec.ticks); + header_buff[$num_header_words] = htonl(metadata.time_spec.get_ticks(tick_rate)); #set $num_header_words += 1 #set $flags |= (0x1 << 20); #end if @@ -127,7 +128,8 @@ void vrt::unpack( size_t &num_header_words32, //output size_t &num_payload_words32, //output size_t num_packet_words32, //input - size_t &packet_count //output + size_t &packet_count, //output + double tick_rate //input ){ //clear the metadata metadata = rx_metadata_t(); @@ -180,7 +182,7 @@ void vrt::unpack( #set $set_has_time_spec = True #end if #set $num_header_words += 1 - metadata.time_spec.ticks = ntohl(header_buff[$num_header_words]); + metadata.time_spec.set_ticks(ntohl(header_buff[$num_header_words]), tick_rate); #set $num_header_words += 1 #end if ########## Trailer ########## diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp index bebca5db9..78c3cf2cb 100644 --- a/host/lib/transport/vrt.cpp +++ b/host/lib/transport/vrt.cpp @@ -2,7 +2,7 @@ /*********************************************************************** - * This file was generated by ./gen_vrt.py on Fri Mar 26 15:33:00 2010 + * This file was generated by gen_vrt.py on 04/08/10 10:55:26 **********************************************************************/ #include @@ -18,7 +18,8 @@ void vrt::pack( size_t &num_header_words32, //output size_t num_payload_words32, //input size_t &num_packet_words32, //output - size_t packet_count //input + size_t packet_count, //input + double tick_rate //input ){ boost::uint32_t vrt_hdr_flags; @@ -85,7 +86,7 @@ void vrt::pack( break; case 8: header_buff[1] = htonl(0); - header_buff[2] = htonl(metadata.time_spec.ticks); + header_buff[2] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 3; num_packet_words32 = 3 + num_payload_words32; vrt_hdr_flags = 0x100000; @@ -93,7 +94,7 @@ void vrt::pack( case 9: header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 4 + num_payload_words32; vrt_hdr_flags = 0x10100000; @@ -102,7 +103,7 @@ void vrt::pack( header_buff[1] = htonl(0); header_buff[2] = htonl(0); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x8100000; @@ -112,7 +113,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(0); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0x18100000; @@ -120,7 +121,7 @@ void vrt::pack( case 12: header_buff[1] = htonl(metadata.time_spec.secs); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 4 + num_payload_words32; vrt_hdr_flags = 0xd00000; @@ -129,7 +130,7 @@ void vrt::pack( header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(metadata.time_spec.secs); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x10d00000; @@ -139,7 +140,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(metadata.time_spec.secs); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0x8d00000; @@ -150,7 +151,7 @@ void vrt::pack( header_buff[3] = htonl(0); header_buff[4] = htonl(metadata.time_spec.secs); header_buff[5] = htonl(0); - header_buff[6] = htonl(metadata.time_spec.ticks); + header_buff[6] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 7; num_packet_words32 = 7 + num_payload_words32; vrt_hdr_flags = 0x18d00000; @@ -213,7 +214,7 @@ void vrt::pack( break; case 24: header_buff[1] = htonl(0); - header_buff[2] = htonl(metadata.time_spec.ticks); + header_buff[2] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 3; num_packet_words32 = 4 + num_payload_words32; vrt_hdr_flags = 0x4100000; @@ -221,7 +222,7 @@ void vrt::pack( case 25: header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x14100000; @@ -230,7 +231,7 @@ void vrt::pack( header_buff[1] = htonl(0); header_buff[2] = htonl(0); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0xc100000; @@ -240,7 +241,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(0); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 7 + num_payload_words32; vrt_hdr_flags = 0x1c100000; @@ -248,7 +249,7 @@ void vrt::pack( case 28: header_buff[1] = htonl(metadata.time_spec.secs); header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.ticks); + header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 4; num_packet_words32 = 5 + num_payload_words32; vrt_hdr_flags = 0x4d00000; @@ -257,7 +258,7 @@ void vrt::pack( header_buff[1] = htonl(metadata.stream_id); header_buff[2] = htonl(metadata.time_spec.secs); header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.ticks); + header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 5; num_packet_words32 = 6 + num_payload_words32; vrt_hdr_flags = 0x14d00000; @@ -267,7 +268,7 @@ void vrt::pack( header_buff[2] = htonl(0); header_buff[3] = htonl(metadata.time_spec.secs); header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.ticks); + header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 6; num_packet_words32 = 7 + num_payload_words32; vrt_hdr_flags = 0xcd00000; @@ -278,7 +279,7 @@ void vrt::pack( header_buff[3] = htonl(0); header_buff[4] = htonl(metadata.time_spec.secs); header_buff[5] = htonl(0); - header_buff[6] = htonl(metadata.time_spec.ticks); + header_buff[6] = htonl(metadata.time_spec.get_ticks(tick_rate)); num_header_words32 = 7; num_packet_words32 = 8 + num_payload_words32; vrt_hdr_flags = 0x1cd00000; @@ -302,7 +303,8 @@ void vrt::unpack( size_t &num_header_words32, //output size_t &num_payload_words32, //output size_t num_packet_words32, //input - size_t &packet_count //output + size_t &packet_count, //output + double tick_rate //input ){ //clear the metadata metadata = rx_metadata_t(); @@ -376,7 +378,7 @@ void vrt::unpack( break; case 8: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[2]); + metadata.time_spec.set_ticks(ntohl(header_buff[2]), tick_rate); num_header_words32 = 3; num_payload_words32 = packet_words32 - 3; break; @@ -384,13 +386,13 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 4; break; case 10: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 5; break; @@ -398,14 +400,14 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 6; break; case 12: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[1]); - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 4; break; @@ -414,14 +416,14 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[2]); - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 5; break; case 14: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[3]); - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 6; break; @@ -430,7 +432,7 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[4]); - metadata.time_spec.ticks = ntohl(header_buff[6]); + metadata.time_spec.set_ticks(ntohl(header_buff[6]), tick_rate); num_header_words32 = 7; num_payload_words32 = packet_words32 - 7; break; @@ -484,7 +486,7 @@ void vrt::unpack( break; case 24: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[2]); + metadata.time_spec.set_ticks(ntohl(header_buff[2]), tick_rate); num_header_words32 = 3; num_payload_words32 = packet_words32 - 4; break; @@ -492,13 +494,13 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 5; break; case 26: metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 6; break; @@ -506,14 +508,14 @@ void vrt::unpack( metadata.has_stream_id = true; metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 7; break; case 28: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[1]); - metadata.time_spec.ticks = ntohl(header_buff[3]); + metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); num_header_words32 = 4; num_payload_words32 = packet_words32 - 5; break; @@ -522,14 +524,14 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[2]); - metadata.time_spec.ticks = ntohl(header_buff[4]); + metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); num_header_words32 = 5; num_payload_words32 = packet_words32 - 6; break; case 30: metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[3]); - metadata.time_spec.ticks = ntohl(header_buff[5]); + metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); num_header_words32 = 6; num_payload_words32 = packet_words32 - 7; break; @@ -538,7 +540,7 @@ void vrt::unpack( metadata.stream_id = ntohl(header_buff[1]); metadata.has_time_spec = true; metadata.time_spec.secs = ntohl(header_buff[4]); - metadata.time_spec.ticks = ntohl(header_buff[6]); + metadata.time_spec.set_ticks(ntohl(header_buff[6]), tick_rate); num_header_words32 = 7; num_payload_words32 = packet_words32 - 8; break; diff --git a/host/lib/types.cpp b/host/lib/types.cpp index 61a63b710..cd688e73d 100644 --- a/host/lib/types.cpp +++ b/host/lib/types.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -101,29 +102,26 @@ tx_metadata_t::tx_metadata_t(void){ /*********************************************************************** * time spec **********************************************************************/ -time_spec_t::time_spec_t(boost::uint32_t new_secs, boost::uint32_t new_ticks){ +time_spec_t::time_spec_t(boost::uint32_t new_secs, double new_nsecs){ secs = new_secs; - ticks = new_ticks; + nsecs = new_nsecs; } -static const boost::posix_time::ptime epoch(boost::gregorian::date(1970,1,1)); -static double time_tick_rate = double(boost::posix_time::time_duration::ticks_per_second()); +boost::uint32_t time_spec_t::get_ticks(double tick_rate) const{ + return boost::math::iround(nsecs*tick_rate*1e-9); +} -time_spec_t::time_spec_t(boost::posix_time::ptime time, double tick_rate){ - boost::posix_time::time_duration td = time - epoch; - secs = boost::uint32_t(td.total_seconds()); - double time_ticks_per_device_ticks = time_tick_rate/tick_rate; - ticks = boost::uint32_t(td.fractional_seconds()/time_ticks_per_device_ticks); +void time_spec_t::set_ticks(boost::uint32_t ticks, double tick_rate){ + nsecs = double(ticks)*1e9/tick_rate; } /*********************************************************************** * device addr **********************************************************************/ std::string device_addr_t::to_string(void) const{ - const device_addr_t &device_addr = *this; std::stringstream ss; - BOOST_FOREACH(std::string key, device_addr.keys()){ - ss << boost::format("%s: %s") % key % device_addr[key] << std::endl; + BOOST_FOREACH(std::string key, this->keys()){ + ss << boost::format("%s: %s") % key % (*this)[key] << std::endl; } return ss.str(); } @@ -137,9 +135,8 @@ static std::string trim(const std::string &in){ std::string device_addr_t::to_args_str(void) const{ std::string args_str; - const device_addr_t &device_addr = *this; - BOOST_FOREACH(const std::string &key, device_addr.keys()){ - args_str += key + pair_delim + device_addr[key] + arg_delim; + BOOST_FOREACH(const std::string &key, this->keys()){ + args_str += key + pair_delim + (*this)[key] + arg_delim; } return args_str; } diff --git a/host/lib/usrp/usrp2/dboard_impl.cpp b/host/lib/usrp/usrp2/dboard_impl.cpp index d1515f2d5..3ac805421 100644 --- a/host/lib/usrp/usrp2/dboard_impl.cpp +++ b/host/lib/usrp/usrp2/dboard_impl.cpp @@ -22,6 +22,7 @@ #include #include #include +#include using namespace uhd; using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp index a58e32619..eb6b5f7b9 100644 --- a/host/lib/usrp/usrp2/io_impl.cpp +++ b/host/lib/usrp/usrp2/io_impl.cpp @@ -15,9 +15,10 @@ // along with this program. If not, see . // -#include -#include #include "usrp2_impl.hpp" +#include +#include +#include using namespace uhd; using namespace uhd::usrp; @@ -144,7 +145,8 @@ void usrp2_impl::recv_raw(rx_metadata_t &metadata){ num_header_words32_out, //output num_payload_words32_out, //output num_packet_words32, //input - packet_count_out //output + packet_count_out, //output + get_master_clock_freq() ); }catch(const std::exception &e){ std::cerr << "bad vrt header: " << e.what() << std::endl; @@ -196,7 +198,8 @@ size_t usrp2_impl::send( num_header_words32, //output num_samps, //input num_packet_words32, //output - packet_count //input + packet_count, //input + get_master_clock_freq() ); boost::uint32_t *items = tx_mem + num_header_words32; //offset for data diff --git a/host/lib/usrp/usrp2/mboard_impl.cpp b/host/lib/usrp/usrp2/mboard_impl.cpp index 94ab88a6b..2fa2e5211 100644 --- a/host/lib/usrp/usrp2/mboard_impl.cpp +++ b/host/lib/usrp/usrp2/mboard_impl.cpp @@ -33,10 +33,6 @@ void usrp2_impl::mboard_init(void){ boost::bind(&usrp2_impl::mboard_get, this, _1, _2), boost::bind(&usrp2_impl::mboard_set, this, _1, _2) ); - - //set the time on the usrp2 as close as possible to the system utc time - boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time()); - set_time_spec(time_spec_t(now, get_master_clock_freq()), true); } void usrp2_impl::init_clock_config(void){ @@ -75,7 +71,7 @@ void usrp2_impl::update_clock_config(void){ void usrp2_impl::set_time_spec(const time_spec_t &time_spec, bool now){ //set ticks and seconds this->poke32(FR_TIME64_SECS, time_spec.secs); - this->poke32(FR_TIME64_TICKS, time_spec.ticks); + this->poke32(FR_TIME64_TICKS, time_spec.get_ticks(get_master_clock_freq())); //set the register to latch it all in boost::uint32_t imm_flags = (now)? FRF_TIME64_LATCH_NOW : FRF_TIME64_LATCH_NEXT_PPS; @@ -88,7 +84,7 @@ void usrp2_impl::issue_ddc_stream_cmd(const stream_cmd_t &stream_cmd){ out_data.id = htonl(USRP2_CTRL_ID_SEND_STREAM_COMMAND_FOR_ME_BRO); out_data.data.stream_cmd.now = (stream_cmd.stream_now)? 1 : 0; out_data.data.stream_cmd.secs = htonl(stream_cmd.time_spec.secs); - out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.ticks); + out_data.data.stream_cmd.ticks = htonl(stream_cmd.time_spec.get_ticks(get_master_clock_freq())); //set these to defaults, then change in the switch statement out_data.data.stream_cmd.continuous = 0; diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp index 40116e110..939a61eb4 100644 --- a/host/test/vrt_test.cpp +++ b/host/test/vrt_test.cpp @@ -36,7 +36,8 @@ static void pack_and_unpack( num_header_words32, //output num_payload_words32, //input num_packet_words32, //output - packet_count //input + packet_count, //input + 100e6 ); uhd::rx_metadata_t metadata_out; @@ -51,7 +52,8 @@ static void pack_and_unpack( num_header_words32_out, //output num_payload_words32_out, //output num_packet_words32, //input - packet_count_out //output + packet_count_out, //output + 100e6 ); //check the the unpacked metadata is the same @@ -65,7 +67,7 @@ static void pack_and_unpack( BOOST_CHECK_EQUAL(metadata.has_time_spec, metadata_out.has_time_spec); if (metadata.has_time_spec and metadata_out.has_time_spec){ BOOST_CHECK_EQUAL(metadata.time_spec.secs, metadata_out.time_spec.secs); - BOOST_CHECK_EQUAL(metadata.time_spec.ticks, metadata_out.time_spec.ticks); + BOOST_CHECK_EQUAL(metadata.time_spec.nsecs, metadata_out.time_spec.nsecs); } } @@ -85,7 +87,7 @@ BOOST_AUTO_TEST_CASE(test_with_time_spec){ uhd::tx_metadata_t metadata; metadata.has_time_spec = true; metadata.time_spec.secs = 7; - metadata.time_spec.ticks = 2000; + metadata.time_spec.nsecs = 2000; pack_and_unpack(metadata, 500, 3); } @@ -95,6 +97,6 @@ BOOST_AUTO_TEST_CASE(test_with_sid_and_time_spec){ metadata.stream_id = 2; metadata.has_time_spec = true; metadata.time_spec.secs = 5; - metadata.time_spec.ticks = 1000; + metadata.time_spec.nsecs = 1000; pack_and_unpack(metadata, 600, 4); } -- cgit v1.2.3 From fdd80e548dcda3e4ee0c022d7d04b5ba581c5ad9 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 9 Apr 2010 08:13:19 -0700 Subject: added python+cheetah build requirement, generating vrt.cpp --- host/CMakeLists.txt | 20 +- host/lib/CMakeLists.txt | 46 +++- host/lib/transport/gen_vrt.py | 3 +- host/lib/transport/vrt.cpp | 549 ------------------------------------------ 4 files changed, 57 insertions(+), 561 deletions(-) delete mode 100644 host/lib/transport/vrt.cpp diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index baae90861..6334b44ff 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -25,8 +25,8 @@ ENABLE_TESTING() SET(CPACK_PACKAGE_VERSION_MAJOR 0) SET(CPACK_PACKAGE_VERSION_MINOR 0) SET(CPACK_PACKAGE_VERSION_PATCH 0) -SET(CPACK_RESOURCE_FILE_README ${CMAKE_SOURCE_DIR}/README) -SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE) +SET(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_SOURCE_DIR}/README) +SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE) INCLUDE(CPack) #include after setting vars ######################################################################## @@ -42,18 +42,18 @@ MESSAGE(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}") ######################################################################## # Local Include Dir ######################################################################## -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) ######################################################################## # Optional Compiler Flags ######################################################################## INCLUDE(CheckCXXCompilerFlag) -FUNCTION(UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG flag have) +MACRO(UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG flag have) CHECK_CXX_COMPILER_FLAG(${flag} ${have}) IF(${have}) ADD_DEFINITIONS(${flag}) ENDIF(${have}) -ENDFUNCTION(UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG) +ENDMACRO(UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG) IF(UNIX) UHD_ADD_OPTIONAL_CXX_COMPILER_FLAG(-Wall HAVE_WALL) @@ -114,7 +114,7 @@ ADD_CUSTOM_TARGET(uninstall # Create Pkg Config File ######################################################################## CONFIGURE_FILE( - ${CMAKE_SOURCE_DIR}/uhd.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/uhd.pc.in ${CMAKE_CURRENT_BINARY_DIR}/uhd.pc @ONLY) @@ -131,7 +131,7 @@ INCLUDE(FindDoxygen) IF(DOXYGEN_FOUND) SET(CMAKE_CURRENT_BINARY_DIR_DOXYGEN ${CMAKE_CURRENT_BINARY_DIR}/doxygen) CONFIGURE_FILE( - ${CMAKE_SOURCE_DIR}/Doxyfile.in + ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY) ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR_DOXYGEN} @@ -143,9 +143,9 @@ IF(DOXYGEN_FOUND) ENDIF(DOXYGEN_FOUND) INSTALL(FILES - ${CMAKE_SOURCE_DIR}/README - ${CMAKE_SOURCE_DIR}/LICENSE - ${CMAKE_SOURCE_DIR}/AUTHORS + ${CMAKE_CURRENT_SOURCE_DIR}/README + ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE + ${CMAKE_CURRENT_SOURCE_DIR}/AUTHORS DESTINATION ${PKG_DOC_DIR} ) diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index f21a4a491..87e35f412 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -15,6 +15,33 @@ # along with this program. If not, see . # + +######################################################################## +# Setup Python +######################################################################## +INCLUDE(FindPythonInterp) + +MACRO(PYTHON_CHECK_MODULE module have) + MESSAGE(STATUS "Checking for python module ${module}") + EXECUTE_PROCESS( + COMMAND ${PYTHON_EXECUTABLE} -c "import ${module}" + RESULT_VARIABLE ${have} + ) + IF(${have} EQUAL 0) + MESSAGE(STATUS "Checking for python module ${module} - found") + SET(${have} TRUE) + ELSE(${have} EQUAL 0) + MESSAGE(STATUS "Checking for python module ${module} - not found") + SET(${have} FALSE) + ENDIF(${have} EQUAL 0) +ENDMACRO(PYTHON_CHECK_MODULE) + +PYTHON_CHECK_MODULE("Cheetah" HAVE_PYTHON_MODULE_CHEETAH) + +IF(NOT HAVE_PYTHON_MODULE_CHEETAH) + MESSAGE(FATAL_ERROR "Error: Cheetah Templates needed for pre-build generation.") +ENDIF(NOT HAVE_PYTHON_MODULE_CHEETAH) + ######################################################################## # Create a list of libuhd sources ######################################################################## @@ -26,7 +53,6 @@ SET(libuhd_sources wax.cpp transport/if_addrs.cpp transport/udp_simple.cpp - transport/vrt.cpp usrp/dboard/db_basic_and_lf.cpp usrp/dboard/db_rfx.cpp usrp/dboard_base.cpp @@ -41,6 +67,24 @@ SET(libuhd_sources usrp/usrp2/usrp2_impl.cpp ) +######################################################################## +# Generate Files +######################################################################## +MACRO(UHD_PYTHON_GEN_FILE pyfile outfile) + ADD_CUSTOM_COMMAND( + OUTPUT ${outfile} DEPENDS ${pyfile} + COMMAND ${PYTHON_EXECUTABLE} ${pyfile} ${outfile} + COMMENT "Calling ${pyfile} to generate ${outfile}" + ) +ENDMACRO(UHD_PYTHON_GEN_FILE) +UHD_PYTHON_GEN_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/transport/gen_vrt.py + ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp +) +LIST(APPEND libuhd_sources + ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp +) + ######################################################################## # Conditionally add the udp sources ######################################################################## diff --git a/host/lib/transport/gen_vrt.py b/host/lib/transport/gen_vrt.py index bc6635d78..0f961efc2 100755 --- a/host/lib/transport/gen_vrt.py +++ b/host/lib/transport/gen_vrt.py @@ -200,9 +200,10 @@ void vrt::unpack( } """ +import sys from Cheetah import Template def parse_str(_tmpl_text, **kwargs): return str(Template.Template(_tmpl_text, kwargs)) if __name__ == '__main__': from Cheetah import Template - print parse_str(TMPL_TEXT, file=__file__) + open(sys.argv[1], 'w').write(parse_str(TMPL_TEXT, file=__file__)) diff --git a/host/lib/transport/vrt.cpp b/host/lib/transport/vrt.cpp deleted file mode 100644 index 78c3cf2cb..000000000 --- a/host/lib/transport/vrt.cpp +++ /dev/null @@ -1,549 +0,0 @@ - - - -/*********************************************************************** - * This file was generated by gen_vrt.py on 04/08/10 10:55:26 - **********************************************************************/ - -#include -#include //endianness conversion -#include - -using namespace uhd; -using namespace uhd::transport; - -void vrt::pack( - const tx_metadata_t &metadata, //input - boost::uint32_t *header_buff, //output - size_t &num_header_words32, //output - size_t num_payload_words32, //input - size_t &num_packet_words32, //output - size_t packet_count, //input - double tick_rate //input -){ - boost::uint32_t vrt_hdr_flags; - - boost::uint8_t pred = 0; - if (metadata.has_stream_id) pred |= 0x1; - if (metadata.has_time_spec) pred |= 0xc; - - switch(pred){ - case 0: - num_header_words32 = 1; - num_packet_words32 = 1 + num_payload_words32; - vrt_hdr_flags = 0x0; - break; - case 1: - header_buff[1] = htonl(metadata.stream_id); - num_header_words32 = 2; - num_packet_words32 = 2 + num_payload_words32; - vrt_hdr_flags = 0x10000000; - break; - case 2: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - num_header_words32 = 3; - num_packet_words32 = 3 + num_payload_words32; - vrt_hdr_flags = 0x8000000; - break; - case 3: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - num_header_words32 = 4; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0x18000000; - break; - case 4: - header_buff[1] = htonl(metadata.time_spec.secs); - num_header_words32 = 2; - num_packet_words32 = 2 + num_payload_words32; - vrt_hdr_flags = 0xc00000; - break; - case 5: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(metadata.time_spec.secs); - num_header_words32 = 3; - num_packet_words32 = 3 + num_payload_words32; - vrt_hdr_flags = 0x10c00000; - break; - case 6: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.secs); - num_header_words32 = 4; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0x8c00000; - break; - case 7: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.secs); - num_header_words32 = 5; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0x18c00000; - break; - case 8: - header_buff[1] = htonl(0); - header_buff[2] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 3; - num_packet_words32 = 3 + num_payload_words32; - vrt_hdr_flags = 0x100000; - break; - case 9: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 4; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0x10100000; - break; - case 10: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 5; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0x8100000; - break; - case 11: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 6; - num_packet_words32 = 6 + num_payload_words32; - vrt_hdr_flags = 0x18100000; - break; - case 12: - header_buff[1] = htonl(metadata.time_spec.secs); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 4; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0xd00000; - break; - case 13: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(metadata.time_spec.secs); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 5; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0x10d00000; - break; - case 14: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.secs); - header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 6; - num_packet_words32 = 6 + num_payload_words32; - vrt_hdr_flags = 0x8d00000; - break; - case 15: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.secs); - header_buff[5] = htonl(0); - header_buff[6] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 7; - num_packet_words32 = 7 + num_payload_words32; - vrt_hdr_flags = 0x18d00000; - break; - case 16: - num_header_words32 = 1; - num_packet_words32 = 2 + num_payload_words32; - vrt_hdr_flags = 0x4000000; - break; - case 17: - header_buff[1] = htonl(metadata.stream_id); - num_header_words32 = 2; - num_packet_words32 = 3 + num_payload_words32; - vrt_hdr_flags = 0x14000000; - break; - case 18: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - num_header_words32 = 3; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0xc000000; - break; - case 19: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - num_header_words32 = 4; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0x1c000000; - break; - case 20: - header_buff[1] = htonl(metadata.time_spec.secs); - num_header_words32 = 2; - num_packet_words32 = 3 + num_payload_words32; - vrt_hdr_flags = 0x4c00000; - break; - case 21: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(metadata.time_spec.secs); - num_header_words32 = 3; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0x14c00000; - break; - case 22: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.secs); - num_header_words32 = 4; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0xcc00000; - break; - case 23: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.secs); - num_header_words32 = 5; - num_packet_words32 = 6 + num_payload_words32; - vrt_hdr_flags = 0x1cc00000; - break; - case 24: - header_buff[1] = htonl(0); - header_buff[2] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 3; - num_packet_words32 = 4 + num_payload_words32; - vrt_hdr_flags = 0x4100000; - break; - case 25: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 4; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0x14100000; - break; - case 26: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 5; - num_packet_words32 = 6 + num_payload_words32; - vrt_hdr_flags = 0xc100000; - break; - case 27: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 6; - num_packet_words32 = 7 + num_payload_words32; - vrt_hdr_flags = 0x1c100000; - break; - case 28: - header_buff[1] = htonl(metadata.time_spec.secs); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 4; - num_packet_words32 = 5 + num_payload_words32; - vrt_hdr_flags = 0x4d00000; - break; - case 29: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(metadata.time_spec.secs); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 5; - num_packet_words32 = 6 + num_payload_words32; - vrt_hdr_flags = 0x14d00000; - break; - case 30: - header_buff[1] = htonl(0); - header_buff[2] = htonl(0); - header_buff[3] = htonl(metadata.time_spec.secs); - header_buff[4] = htonl(0); - header_buff[5] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 6; - num_packet_words32 = 7 + num_payload_words32; - vrt_hdr_flags = 0xcd00000; - break; - case 31: - header_buff[1] = htonl(metadata.stream_id); - header_buff[2] = htonl(0); - header_buff[3] = htonl(0); - header_buff[4] = htonl(metadata.time_spec.secs); - header_buff[5] = htonl(0); - header_buff[6] = htonl(metadata.time_spec.get_ticks(tick_rate)); - num_header_words32 = 7; - num_packet_words32 = 8 + num_payload_words32; - vrt_hdr_flags = 0x1cd00000; - break; - } - - //set the burst flags - if (metadata.start_of_burst) vrt_hdr_flags |= 0x2000000; - if (metadata.end_of_burst) vrt_hdr_flags |= 0x1000000; - - //fill in complete header word - header_buff[0] = htonl(vrt_hdr_flags | - ((packet_count & 0xf) << 16) | - (num_packet_words32 & 0xffff) - ); -} - -void vrt::unpack( - rx_metadata_t &metadata, //output - const boost::uint32_t *header_buff, //input - size_t &num_header_words32, //output - size_t &num_payload_words32, //output - size_t num_packet_words32, //input - size_t &packet_count, //output - double tick_rate //input -){ - //clear the metadata - metadata = rx_metadata_t(); - - //extract vrt header - boost::uint32_t vrt_hdr_word = ntohl(header_buff[0]); - size_t packet_words32 = vrt_hdr_word & 0xffff; - packet_count = (vrt_hdr_word >> 16) & 0xf; - - //failure cases - if (packet_words32 == 0 or num_packet_words32 < packet_words32) - throw std::runtime_error("bad vrt header or packet fragment"); - if (vrt_hdr_word & (0x7 << 29)) - throw std::runtime_error("unsupported vrt packet type"); - - boost::uint8_t pred = 0; - if(vrt_hdr_word & 0x10000000) pred |= 0x1; - if(vrt_hdr_word & 0x8000000) pred |= 0x2; - if(vrt_hdr_word & 0xc00000) pred |= 0x4; - if(vrt_hdr_word & 0x300000) pred |= 0x8; - if(vrt_hdr_word & 0x4000000) pred |= 0x10; - - switch(pred){ - case 0: - num_header_words32 = 1; - num_payload_words32 = packet_words32 - 1; - break; - case 1: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - num_header_words32 = 2; - num_payload_words32 = packet_words32 - 2; - break; - case 2: - num_header_words32 = 3; - num_payload_words32 = packet_words32 - 3; - break; - case 3: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 4; - break; - case 4: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[1]); - num_header_words32 = 2; - num_payload_words32 = packet_words32 - 2; - break; - case 5: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[2]); - num_header_words32 = 3; - num_payload_words32 = packet_words32 - 3; - break; - case 6: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[3]); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 4; - break; - case 7: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[4]); - num_header_words32 = 5; - num_payload_words32 = packet_words32 - 5; - break; - case 8: - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[2]), tick_rate); - num_header_words32 = 3; - num_payload_words32 = packet_words32 - 3; - break; - case 9: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 4; - break; - case 10: - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); - num_header_words32 = 5; - num_payload_words32 = packet_words32 - 5; - break; - case 11: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); - num_header_words32 = 6; - num_payload_words32 = packet_words32 - 6; - break; - case 12: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[1]); - metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 4; - break; - case 13: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[2]); - metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); - num_header_words32 = 5; - num_payload_words32 = packet_words32 - 5; - break; - case 14: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[3]); - metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); - num_header_words32 = 6; - num_payload_words32 = packet_words32 - 6; - break; - case 15: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[4]); - metadata.time_spec.set_ticks(ntohl(header_buff[6]), tick_rate); - num_header_words32 = 7; - num_payload_words32 = packet_words32 - 7; - break; - case 16: - num_header_words32 = 1; - num_payload_words32 = packet_words32 - 2; - break; - case 17: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - num_header_words32 = 2; - num_payload_words32 = packet_words32 - 3; - break; - case 18: - num_header_words32 = 3; - num_payload_words32 = packet_words32 - 4; - break; - case 19: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 5; - break; - case 20: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[1]); - num_header_words32 = 2; - num_payload_words32 = packet_words32 - 3; - break; - case 21: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[2]); - num_header_words32 = 3; - num_payload_words32 = packet_words32 - 4; - break; - case 22: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[3]); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 5; - break; - case 23: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[4]); - num_header_words32 = 5; - num_payload_words32 = packet_words32 - 6; - break; - case 24: - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[2]), tick_rate); - num_header_words32 = 3; - num_payload_words32 = packet_words32 - 4; - break; - case 25: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 5; - break; - case 26: - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); - num_header_words32 = 5; - num_payload_words32 = packet_words32 - 6; - break; - case 27: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); - num_header_words32 = 6; - num_payload_words32 = packet_words32 - 7; - break; - case 28: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[1]); - metadata.time_spec.set_ticks(ntohl(header_buff[3]), tick_rate); - num_header_words32 = 4; - num_payload_words32 = packet_words32 - 5; - break; - case 29: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[2]); - metadata.time_spec.set_ticks(ntohl(header_buff[4]), tick_rate); - num_header_words32 = 5; - num_payload_words32 = packet_words32 - 6; - break; - case 30: - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[3]); - metadata.time_spec.set_ticks(ntohl(header_buff[5]), tick_rate); - num_header_words32 = 6; - num_payload_words32 = packet_words32 - 7; - break; - case 31: - metadata.has_stream_id = true; - metadata.stream_id = ntohl(header_buff[1]); - metadata.has_time_spec = true; - metadata.time_spec.secs = ntohl(header_buff[4]); - metadata.time_spec.set_ticks(ntohl(header_buff[6]), tick_rate); - num_header_words32 = 7; - num_payload_words32 = packet_words32 - 8; - break; - } -} - -- cgit v1.2.3 From 01cb9070c7b136d44d3de36d102d302d2f2de55f Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 9 Apr 2010 14:01:10 -0700 Subject: generate the register file, added lib include dir --- host/lib/CMakeLists.txt | 22 +++- host/lib/include/gen_adf4360_regs.py | 169 ++++++++++++++++++++++++++++ host/lib/usrp/dboard/adf4360_regs.hpp | 185 ------------------------------- host/lib/usrp/dboard/gen_adf4360_regs.py | 168 ---------------------------- 4 files changed, 186 insertions(+), 358 deletions(-) create mode 100755 host/lib/include/gen_adf4360_regs.py delete mode 100644 host/lib/usrp/dboard/adf4360_regs.hpp delete mode 100755 host/lib/usrp/dboard/gen_adf4360_regs.py diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 87e35f412..dc4986f8c 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -16,6 +16,14 @@ # +######################################################################## +# Library Includes (not part of API) +######################################################################## +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include #generated includes +) + ######################################################################## # Setup Python ######################################################################## @@ -70,19 +78,23 @@ SET(libuhd_sources ######################################################################## # Generate Files ######################################################################## -MACRO(UHD_PYTHON_GEN_FILE pyfile outfile) +MACRO(UHD_PYTHON_GEN_SOURCE_FILE pyfile outfile) ADD_CUSTOM_COMMAND( OUTPUT ${outfile} DEPENDS ${pyfile} COMMAND ${PYTHON_EXECUTABLE} ${pyfile} ${outfile} COMMENT "Calling ${pyfile} to generate ${outfile}" ) -ENDMACRO(UHD_PYTHON_GEN_FILE) -UHD_PYTHON_GEN_FILE( + LIST(APPEND libuhd_sources ${outfile}) +ENDMACRO(UHD_PYTHON_GEN_SOURCE_FILE) + +UHD_PYTHON_GEN_SOURCE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/transport/gen_vrt.py ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp ) -LIST(APPEND libuhd_sources - ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp + +UHD_PYTHON_GEN_SOURCE_FILE( + ${CMAKE_CURRENT_SOURCE_DIR}/include/gen_adf4360_regs.py + ${CMAKE_CURRENT_BINARY_DIR}/include/adf4360_regs.hpp ) ######################################################################## diff --git a/host/lib/include/gen_adf4360_regs.py b/host/lib/include/gen_adf4360_regs.py new file mode 100755 index 000000000..702c3060f --- /dev/null +++ b/host/lib/include/gen_adf4360_regs.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# Copyright 2008,2009 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 asversion 3, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +import re +import sys +from Cheetah.Template import Template +def parse_tmpl(_tmpl_text, **kwargs): + return str(Template(_tmpl_text, kwargs)) + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_DATA_TMPL="""\ +######################################################################## +## address 0 +######################################################################## +core_power_level 0[2:3] 0 5ma, 10ma, 15ma, 20ma +counter_reset 0[4] 0 normal, reset +muxout_control 0[5:7] 0 3state, dld, ndiv, dvdd, rdiv, nchan_od_ld, sdo, dgnd +phase_detector_polarity 0[8] 0 neg, pos +cp_three_state 0[9] 0 normal, 3state +cp_gain_0 0[10] 0 set1, set2 +mute_till_ld 0[11] 0 dis, enb +output_power_level 0[12:13] 0 3_5ma, 5_0ma, 7_5ma, 11_0ma +#set $current_setting_enums = "0_31, 0_62, 0_93, 1_25, 1_56, 1_87, 2_18, 2_50" +current_setting1 0[14:16] 0 $current_setting_enums +current_setting2 0[17:19] 0 $current_setting_enums +power_down 0[20:21] 0 normal_op=0, async_pd=1, sync_pd=3 +prescaler_value 0[22:23] 0 8_9, 16_17, 32_33 +######################################################################## +## address 2 +######################################################################## +a_counter 2[2:6] 0 +b_counter 2[8:20] 0 +cp_gain_1 2[21] 0 set1, set2 +divide_by_2_output 2[22] 0 fund, div2 +divide_by_2_prescaler 2[23] 0 fund, div2 +######################################################################## +## address 1 +######################################################################## +r_counter 1[2:15] 0 +ablpw 1[16:17] 0 3_0ns, 1_3ns, 6_0ns +lock_detect_precision 1[18] 0 3cycles, 5cycles +test_mode_bit 1[19] 0 +band_select_clock_div 1[20:21] 0 1, 2, 4, 8 +""" + +######################################################################## +# Header and Source templates below +######################################################################## +HEADER_TEXT=""" +#import time + +/*********************************************************************** + * This file was generated by $file on $time.strftime("%c") + **********************************************************************/ + +\#ifndef INCLUDED_ADF4360_REGS_HPP +\#define INCLUDED_ADF4360_REGS_HPP + +\#include + +struct adf4360_regs_t{ +#for $reg in $regs + #if $reg.get_enums() + enum $(reg.get_name())_t{ + #for $i, $enum in enumerate($reg.get_enums()) + #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' + $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma + #end for + } $reg.get_name(); + #else + boost::$reg.get_stdint_type() $reg.get_name(); + #end if +#end for + + adf4360_regs_t(void){ +#for $reg in $regs + $reg.get_name() = $reg.get_default(); +#end for + } + + enum addr_t{ + ADDR_CONTROL = 0, + ADDR_NCOUNTER = 2, + ADDR_RCOUNTER = 1 + }; + + boost::uint32_t get_reg(addr_t addr){ + boost::uint32_t reg = addr & 0x3; + switch(addr){ + #for $addr in (0, 1, 2) + case $addr: + #for $reg in filter(lambda r: r.get_addr() == addr, $regs) + reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); + #end for + break; + #end for + } + return reg; + } +}; + +\#endif /* INCLUDED_ADF4360_REGS_HPP */ +""" + +class reg: + def __init__(self, reg_des): + x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des) + name, addr, bit_range, default, enums = x.groups() + + #store variables + self._name = name + self._addr = int(addr) + if ':' in bit_range: self._addr_spec = map(int, bit_range.split(':')) + else: self._addr_spec = int(bit_range), int(bit_range) + self._default = int(default) + + #extract enum + self._enums = list() + if enums: + enum_val = 0 + for enum_str in map(str.strip, enums.split(',')): + if '=' in enum_str: + enum_name, enum_val = enum_str.split('=') + enum_val = int(enum_val) + else: enum_name = enum_str + self._enums.append((enum_name, enum_val)) + enum_val += 1 + + def get_addr(self): return self._addr + def get_enums(self): return self._enums + def get_name(self): return self._name + def get_default(self): + for key, val in self.get_enums(): + if val == self._default: return str.upper('%s_%s'%(self.get_name(), key)) + return self._default + def get_stdint_type(self): + if self.get_bit_width() <= 8: return 'uint8_t' + if self.get_bit_width() <= 16: return 'uint16_t' + if self.get_bit_width() <= 32: return 'uint32_t' + if self.get_bit_width() <= 64: return 'uint64_t' + raise Exception, 'too damn big' + def get_shift(self): return self._addr_spec[0] + def get_mask(self): return hex(int('1'*self.get_bit_width(), 2)) + def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 + +if __name__ == '__main__': + regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) + open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) diff --git a/host/lib/usrp/dboard/adf4360_regs.hpp b/host/lib/usrp/dboard/adf4360_regs.hpp deleted file mode 100644 index 309ff50e9..000000000 --- a/host/lib/usrp/dboard/adf4360_regs.hpp +++ /dev/null @@ -1,185 +0,0 @@ - - -/*********************************************************************** - * This file was generated by gen_adf4360_regs.py on Tue Apr 6 18:40:51 2010 - **********************************************************************/ - -#ifndef INCLUDED_ADF4360_REGS_HPP -#define INCLUDED_ADF4360_REGS_HPP - -#include - -struct adf4360_regs_t{ - enum core_power_level_t{ - CORE_POWER_LEVEL_5MA = 0, - CORE_POWER_LEVEL_10MA = 1, - CORE_POWER_LEVEL_15MA = 2, - CORE_POWER_LEVEL_20MA = 3 - } core_power_level; - enum counter_reset_t{ - COUNTER_RESET_NORMAL = 0, - COUNTER_RESET_RESET = 1 - } counter_reset; - enum muxout_control_t{ - MUXOUT_CONTROL_3STATE = 0, - MUXOUT_CONTROL_DLD = 1, - MUXOUT_CONTROL_NDIV = 2, - MUXOUT_CONTROL_DVDD = 3, - MUXOUT_CONTROL_RDIV = 4, - MUXOUT_CONTROL_NCHAN_OD_LD = 5, - MUXOUT_CONTROL_SDO = 6, - MUXOUT_CONTROL_DGND = 7 - } muxout_control; - enum phase_detector_polarity_t{ - PHASE_DETECTOR_POLARITY_NEG = 0, - PHASE_DETECTOR_POLARITY_POS = 1 - } phase_detector_polarity; - enum cp_three_state_t{ - CP_THREE_STATE_NORMAL = 0, - CP_THREE_STATE_3STATE = 1 - } cp_three_state; - enum cp_gain_0_t{ - CP_GAIN_0_SET1 = 0, - CP_GAIN_0_SET2 = 1 - } cp_gain_0; - enum mute_till_ld_t{ - MUTE_TILL_LD_DIS = 0, - MUTE_TILL_LD_ENB = 1 - } mute_till_ld; - enum output_power_level_t{ - OUTPUT_POWER_LEVEL_3_5MA = 0, - OUTPUT_POWER_LEVEL_5_0MA = 1, - OUTPUT_POWER_LEVEL_7_5MA = 2, - OUTPUT_POWER_LEVEL_11_0MA = 3 - } output_power_level; - enum current_setting1_t{ - CURRENT_SETTING1_0_31 = 0, - CURRENT_SETTING1_0_62 = 1, - CURRENT_SETTING1_0_93 = 2, - CURRENT_SETTING1_1_25 = 3, - CURRENT_SETTING1_1_56 = 4, - CURRENT_SETTING1_1_87 = 5, - CURRENT_SETTING1_2_18 = 6, - CURRENT_SETTING1_2_50 = 7 - } current_setting1; - enum current_setting2_t{ - CURRENT_SETTING2_0_31 = 0, - CURRENT_SETTING2_0_62 = 1, - CURRENT_SETTING2_0_93 = 2, - CURRENT_SETTING2_1_25 = 3, - CURRENT_SETTING2_1_56 = 4, - CURRENT_SETTING2_1_87 = 5, - CURRENT_SETTING2_2_18 = 6, - CURRENT_SETTING2_2_50 = 7 - } current_setting2; - enum power_down_t{ - POWER_DOWN_NORMAL_OP = 0, - POWER_DOWN_ASYNC_PD = 1, - POWER_DOWN_SYNC_PD = 3 - } power_down; - enum prescaler_value_t{ - PRESCALER_VALUE_8_9 = 0, - PRESCALER_VALUE_16_17 = 1, - PRESCALER_VALUE_32_33 = 2 - } prescaler_value; - boost::uint8_t a_counter; - boost::uint16_t b_counter; - enum cp_gain_1_t{ - CP_GAIN_1_SET1 = 0, - CP_GAIN_1_SET2 = 1 - } cp_gain_1; - enum divide_by_2_output_t{ - DIVIDE_BY_2_OUTPUT_FUND = 0, - DIVIDE_BY_2_OUTPUT_DIV2 = 1 - } divide_by_2_output; - enum divide_by_2_prescaler_t{ - DIVIDE_BY_2_PRESCALER_FUND = 0, - DIVIDE_BY_2_PRESCALER_DIV2 = 1 - } divide_by_2_prescaler; - boost::uint16_t r_counter; - enum ablpw_t{ - ABLPW_3_0NS = 0, - ABLPW_1_3NS = 1, - ABLPW_6_0NS = 2 - } ablpw; - enum lock_detect_precision_t{ - LOCK_DETECT_PRECISION_3CYCLES = 0, - LOCK_DETECT_PRECISION_5CYCLES = 1 - } lock_detect_precision; - boost::uint8_t test_mode_bit; - enum band_select_clock_div_t{ - BAND_SELECT_CLOCK_DIV_1 = 0, - BAND_SELECT_CLOCK_DIV_2 = 1, - BAND_SELECT_CLOCK_DIV_4 = 2, - BAND_SELECT_CLOCK_DIV_8 = 3 - } band_select_clock_div; - - adf4360_regs_t(void){ - core_power_level = CORE_POWER_LEVEL_5MA; - counter_reset = COUNTER_RESET_NORMAL; - muxout_control = MUXOUT_CONTROL_3STATE; - phase_detector_polarity = PHASE_DETECTOR_POLARITY_NEG; - cp_three_state = CP_THREE_STATE_NORMAL; - cp_gain_0 = CP_GAIN_0_SET1; - mute_till_ld = MUTE_TILL_LD_DIS; - output_power_level = OUTPUT_POWER_LEVEL_3_5MA; - current_setting1 = CURRENT_SETTING1_0_31; - current_setting2 = CURRENT_SETTING2_0_31; - power_down = POWER_DOWN_NORMAL_OP; - prescaler_value = PRESCALER_VALUE_8_9; - a_counter = 0; - b_counter = 0; - cp_gain_1 = CP_GAIN_1_SET1; - divide_by_2_output = DIVIDE_BY_2_OUTPUT_FUND; - divide_by_2_prescaler = DIVIDE_BY_2_PRESCALER_FUND; - r_counter = 0; - ablpw = ABLPW_3_0NS; - lock_detect_precision = LOCK_DETECT_PRECISION_3CYCLES; - test_mode_bit = 0; - band_select_clock_div = BAND_SELECT_CLOCK_DIV_1; - } - - enum addr_t{ - ADDR_CONTROL = 0, - ADDR_NCOUNTER = 2, - ADDR_RCOUNTER = 1 - }; - - boost::uint32_t get_reg(addr_t addr){ - boost::uint32_t reg = addr & 0x3; - switch(addr){ - case 0: - reg |= (boost::uint32_t(core_power_level) & 0x3) << 2; - reg |= (boost::uint32_t(counter_reset) & 0x1) << 4; - reg |= (boost::uint32_t(muxout_control) & 0x7) << 5; - reg |= (boost::uint32_t(phase_detector_polarity) & 0x1) << 8; - reg |= (boost::uint32_t(cp_three_state) & 0x1) << 9; - reg |= (boost::uint32_t(cp_gain_0) & 0x1) << 10; - reg |= (boost::uint32_t(mute_till_ld) & 0x1) << 11; - reg |= (boost::uint32_t(output_power_level) & 0x3) << 12; - reg |= (boost::uint32_t(current_setting1) & 0x7) << 14; - reg |= (boost::uint32_t(current_setting2) & 0x7) << 17; - reg |= (boost::uint32_t(power_down) & 0x3) << 20; - reg |= (boost::uint32_t(prescaler_value) & 0x3) << 22; - break; - case 1: - reg |= (boost::uint32_t(r_counter) & 0x3fff) << 2; - reg |= (boost::uint32_t(ablpw) & 0x3) << 16; - reg |= (boost::uint32_t(lock_detect_precision) & 0x1) << 18; - reg |= (boost::uint32_t(test_mode_bit) & 0x1) << 19; - reg |= (boost::uint32_t(band_select_clock_div) & 0x3) << 20; - break; - case 2: - reg |= (boost::uint32_t(a_counter) & 0x1f) << 2; - reg |= (boost::uint32_t(b_counter) & 0x1fff) << 8; - reg |= (boost::uint32_t(cp_gain_1) & 0x1) << 21; - reg |= (boost::uint32_t(divide_by_2_output) & 0x1) << 22; - reg |= (boost::uint32_t(divide_by_2_prescaler) & 0x1) << 23; - break; - } - return reg; - } -}; - -#endif /* INCLUDED_ADF4360_REGS_HPP */ - diff --git a/host/lib/usrp/dboard/gen_adf4360_regs.py b/host/lib/usrp/dboard/gen_adf4360_regs.py deleted file mode 100755 index f16e59e2a..000000000 --- a/host/lib/usrp/dboard/gen_adf4360_regs.py +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008,2009 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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 asversion 3, or (at your option) -# any later version. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. - -import re -from Cheetah.Template import Template -def parse_tmpl(_tmpl_text, **kwargs): - return str(Template(_tmpl_text, kwargs)) - -######################################################################## -# Template for raw text data describing registers -# name addr[bit range inclusive] default optional enums -######################################################################## -REGS_DATA_TMPL="""\ -######################################################################## -## address 0 -######################################################################## -core_power_level 0[2:3] 0 5ma, 10ma, 15ma, 20ma -counter_reset 0[4] 0 normal, reset -muxout_control 0[5:7] 0 3state, dld, ndiv, dvdd, rdiv, nchan_od_ld, sdo, dgnd -phase_detector_polarity 0[8] 0 neg, pos -cp_three_state 0[9] 0 normal, 3state -cp_gain_0 0[10] 0 set1, set2 -mute_till_ld 0[11] 0 dis, enb -output_power_level 0[12:13] 0 3_5ma, 5_0ma, 7_5ma, 11_0ma -#set $current_setting_enums = "0_31, 0_62, 0_93, 1_25, 1_56, 1_87, 2_18, 2_50" -current_setting1 0[14:16] 0 $current_setting_enums -current_setting2 0[17:19] 0 $current_setting_enums -power_down 0[20:21] 0 normal_op=0, async_pd=1, sync_pd=3 -prescaler_value 0[22:23] 0 8_9, 16_17, 32_33 -######################################################################## -## address 2 -######################################################################## -a_counter 2[2:6] 0 -b_counter 2[8:20] 0 -cp_gain_1 2[21] 0 set1, set2 -divide_by_2_output 2[22] 0 fund, div2 -divide_by_2_prescaler 2[23] 0 fund, div2 -######################################################################## -## address 1 -######################################################################## -r_counter 1[2:15] 0 -ablpw 1[16:17] 0 3_0ns, 1_3ns, 6_0ns -lock_detect_precision 1[18] 0 3cycles, 5cycles -test_mode_bit 1[19] 0 -band_select_clock_div 1[20:21] 0 1, 2, 4, 8 -""" - -######################################################################## -# Header and Source templates below -######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_ADF4360_REGS_HPP -\#define INCLUDED_ADF4360_REGS_HPP - -\#include - -struct adf4360_regs_t{ -#for $reg in $regs - #if $reg.get_enums() - enum $(reg.get_name())_t{ - #for $i, $enum in enumerate($reg.get_enums()) - #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' - $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma - #end for - } $reg.get_name(); - #else - boost::$reg.get_stdint_type() $reg.get_name(); - #end if -#end for - - adf4360_regs_t(void){ -#for $reg in $regs - $reg.get_name() = $reg.get_default(); -#end for - } - - enum addr_t{ - ADDR_CONTROL = 0, - ADDR_NCOUNTER = 2, - ADDR_RCOUNTER = 1 - }; - - boost::uint32_t get_reg(addr_t addr){ - boost::uint32_t reg = addr & 0x3; - switch(addr){ - #for $addr in (0, 1, 2) - case $addr: - #for $reg in filter(lambda r: r.get_addr() == addr, $regs) - reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); - #end for - break; - #end for - } - return reg; - } -}; - -\#endif /* INCLUDED_ADF4360_REGS_HPP */ -""" - -class reg: - def __init__(self, reg_des): - x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des) - name, addr, bit_range, default, enums = x.groups() - - #store variables - self._name = name - self._addr = int(addr) - if ':' in bit_range: self._addr_spec = map(int, bit_range.split(':')) - else: self._addr_spec = int(bit_range), int(bit_range) - self._default = int(default) - - #extract enum - self._enums = list() - if enums: - enum_val = 0 - for enum_str in map(str.strip, enums.split(',')): - if '=' in enum_str: - enum_name, enum_val = enum_str.split('=') - enum_val = int(enum_val) - else: enum_name = enum_str - self._enums.append((enum_name, enum_val)) - enum_val += 1 - - def get_addr(self): return self._addr - def get_enums(self): return self._enums - def get_name(self): return self._name - def get_default(self): - for key, val in self.get_enums(): - if val == self._default: return str.upper('%s_%s'%(self.get_name(), key)) - return self._default - def get_stdint_type(self): - if self.get_bit_width() <= 8: return 'uint8_t' - if self.get_bit_width() <= 16: return 'uint16_t' - if self.get_bit_width() <= 32: return 'uint32_t' - if self.get_bit_width() <= 64: return 'uint64_t' - raise Exception, 'too damn big' - def get_shift(self): return self._addr_spec[0] - def get_mask(self): return hex(int('1'*self.get_bit_width(), 2)) - def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 - -if __name__ == '__main__': - regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) - print parse_tmpl(HEADER_TEXT, regs=regs, file=__file__) -- cgit v1.2.3 From fa96b25b99dbd19ac0689cab9bcab84063287ad3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 10 Apr 2010 07:20:16 -0700 Subject: moved regs generator to ic reg maps folder, others will go there as well --- host/lib/CMakeLists.txt | 14 +-- host/lib/ic_reg_maps/gen_adf4360_regs.py | 169 +++++++++++++++++++++++++++++++ host/lib/include/gen_adf4360_regs.py | 169 ------------------------------- 3 files changed, 173 insertions(+), 179 deletions(-) create mode 100755 host/lib/ic_reg_maps/gen_adf4360_regs.py delete mode 100755 host/lib/include/gen_adf4360_regs.py diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index dc4986f8c..58afe099d 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -16,14 +16,6 @@ # -######################################################################## -# Library Includes (not part of API) -######################################################################## -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_BINARY_DIR}/include #generated includes -) - ######################################################################## # Setup Python ######################################################################## @@ -92,9 +84,11 @@ UHD_PYTHON_GEN_SOURCE_FILE( ${CMAKE_CURRENT_BINARY_DIR}/transport/vrt.cpp ) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps) + UHD_PYTHON_GEN_SOURCE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/include/gen_adf4360_regs.py - ${CMAKE_CURRENT_BINARY_DIR}/include/adf4360_regs.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/ic_reg_maps/gen_adf4360_regs.py + ${CMAKE_CURRENT_BINARY_DIR}/ic_reg_maps/adf4360_regs.hpp ) ######################################################################## diff --git a/host/lib/ic_reg_maps/gen_adf4360_regs.py b/host/lib/ic_reg_maps/gen_adf4360_regs.py new file mode 100755 index 000000000..702c3060f --- /dev/null +++ b/host/lib/ic_reg_maps/gen_adf4360_regs.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python +# +# Copyright 2008,2009 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 asversion 3, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +import re +import sys +from Cheetah.Template import Template +def parse_tmpl(_tmpl_text, **kwargs): + return str(Template(_tmpl_text, kwargs)) + +######################################################################## +# Template for raw text data describing registers +# name addr[bit range inclusive] default optional enums +######################################################################## +REGS_DATA_TMPL="""\ +######################################################################## +## address 0 +######################################################################## +core_power_level 0[2:3] 0 5ma, 10ma, 15ma, 20ma +counter_reset 0[4] 0 normal, reset +muxout_control 0[5:7] 0 3state, dld, ndiv, dvdd, rdiv, nchan_od_ld, sdo, dgnd +phase_detector_polarity 0[8] 0 neg, pos +cp_three_state 0[9] 0 normal, 3state +cp_gain_0 0[10] 0 set1, set2 +mute_till_ld 0[11] 0 dis, enb +output_power_level 0[12:13] 0 3_5ma, 5_0ma, 7_5ma, 11_0ma +#set $current_setting_enums = "0_31, 0_62, 0_93, 1_25, 1_56, 1_87, 2_18, 2_50" +current_setting1 0[14:16] 0 $current_setting_enums +current_setting2 0[17:19] 0 $current_setting_enums +power_down 0[20:21] 0 normal_op=0, async_pd=1, sync_pd=3 +prescaler_value 0[22:23] 0 8_9, 16_17, 32_33 +######################################################################## +## address 2 +######################################################################## +a_counter 2[2:6] 0 +b_counter 2[8:20] 0 +cp_gain_1 2[21] 0 set1, set2 +divide_by_2_output 2[22] 0 fund, div2 +divide_by_2_prescaler 2[23] 0 fund, div2 +######################################################################## +## address 1 +######################################################################## +r_counter 1[2:15] 0 +ablpw 1[16:17] 0 3_0ns, 1_3ns, 6_0ns +lock_detect_precision 1[18] 0 3cycles, 5cycles +test_mode_bit 1[19] 0 +band_select_clock_div 1[20:21] 0 1, 2, 4, 8 +""" + +######################################################################## +# Header and Source templates below +######################################################################## +HEADER_TEXT=""" +#import time + +/*********************************************************************** + * This file was generated by $file on $time.strftime("%c") + **********************************************************************/ + +\#ifndef INCLUDED_ADF4360_REGS_HPP +\#define INCLUDED_ADF4360_REGS_HPP + +\#include + +struct adf4360_regs_t{ +#for $reg in $regs + #if $reg.get_enums() + enum $(reg.get_name())_t{ + #for $i, $enum in enumerate($reg.get_enums()) + #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' + $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma + #end for + } $reg.get_name(); + #else + boost::$reg.get_stdint_type() $reg.get_name(); + #end if +#end for + + adf4360_regs_t(void){ +#for $reg in $regs + $reg.get_name() = $reg.get_default(); +#end for + } + + enum addr_t{ + ADDR_CONTROL = 0, + ADDR_NCOUNTER = 2, + ADDR_RCOUNTER = 1 + }; + + boost::uint32_t get_reg(addr_t addr){ + boost::uint32_t reg = addr & 0x3; + switch(addr){ + #for $addr in (0, 1, 2) + case $addr: + #for $reg in filter(lambda r: r.get_addr() == addr, $regs) + reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); + #end for + break; + #end for + } + return reg; + } +}; + +\#endif /* INCLUDED_ADF4360_REGS_HPP */ +""" + +class reg: + def __init__(self, reg_des): + x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des) + name, addr, bit_range, default, enums = x.groups() + + #store variables + self._name = name + self._addr = int(addr) + if ':' in bit_range: self._addr_spec = map(int, bit_range.split(':')) + else: self._addr_spec = int(bit_range), int(bit_range) + self._default = int(default) + + #extract enum + self._enums = list() + if enums: + enum_val = 0 + for enum_str in map(str.strip, enums.split(',')): + if '=' in enum_str: + enum_name, enum_val = enum_str.split('=') + enum_val = int(enum_val) + else: enum_name = enum_str + self._enums.append((enum_name, enum_val)) + enum_val += 1 + + def get_addr(self): return self._addr + def get_enums(self): return self._enums + def get_name(self): return self._name + def get_default(self): + for key, val in self.get_enums(): + if val == self._default: return str.upper('%s_%s'%(self.get_name(), key)) + return self._default + def get_stdint_type(self): + if self.get_bit_width() <= 8: return 'uint8_t' + if self.get_bit_width() <= 16: return 'uint16_t' + if self.get_bit_width() <= 32: return 'uint32_t' + if self.get_bit_width() <= 64: return 'uint64_t' + raise Exception, 'too damn big' + def get_shift(self): return self._addr_spec[0] + def get_mask(self): return hex(int('1'*self.get_bit_width(), 2)) + def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 + +if __name__ == '__main__': + regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) + open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) diff --git a/host/lib/include/gen_adf4360_regs.py b/host/lib/include/gen_adf4360_regs.py deleted file mode 100755 index 702c3060f..000000000 --- a/host/lib/include/gen_adf4360_regs.py +++ /dev/null @@ -1,169 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008,2009 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio 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 asversion 3, or (at your option) -# any later version. -# -# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. - -import re -import sys -from Cheetah.Template import Template -def parse_tmpl(_tmpl_text, **kwargs): - return str(Template(_tmpl_text, kwargs)) - -######################################################################## -# Template for raw text data describing registers -# name addr[bit range inclusive] default optional enums -######################################################################## -REGS_DATA_TMPL="""\ -######################################################################## -## address 0 -######################################################################## -core_power_level 0[2:3] 0 5ma, 10ma, 15ma, 20ma -counter_reset 0[4] 0 normal, reset -muxout_control 0[5:7] 0 3state, dld, ndiv, dvdd, rdiv, nchan_od_ld, sdo, dgnd -phase_detector_polarity 0[8] 0 neg, pos -cp_three_state 0[9] 0 normal, 3state -cp_gain_0 0[10] 0 set1, set2 -mute_till_ld 0[11] 0 dis, enb -output_power_level 0[12:13] 0 3_5ma, 5_0ma, 7_5ma, 11_0ma -#set $current_setting_enums = "0_31, 0_62, 0_93, 1_25, 1_56, 1_87, 2_18, 2_50" -current_setting1 0[14:16] 0 $current_setting_enums -current_setting2 0[17:19] 0 $current_setting_enums -power_down 0[20:21] 0 normal_op=0, async_pd=1, sync_pd=3 -prescaler_value 0[22:23] 0 8_9, 16_17, 32_33 -######################################################################## -## address 2 -######################################################################## -a_counter 2[2:6] 0 -b_counter 2[8:20] 0 -cp_gain_1 2[21] 0 set1, set2 -divide_by_2_output 2[22] 0 fund, div2 -divide_by_2_prescaler 2[23] 0 fund, div2 -######################################################################## -## address 1 -######################################################################## -r_counter 1[2:15] 0 -ablpw 1[16:17] 0 3_0ns, 1_3ns, 6_0ns -lock_detect_precision 1[18] 0 3cycles, 5cycles -test_mode_bit 1[19] 0 -band_select_clock_div 1[20:21] 0 1, 2, 4, 8 -""" - -######################################################################## -# Header and Source templates below -######################################################################## -HEADER_TEXT=""" -#import time - -/*********************************************************************** - * This file was generated by $file on $time.strftime("%c") - **********************************************************************/ - -\#ifndef INCLUDED_ADF4360_REGS_HPP -\#define INCLUDED_ADF4360_REGS_HPP - -\#include - -struct adf4360_regs_t{ -#for $reg in $regs - #if $reg.get_enums() - enum $(reg.get_name())_t{ - #for $i, $enum in enumerate($reg.get_enums()) - #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' - $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma - #end for - } $reg.get_name(); - #else - boost::$reg.get_stdint_type() $reg.get_name(); - #end if -#end for - - adf4360_regs_t(void){ -#for $reg in $regs - $reg.get_name() = $reg.get_default(); -#end for - } - - enum addr_t{ - ADDR_CONTROL = 0, - ADDR_NCOUNTER = 2, - ADDR_RCOUNTER = 1 - }; - - boost::uint32_t get_reg(addr_t addr){ - boost::uint32_t reg = addr & 0x3; - switch(addr){ - #for $addr in (0, 1, 2) - case $addr: - #for $reg in filter(lambda r: r.get_addr() == addr, $regs) - reg |= (boost::uint32_t($reg.get_name()) & $reg.get_mask()) << $reg.get_shift(); - #end for - break; - #end for - } - return reg; - } -}; - -\#endif /* INCLUDED_ADF4360_REGS_HPP */ -""" - -class reg: - def __init__(self, reg_des): - x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des) - name, addr, bit_range, default, enums = x.groups() - - #store variables - self._name = name - self._addr = int(addr) - if ':' in bit_range: self._addr_spec = map(int, bit_range.split(':')) - else: self._addr_spec = int(bit_range), int(bit_range) - self._default = int(default) - - #extract enum - self._enums = list() - if enums: - enum_val = 0 - for enum_str in map(str.strip, enums.split(',')): - if '=' in enum_str: - enum_name, enum_val = enum_str.split('=') - enum_val = int(enum_val) - else: enum_name = enum_str - self._enums.append((enum_name, enum_val)) - enum_val += 1 - - def get_addr(self): return self._addr - def get_enums(self): return self._enums - def get_name(self): return self._name - def get_default(self): - for key, val in self.get_enums(): - if val == self._default: return str.upper('%s_%s'%(self.get_name(), key)) - return self._default - def get_stdint_type(self): - if self.get_bit_width() <= 8: return 'uint8_t' - if self.get_bit_width() <= 16: return 'uint16_t' - if self.get_bit_width() <= 32: return 'uint32_t' - if self.get_bit_width() <= 64: return 'uint64_t' - raise Exception, 'too damn big' - def get_shift(self): return self._addr_spec[0] - def get_mask(self): return hex(int('1'*self.get_bit_width(), 2)) - def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 - -if __name__ == '__main__': - regs = map(reg, parse_tmpl(REGS_DATA_TMPL).splitlines()) - open(sys.argv[1], 'w').write(parse_tmpl(HEADER_TEXT, regs=regs, file=__file__)) -- cgit v1.2.3