From d33a6cab6646692e06ef34317f6c831ac9c91148 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 18:48:54 -0800 Subject: usrp_e: renamed directory to usrp_e100 to reflect product name --- host/lib/usrp/usrp_e100/dsp_impl.cpp | 192 +++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 host/lib/usrp/usrp_e100/dsp_impl.cpp (limited to 'host/lib/usrp/usrp_e100/dsp_impl.cpp') diff --git a/host/lib/usrp/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp new file mode 100644 index 000000000..97f173c1a --- /dev/null +++ b/host/lib/usrp/usrp_e100/dsp_impl.cpp @@ -0,0 +1,192 @@ +// +// 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 "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include +#include +#include +#include + +#define rint boost::math::iround + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * RX DDC Initialization + **********************************************************************/ +void usrp_e_impl::rx_ddc_init(void){ + _rx_ddc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) + ); + + //initial config and update + rx_ddc_set(DSP_PROP_FREQ_SHIFT, double(0)); + rx_ddc_set(DSP_PROP_HOST_RATE, double(64e6/10)); +} + +/*********************************************************************** + * RX DDC Get + **********************************************************************/ +void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + case DSP_PROP_NAME: + val = std::string("usrp-e ddc0"); + return; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case DSP_PROP_FREQ_SHIFT: + val = _ddc_freq; + return; + + case DSP_PROP_FREQ_SHIFT_NAMES: + val = prop_names_t(1, ""); + return; + + case DSP_PROP_CODEC_RATE: + val = _clock_ctrl->get_fpga_clock_rate(); + return; + + case DSP_PROP_HOST_RATE: + val = _clock_ctrl->get_fpga_clock_rate()/_ddc_decim; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * RX DDC Set + **********************************************************************/ +void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as(); + _iface->poke32(UE_REG_DSP_RX_FREQ, + dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) + ); + _ddc_freq = new_freq; //shadow + } + return; + + case DSP_PROP_HOST_RATE:{ + //set the decimation + _ddc_decim = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); + _iface->poke32(UE_REG_DSP_RX_DECIM_RATE, dsp_type1::calc_cic_filter_word(_ddc_decim)); + + //set the scaling + static const boost::int16_t default_rx_scale_iq = 1024; + _iface->poke32(UE_REG_DSP_RX_SCALE_IQ, + dsp_type1::calc_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq) + ); + } + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} + +/*********************************************************************** + * TX DUC Initialization + **********************************************************************/ +void usrp_e_impl::tx_duc_init(void){ + _tx_duc_proxy = wax_obj_proxy::make( + boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) + ); + + //initial config and update + tx_duc_set(DSP_PROP_FREQ_SHIFT, double(0)); + tx_duc_set(DSP_PROP_HOST_RATE, double(64e6/10)); +} + +/*********************************************************************** + * TX DUC Get + **********************************************************************/ +void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + case DSP_PROP_NAME: + val = std::string("usrp-e duc0"); + return; + + case DSP_PROP_OTHERS: + val = prop_names_t(); //empty + return; + + case DSP_PROP_FREQ_SHIFT: + val = _duc_freq; + return; + + case DSP_PROP_FREQ_SHIFT_NAMES: + val = prop_names_t(1, ""); + return; + + case DSP_PROP_CODEC_RATE: + val = _clock_ctrl->get_fpga_clock_rate(); + return; + + case DSP_PROP_HOST_RATE: + val = _clock_ctrl->get_fpga_clock_rate()/_duc_interp; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * TX DUC Set + **********************************************************************/ +void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + switch(key.as()){ + + case DSP_PROP_FREQ_SHIFT:{ + double new_freq = val.as(); + _iface->poke32(UE_REG_DSP_TX_FREQ, + dsp_type1::calc_cordic_word_and_update(new_freq, _clock_ctrl->get_fpga_clock_rate()) + ); + _duc_freq = new_freq; //shadow + } + return; + + case DSP_PROP_HOST_RATE:{ + _duc_interp = rint(_clock_ctrl->get_fpga_clock_rate()/val.as()); + + //set the interpolation + _iface->poke32(UE_REG_DSP_TX_INTERP_RATE, dsp_type1::calc_cic_filter_word(_duc_interp)); + + //set the scaling + _iface->poke32(UE_REG_DSP_TX_SCALE_IQ, dsp_type1::calc_iq_scale_word(_duc_interp)); + } + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } +} -- cgit v1.2.3 From 5f2c71383a2b5dd0f2f469f6ad8c4720358f2a12 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 9 Nov 2010 19:02:11 -0800 Subject: usrp-e100: renamed files and classes in usrp-e100 to e100 name --- host/lib/usrp/usrp_e100/CMakeLists.txt | 12 +- host/lib/usrp/usrp_e100/clock_ctrl.cpp | 14 +- host/lib/usrp/usrp_e100/clock_ctrl.hpp | 16 +- host/lib/usrp/usrp_e100/codec_ctrl.cpp | 38 ++-- host/lib/usrp/usrp_e100/codec_ctrl.hpp | 16 +- host/lib/usrp/usrp_e100/codec_impl.cpp | 24 +-- host/lib/usrp/usrp_e100/dboard_iface.cpp | 86 ++++----- host/lib/usrp/usrp_e100/dboard_impl.cpp | 24 +-- host/lib/usrp/usrp_e100/dsp_impl.cpp | 24 +-- host/lib/usrp/usrp_e100/fpga-downloader.cc | 2 +- host/lib/usrp/usrp_e100/io_impl.cpp | 38 ++-- host/lib/usrp/usrp_e100/mboard_impl.cpp | 14 +- host/lib/usrp/usrp_e100/usrp_e100_iface.cpp | 194 +++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_iface.hpp | 112 +++++++++++ host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 201 +++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_impl.hpp | 164 ++++++++++++++++ .../usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp | 215 +++++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e100_regs.hpp | 198 +++++++++++++++++++ host/lib/usrp/usrp_e100/usrp_e_iface.cpp | 194 ------------------- host/lib/usrp/usrp_e100/usrp_e_iface.hpp | 112 ----------- host/lib/usrp/usrp_e100/usrp_e_impl.cpp | 201 ------------------- host/lib/usrp/usrp_e100/usrp_e_impl.hpp | 164 ---------------- host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp | 215 --------------------- host/lib/usrp/usrp_e100/usrp_e_regs.hpp | 198 ------------------- 24 files changed, 1238 insertions(+), 1238 deletions(-) create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_iface.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_iface.hpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_impl.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_impl.hpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp create mode 100644 host/lib/usrp/usrp_e100/usrp_e100_regs.hpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_iface.cpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_iface.hpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_impl.cpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_impl.hpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp delete mode 100644 host/lib/usrp/usrp_e100/usrp_e_regs.hpp (limited to 'host/lib/usrp/usrp_e100/dsp_impl.cpp') diff --git a/host/lib/usrp/usrp_e100/CMakeLists.txt b/host/lib/usrp/usrp_e100/CMakeLists.txt index 17ef53152..97a3d5d9a 100644 --- a/host/lib/usrp/usrp_e100/CMakeLists.txt +++ b/host/lib/usrp/usrp_e100/CMakeLists.txt @@ -52,12 +52,12 @@ IF(ENABLE_USRP_E100) ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/fpga-downloader.cc ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/io_impl.cpp ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/mboard_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_impl.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_impl.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_iface.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_iface.hpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp - ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e_regs.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_impl.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_impl.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_iface.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_iface.hpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp + ${CMAKE_SOURCE_DIR}/lib/usrp/usrp_e100/usrp_e100_regs.hpp ) ELSE(ENABLE_USRP_E100) MESSAGE(STATUS " Skipping USRP-E100 support.") diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.cpp b/host/lib/usrp/usrp_e100/clock_ctrl.cpp index 9d4625305..e99560540 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.cpp @@ -19,7 +19,7 @@ #include "ad9522_regs.hpp" #include #include -#include "usrp_e_regs.hpp" //spi slave constants +#include "usrp_e100_regs.hpp" //spi slave constants #include #include #include @@ -58,9 +58,9 @@ static const size_t codec_clock_divider = size_t(master_clock_rate/64e6); /*********************************************************************** * Clock Control Implementation **********************************************************************/ -class usrp_e_clock_ctrl_impl : public usrp_e_clock_ctrl{ +class usrp_e100_clock_ctrl_impl : public usrp_e100_clock_ctrl{ public: - usrp_e_clock_ctrl_impl(usrp_e_iface::sptr iface){ + usrp_e100_clock_ctrl_impl(usrp_e100_iface::sptr iface){ _iface = iface; //init the clock gen registers @@ -137,7 +137,7 @@ public: this->enable_tx_dboard_clock(false); } - ~usrp_e_clock_ctrl_impl(void){ + ~usrp_e100_clock_ctrl_impl(void){ this->enable_rx_dboard_clock(false); this->enable_tx_dboard_clock(false); } @@ -210,7 +210,7 @@ public: } private: - usrp_e_iface::sptr _iface; + usrp_e100_iface::sptr _iface; ad9522_regs_t _ad9522_regs; void latch_regs(void){ @@ -232,6 +232,6 @@ private: /*********************************************************************** * Clock Control Make **********************************************************************/ -usrp_e_clock_ctrl::sptr usrp_e_clock_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new usrp_e_clock_ctrl_impl(iface)); +usrp_e100_clock_ctrl::sptr usrp_e100_clock_ctrl::make(usrp_e100_iface::sptr iface){ + return sptr(new usrp_e100_clock_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e100/clock_ctrl.hpp b/host/lib/usrp/usrp_e100/clock_ctrl.hpp index 3b5103ed1..0ae68728e 100644 --- a/host/lib/usrp/usrp_e100/clock_ctrl.hpp +++ b/host/lib/usrp/usrp_e100/clock_ctrl.hpp @@ -15,10 +15,10 @@ // along with this program. If not, see . // -#ifndef INCLUDED_USRP_E_CLOCK_CTRL_HPP -#define INCLUDED_USRP_E_CLOCK_CTRL_HPP +#ifndef INCLUDED_USRP_E100_CLOCK_CTRL_HPP +#define INCLUDED_USRP_E100_CLOCK_CTRL_HPP -#include "usrp_e_iface.hpp" +#include "usrp_e100_iface.hpp" #include #include #include @@ -28,16 +28,16 @@ * - Setup system clocks. * - Disable/enable clock lines. */ -class usrp_e_clock_ctrl : boost::noncopyable{ +class usrp_e100_clock_ctrl : boost::noncopyable{ public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; /*! * Make a new clock control object. - * \param iface the usrp_e iface object + * \param iface the usrp_e100 iface object * \return the clock control object */ - static sptr make(usrp_e_iface::sptr iface); + static sptr make(usrp_e100_iface::sptr iface); /*! * Get the rate of the fpga clock line. @@ -85,4 +85,4 @@ public: }; -#endif /* INCLUDED_USRP_E_CLOCK_CTRL_HPP */ +#endif /* INCLUDED_USRP_E100_CLOCK_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.cpp b/host/lib/usrp/usrp_e100/codec_ctrl.cpp index a728d7e46..e7fd9792e 100644 --- a/host/lib/usrp/usrp_e100/codec_ctrl.cpp +++ b/host/lib/usrp/usrp_e100/codec_ctrl.cpp @@ -23,7 +23,7 @@ #include #include #include -#include "usrp_e_regs.hpp" //spi slave constants +#include "usrp_e100_regs.hpp" //spi slave constants #include #include @@ -31,17 +31,17 @@ using namespace uhd; static const bool codec_debug = false; -const gain_range_t usrp_e_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); -const gain_range_t usrp_e_codec_ctrl::rx_pga_gain_range(0, 20, 1); +const gain_range_t usrp_e100_codec_ctrl::tx_pga_gain_range(-20, 0, float(0.1)); +const gain_range_t usrp_e100_codec_ctrl::rx_pga_gain_range(0, 20, 1); /*********************************************************************** * Codec Control Implementation **********************************************************************/ -class usrp_e_codec_ctrl_impl : public usrp_e_codec_ctrl{ +class usrp_e100_codec_ctrl_impl : public usrp_e100_codec_ctrl{ public: //structors - usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface); - ~usrp_e_codec_ctrl_impl(void); + usrp_e100_codec_ctrl_impl(usrp_e100_iface::sptr iface); + ~usrp_e100_codec_ctrl_impl(void); //aux adc and dac control float read_aux_adc(aux_adc_t which); @@ -54,7 +54,7 @@ public: float get_rx_pga_gain(char); private: - usrp_e_iface::sptr _iface; + usrp_e100_iface::sptr _iface; ad9862_regs_t _ad9862_regs; aux_adc_t _last_aux_adc_a, _last_aux_adc_b; void send_reg(boost::uint8_t addr); @@ -64,7 +64,7 @@ private: /*********************************************************************** * Codec Control Structors **********************************************************************/ -usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ +usrp_e100_codec_ctrl_impl::usrp_e100_codec_ctrl_impl(usrp_e100_iface::sptr iface){ _iface = iface; //soft reset @@ -115,7 +115,7 @@ usrp_e_codec_ctrl_impl::usrp_e_codec_ctrl_impl(usrp_e_iface::sptr iface){ this->send_reg(34); } -usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ +usrp_e100_codec_ctrl_impl::~usrp_e100_codec_ctrl_impl(void){ //set aux dacs to zero this->write_aux_dac(AUX_DAC_A, 0); this->write_aux_dac(AUX_DAC_B, 0); @@ -135,19 +135,19 @@ usrp_e_codec_ctrl_impl::~usrp_e_codec_ctrl_impl(void){ **********************************************************************/ static const int mtpgw = 255; //maximum tx pga gain word -void usrp_e_codec_ctrl_impl::set_tx_pga_gain(float gain){ +void usrp_e100_codec_ctrl_impl::set_tx_pga_gain(float gain){ int gain_word = int(mtpgw*(gain - tx_pga_gain_range.min)/(tx_pga_gain_range.max - tx_pga_gain_range.min)); _ad9862_regs.tx_pga_gain = std::clip(gain_word, 0, mtpgw); this->send_reg(16); } -float usrp_e_codec_ctrl_impl::get_tx_pga_gain(void){ +float usrp_e100_codec_ctrl_impl::get_tx_pga_gain(void){ return (_ad9862_regs.tx_pga_gain*(tx_pga_gain_range.max - tx_pga_gain_range.min)/mtpgw) + tx_pga_gain_range.min; } static const int mrpgw = 0x14; //maximum rx pga gain word -void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ +void usrp_e100_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ int gain_word = int(mrpgw*(gain - rx_pga_gain_range.min)/(rx_pga_gain_range.max - rx_pga_gain_range.min)); gain_word = std::clip(gain_word, 0, mrpgw); switch(which){ @@ -163,7 +163,7 @@ void usrp_e_codec_ctrl_impl::set_rx_pga_gain(float gain, char which){ } } -float usrp_e_codec_ctrl_impl::get_rx_pga_gain(char which){ +float usrp_e100_codec_ctrl_impl::get_rx_pga_gain(char which){ int gain_word; switch(which){ case 'A': gain_word = _ad9862_regs.rx_pga_a; break; @@ -180,7 +180,7 @@ static float aux_adc_to_volts(boost::uint8_t high, boost::uint8_t low){ return float((boost::uint16_t(high) << 2) | low)*3.3/0x3ff; } -float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ +float usrp_e100_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ //check to see if the switch needs to be set bool write_switch = false; switch(which){ @@ -233,7 +233,7 @@ float usrp_e_codec_ctrl_impl::read_aux_adc(aux_adc_t which){ /*********************************************************************** * Codec Control AUX DAC Methods **********************************************************************/ -void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ +void usrp_e100_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ //special case for aux dac d (aka sigma delta word) if (which == AUX_DAC_D){ boost::uint16_t dac_word = std::clip(boost::math::iround(volts*0xfff/3.3), 0, 0xfff); @@ -266,7 +266,7 @@ void usrp_e_codec_ctrl_impl::write_aux_dac(aux_dac_t which, float volts){ /*********************************************************************** * Codec Control SPI Methods **********************************************************************/ -void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ +void usrp_e100_codec_ctrl_impl::send_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_write_reg(addr); if (codec_debug) std::cout << "codec control write reg: " << std::hex << reg << std::endl; _iface->transact_spi( @@ -276,7 +276,7 @@ void usrp_e_codec_ctrl_impl::send_reg(boost::uint8_t addr){ ); } -void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ +void usrp_e100_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ boost::uint32_t reg = _ad9862_regs.get_read_reg(addr); if (codec_debug) std::cout << "codec control read reg: " << std::hex << reg << std::endl; boost::uint32_t ret = _iface->transact_spi( @@ -291,6 +291,6 @@ void usrp_e_codec_ctrl_impl::recv_reg(boost::uint8_t addr){ /*********************************************************************** * Codec Control Make **********************************************************************/ -usrp_e_codec_ctrl::sptr usrp_e_codec_ctrl::make(usrp_e_iface::sptr iface){ - return sptr(new usrp_e_codec_ctrl_impl(iface)); +usrp_e100_codec_ctrl::sptr usrp_e100_codec_ctrl::make(usrp_e100_iface::sptr iface){ + return sptr(new usrp_e100_codec_ctrl_impl(iface)); } diff --git a/host/lib/usrp/usrp_e100/codec_ctrl.hpp b/host/lib/usrp/usrp_e100/codec_ctrl.hpp index 87b6ff951..74ce9bd9a 100644 --- a/host/lib/usrp/usrp_e100/codec_ctrl.hpp +++ b/host/lib/usrp/usrp_e100/codec_ctrl.hpp @@ -15,10 +15,10 @@ // along with this program. If not, see . // -#ifndef INCLUDED_USRP_E_CODEC_CTRL_HPP -#define INCLUDED_USRP_E_CODEC_CTRL_HPP +#ifndef INCLUDED_USRP_E100_CODEC_CTRL_HPP +#define INCLUDED_USRP_E100_CODEC_CTRL_HPP -#include "usrp_e_iface.hpp" +#include "usrp_e100_iface.hpp" #include #include #include @@ -28,19 +28,19 @@ * - Init/power down codec. * - Read aux adc, write aux dac. */ -class usrp_e_codec_ctrl : boost::noncopyable{ +class usrp_e100_codec_ctrl : boost::noncopyable{ public: - typedef boost::shared_ptr sptr; + typedef boost::shared_ptr sptr; static const uhd::gain_range_t tx_pga_gain_range; static const uhd::gain_range_t rx_pga_gain_range; /*! * Make a new codec control object. - * \param iface the usrp_e iface object + * \param iface the usrp_e100 iface object * \return the codec control object */ - static sptr make(usrp_e_iface::sptr iface); + static sptr make(usrp_e100_iface::sptr iface); //! aux adc identifier constants enum aux_adc_t{ @@ -87,4 +87,4 @@ public: virtual float get_rx_pga_gain(char which) = 0; }; -#endif /* INCLUDED_USRP_E_CODEC_CTRL_HPP */ +#endif /* INCLUDED_USRP_E100_CODEC_CTRL_HPP */ diff --git a/host/lib/usrp/usrp_e100/codec_impl.cpp b/host/lib/usrp/usrp_e100/codec_impl.cpp index 696fb37ec..6fd44bad3 100644 --- a/host/lib/usrp/usrp_e100/codec_impl.cpp +++ b/host/lib/usrp/usrp_e100/codec_impl.cpp @@ -15,7 +15,7 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" +#include "usrp_e100_impl.hpp" #include #include #include @@ -26,15 +26,15 @@ using namespace uhd::usrp; /*********************************************************************** * Helper Methods **********************************************************************/ -void usrp_e_impl::codec_init(void){ +void usrp_e100_impl::codec_init(void){ //make proxies _rx_codec_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_codec_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_codec_set, this, _1, _2) + boost::bind(&usrp_e100_impl::rx_codec_get, this, _1, _2), + boost::bind(&usrp_e100_impl::rx_codec_set, this, _1, _2) ); _tx_codec_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_codec_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_codec_set, this, _1, _2) + boost::bind(&usrp_e100_impl::tx_codec_get, this, _1, _2), + boost::bind(&usrp_e100_impl::tx_codec_set, this, _1, _2) ); } @@ -43,7 +43,7 @@ void usrp_e_impl::codec_init(void){ **********************************************************************/ static const std::string ad9862_pga_gain_name = "ad9862 pga"; -void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -62,7 +62,7 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ case CODEC_PROP_GAIN_RANGE: UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = usrp_e_codec_ctrl::rx_pga_gain_range; + val = usrp_e100_codec_ctrl::rx_pga_gain_range; return; case CODEC_PROP_GAIN_I: @@ -79,7 +79,7 @@ void usrp_e_impl::rx_codec_get(const wax::obj &key_, wax::obj &val){ } } -void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key @@ -101,7 +101,7 @@ void usrp_e_impl::rx_codec_set(const wax::obj &key_, const wax::obj &val){ /*********************************************************************** * TX Codec Properties **********************************************************************/ -void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -120,7 +120,7 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ case CODEC_PROP_GAIN_RANGE: UHD_ASSERT_THROW(key.name == ad9862_pga_gain_name); - val = usrp_e_codec_ctrl::tx_pga_gain_range; + val = usrp_e100_codec_ctrl::tx_pga_gain_range; return; case CODEC_PROP_GAIN_I: //only one gain for I and Q @@ -133,7 +133,7 @@ void usrp_e_impl::tx_codec_get(const wax::obj &key_, wax::obj &val){ } } -void usrp_e_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::tx_codec_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the set request conditioned on the key diff --git a/host/lib/usrp/usrp_e100/dboard_iface.cpp b/host/lib/usrp/usrp_e100/dboard_iface.cpp index 6898df8df..aa96171d6 100644 --- a/host/lib/usrp/usrp_e100/dboard_iface.cpp +++ b/host/lib/usrp/usrp_e100/dboard_iface.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_iface.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_iface.hpp" +#include "usrp_e100_regs.hpp" #include "clock_ctrl.hpp" #include "codec_ctrl.hpp" #include @@ -29,13 +29,13 @@ using namespace uhd; using namespace uhd::usrp; using namespace boost::assign; -class usrp_e_dboard_iface : public dboard_iface{ +class usrp_e100_dboard_iface : public dboard_iface{ public: - usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec + usrp_e100_dboard_iface( + usrp_e100_iface::sptr iface, + usrp_e100_clock_ctrl::sptr clock, + usrp_e100_codec_ctrl::sptr codec ){ _iface = iface; _clock = clock; @@ -49,7 +49,7 @@ public: _iface->poke16(UE_REG_GPIO_TX_DBG, 0); } - ~usrp_e_dboard_iface(void){ + ~usrp_e100_dboard_iface(void){ /* NOP */ } @@ -94,27 +94,27 @@ public: double get_codec_rate(unit_t); private: - usrp_e_iface::sptr _iface; - usrp_e_clock_ctrl::sptr _clock; - usrp_e_codec_ctrl::sptr _codec; + usrp_e100_iface::sptr _iface; + usrp_e100_clock_ctrl::sptr _clock; + usrp_e100_codec_ctrl::sptr _codec; uhd::dict _clock_rates; }; /*********************************************************************** * Make Function **********************************************************************/ -dboard_iface::sptr make_usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec +dboard_iface::sptr make_usrp_e100_dboard_iface( + usrp_e100_iface::sptr iface, + usrp_e100_clock_ctrl::sptr clock, + usrp_e100_codec_ctrl::sptr codec ){ - return dboard_iface::sptr(new usrp_e_dboard_iface(iface, clock, codec)); + return dboard_iface::sptr(new usrp_e100_dboard_iface(iface, clock, codec)); } /*********************************************************************** * Clock Rates **********************************************************************/ -void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ +void usrp_e100_dboard_iface::set_clock_rate(unit_t unit, double rate){ _clock_rates[unit] = rate; switch(unit){ case UNIT_RX: return _clock->set_rx_dboard_clock_rate(rate); @@ -122,7 +122,7 @@ void usrp_e_dboard_iface::set_clock_rate(unit_t unit, double rate){ } } -std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ +std::vector usrp_e100_dboard_iface::get_clock_rates(unit_t unit){ switch(unit){ case UNIT_RX: return _clock->get_rx_dboard_clock_rates(); case UNIT_TX: return _clock->get_tx_dboard_clock_rates(); @@ -130,25 +130,25 @@ std::vector usrp_e_dboard_iface::get_clock_rates(unit_t unit){ } } -double usrp_e_dboard_iface::get_clock_rate(unit_t unit){ +double usrp_e100_dboard_iface::get_clock_rate(unit_t unit){ return _clock_rates[unit]; } -void usrp_e_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ +void usrp_e100_dboard_iface::set_clock_enabled(unit_t unit, bool enb){ switch(unit){ case UNIT_RX: return _clock->enable_rx_dboard_clock(enb); case UNIT_TX: return _clock->enable_tx_dboard_clock(enb); } } -double usrp_e_dboard_iface::get_codec_rate(unit_t){ +double usrp_e100_dboard_iface::get_codec_rate(unit_t){ return _clock->get_fpga_clock_rate(); } /*********************************************************************** * GPIO **********************************************************************/ -void usrp_e_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ +void usrp_e100_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ UHD_ASSERT_THROW(GPIO_SEL_ATR == 1); //make this assumption switch(unit){ case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_SEL, value); return; @@ -156,21 +156,21 @@ void usrp_e_dboard_iface::set_pin_ctrl(unit_t unit, boost::uint16_t value){ } } -void usrp_e_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ +void usrp_e100_dboard_iface::set_gpio_ddr(unit_t unit, boost::uint16_t value){ switch(unit){ case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_DDR, value); return; case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_DDR, value); return; } } -void usrp_e_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ +void usrp_e100_dboard_iface::write_gpio(unit_t unit, boost::uint16_t value){ switch(unit){ case UNIT_RX: _iface->poke16(UE_REG_GPIO_RX_IO, value); return; case UNIT_TX: _iface->poke16(UE_REG_GPIO_TX_IO, value); return; } } -boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ +boost::uint16_t usrp_e100_dboard_iface::read_gpio(unit_t unit){ switch(unit){ case UNIT_RX: return _iface->peek16(UE_REG_GPIO_RX_IO); case UNIT_TX: return _iface->peek16(UE_REG_GPIO_TX_IO); @@ -178,7 +178,7 @@ boost::uint16_t usrp_e_dboard_iface::read_gpio(unit_t unit){ } } -void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ +void usrp_e100_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_t value){ //define mapping of unit to atr regs to register address static const uhd::dict< unit_t, uhd::dict @@ -199,7 +199,7 @@ void usrp_e_dboard_iface::set_atr_reg(unit_t unit, atr_reg_t atr, boost::uint16_ _iface->poke16(unit_to_atr_to_addr[unit][atr], value); } -void usrp_e_dboard_iface::set_gpio_debug(unit_t unit, int which){ +void usrp_e100_dboard_iface::set_gpio_debug(unit_t unit, int which){ //set this unit to all outputs this->set_gpio_ddr(unit, 0xffff); @@ -238,7 +238,7 @@ static boost::uint32_t unit_to_otw_spi_dev(dboard_iface::unit_t unit){ throw std::invalid_argument("unknown unit type"); } -void usrp_e_dboard_iface::write_spi( +void usrp_e100_dboard_iface::write_spi( unit_t unit, const spi_config_t &config, boost::uint32_t data, @@ -247,7 +247,7 @@ void usrp_e_dboard_iface::write_spi( _iface->transact_spi(unit_to_otw_spi_dev(unit), config, data, num_bits, false /*no rb*/); } -boost::uint32_t usrp_e_dboard_iface::read_write_spi( +boost::uint32_t usrp_e100_dboard_iface::read_write_spi( unit_t unit, const spi_config_t &config, boost::uint32_t data, @@ -259,39 +259,39 @@ boost::uint32_t usrp_e_dboard_iface::read_write_spi( /*********************************************************************** * I2C **********************************************************************/ -void usrp_e_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ +void usrp_e100_dboard_iface::write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ return _iface->write_i2c(addr, bytes); } -byte_vector_t usrp_e_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ +byte_vector_t usrp_e100_dboard_iface::read_i2c(boost::uint8_t addr, size_t num_bytes){ return _iface->read_i2c(addr, num_bytes); } /*********************************************************************** * Aux DAX/ADC **********************************************************************/ -void usrp_e_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ +void usrp_e100_dboard_iface::write_aux_dac(dboard_iface::unit_t, aux_dac_t which, float value){ //same aux dacs for each unit - static const uhd::dict which_to_aux_dac = map_list_of - (AUX_DAC_A, usrp_e_codec_ctrl::AUX_DAC_A) - (AUX_DAC_B, usrp_e_codec_ctrl::AUX_DAC_B) - (AUX_DAC_C, usrp_e_codec_ctrl::AUX_DAC_C) - (AUX_DAC_D, usrp_e_codec_ctrl::AUX_DAC_D) + static const uhd::dict which_to_aux_dac = map_list_of + (AUX_DAC_A, usrp_e100_codec_ctrl::AUX_DAC_A) + (AUX_DAC_B, usrp_e100_codec_ctrl::AUX_DAC_B) + (AUX_DAC_C, usrp_e100_codec_ctrl::AUX_DAC_C) + (AUX_DAC_D, usrp_e100_codec_ctrl::AUX_DAC_D) ; _codec->write_aux_dac(which_to_aux_dac[which], value); } -float usrp_e_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ +float usrp_e100_dboard_iface::read_aux_adc(dboard_iface::unit_t unit, aux_adc_t which){ static const uhd::dict< - unit_t, uhd::dict + unit_t, uhd::dict > unit_to_which_to_aux_adc = map_list_of (UNIT_RX, map_list_of - (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A1) - (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B1) + (AUX_ADC_A, usrp_e100_codec_ctrl::AUX_ADC_A1) + (AUX_ADC_B, usrp_e100_codec_ctrl::AUX_ADC_B1) ) (UNIT_TX, map_list_of - (AUX_ADC_A, usrp_e_codec_ctrl::AUX_ADC_A2) - (AUX_ADC_B, usrp_e_codec_ctrl::AUX_ADC_B2) + (AUX_ADC_A, usrp_e100_codec_ctrl::AUX_ADC_A2) + (AUX_ADC_B, usrp_e100_codec_ctrl::AUX_ADC_B2) ) ; return _codec->read_aux_adc(unit_to_which_to_aux_adc[unit][which]); diff --git a/host/lib/usrp/usrp_e100/dboard_impl.cpp b/host/lib/usrp/usrp_e100/dboard_impl.cpp index f2840dcfc..9f2bfb8ae 100644 --- a/host/lib/usrp/usrp_e100/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/dboard_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,12 +30,12 @@ using namespace uhd::usrp; /*********************************************************************** * Dboard Initialization **********************************************************************/ -void usrp_e_impl::dboard_init(void){ +void usrp_e100_impl::dboard_init(void){ _rx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_RX_DB, 0, dboard_eeprom_t::num_bytes())); _tx_db_eeprom = dboard_eeprom_t(_iface->read_eeprom(I2C_ADDR_TX_DB, 0, dboard_eeprom_t::num_bytes())); //create a new dboard interface and manager - _dboard_iface = make_usrp_e_dboard_iface( + _dboard_iface = make_usrp_e100_dboard_iface( _iface, _clock_ctrl, _codec_ctrl ); _dboard_manager = dboard_manager::make( @@ -44,19 +44,19 @@ void usrp_e_impl::dboard_init(void){ //setup the dboard proxies _rx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_dboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_dboard_set, this, _1, _2) + boost::bind(&usrp_e100_impl::rx_dboard_get, this, _1, _2), + boost::bind(&usrp_e100_impl::rx_dboard_set, this, _1, _2) ); _tx_dboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_dboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_dboard_set, this, _1, _2) + boost::bind(&usrp_e100_impl::tx_dboard_get, this, _1, _2), + boost::bind(&usrp_e100_impl::tx_dboard_set, this, _1, _2) ); } /*********************************************************************** * RX Dboard Get **********************************************************************/ -void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -101,7 +101,7 @@ void usrp_e_impl::rx_dboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * RX Dboard Set **********************************************************************/ -void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ +void usrp_e100_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ case DBOARD_PROP_DBOARD_ID: _rx_db_eeprom.id = val.as(); @@ -115,7 +115,7 @@ void usrp_e_impl::rx_dboard_set(const wax::obj &key, const wax::obj &val){ /*********************************************************************** * TX Dboard Get **********************************************************************/ -void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -160,7 +160,7 @@ void usrp_e_impl::tx_dboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * TX Dboard Set **********************************************************************/ -void usrp_e_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ +void usrp_e100_impl::tx_dboard_set(const wax::obj &key, const wax::obj &val){ switch(key.as()){ case DBOARD_PROP_DBOARD_ID: _tx_db_eeprom.id = val.as(); diff --git a/host/lib/usrp/usrp_e100/dsp_impl.cpp b/host/lib/usrp/usrp_e100/dsp_impl.cpp index 97f173c1a..43a3bd3be 100644 --- a/host/lib/usrp/usrp_e100/dsp_impl.cpp +++ b/host/lib/usrp/usrp_e100/dsp_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,10 +30,10 @@ using namespace uhd::usrp; /*********************************************************************** * RX DDC Initialization **********************************************************************/ -void usrp_e_impl::rx_ddc_init(void){ +void usrp_e100_impl::rx_ddc_init(void){ _rx_ddc_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::rx_ddc_get, this, _1, _2), - boost::bind(&usrp_e_impl::rx_ddc_set, this, _1, _2) + boost::bind(&usrp_e100_impl::rx_ddc_get, this, _1, _2), + boost::bind(&usrp_e100_impl::rx_ddc_set, this, _1, _2) ); //initial config and update @@ -44,7 +44,7 @@ void usrp_e_impl::rx_ddc_init(void){ /*********************************************************************** * RX DDC Get **********************************************************************/ -void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -79,7 +79,7 @@ void usrp_e_impl::rx_ddc_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * RX DDC Set **********************************************************************/ -void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -113,10 +113,10 @@ void usrp_e_impl::rx_ddc_set(const wax::obj &key_, const wax::obj &val){ /*********************************************************************** * TX DUC Initialization **********************************************************************/ -void usrp_e_impl::tx_duc_init(void){ +void usrp_e100_impl::tx_duc_init(void){ _tx_duc_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::tx_duc_get, this, _1, _2), - boost::bind(&usrp_e_impl::tx_duc_set, this, _1, _2) + boost::bind(&usrp_e100_impl::tx_duc_get, this, _1, _2), + boost::bind(&usrp_e100_impl::tx_duc_set, this, _1, _2) ); //initial config and update @@ -127,7 +127,7 @@ void usrp_e_impl::tx_duc_init(void){ /*********************************************************************** * TX DUC Get **********************************************************************/ -void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ @@ -162,7 +162,7 @@ void usrp_e_impl::tx_duc_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * TX DUC Set **********************************************************************/ -void usrp_e_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ +void usrp_e100_impl::tx_duc_set(const wax::obj &key_, const wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); switch(key.as()){ diff --git a/host/lib/usrp/usrp_e100/fpga-downloader.cc b/host/lib/usrp/usrp_e100/fpga-downloader.cc index 4dc537919..4a3d3b9af 100644 --- a/host/lib/usrp/usrp_e100/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e100/fpga-downloader.cc @@ -253,7 +253,7 @@ int main(int argc, char *argv[]) } */ -void usrp_e_load_fpga(const std::string &bin_file){ +void usrp_e100_load_fpga(const std::string &bin_file){ gpio gpio_prog_b(PROG_B, OUT); gpio gpio_init_b(INIT_B, IN); gpio gpio_done (DONE, IN); diff --git a/host/lib/usrp/usrp_e100/io_impl.cpp b/host/lib/usrp/usrp_e100/io_impl.cpp index e863944e8..7cb3e25e5 100644 --- a/host/lib/usrp/usrp_e100/io_impl.cpp +++ b/host/lib/usrp/usrp_e100/io_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,7 +30,7 @@ using namespace uhd; using namespace uhd::usrp; using namespace uhd::transport; -zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface); +zero_copy_if::sptr usrp_e100_make_mmap_zero_copy(usrp_e100_iface::sptr iface); /*********************************************************************** * Constants @@ -46,14 +46,14 @@ static const bool recv_debug = false; * - thread loop * - vrt packet handler states **********************************************************************/ -struct usrp_e_impl::io_impl{ +struct usrp_e100_impl::io_impl{ //state management for the vrt packet handler code vrt_packet_handler::recv_state packet_handler_recv_state; vrt_packet_handler::send_state packet_handler_send_state; zero_copy_if::sptr data_xport; bool continuous_streaming; - io_impl(usrp_e_iface::sptr iface): - data_xport(usrp_e_make_mmap_zero_copy(iface)), + io_impl(usrp_e100_iface::sptr iface): + data_xport(usrp_e100_make_mmap_zero_copy(iface)), recv_pirate_booty(recv_booty_type::make(data_xport->get_num_recv_frames())), async_msg_fifo(bounded_buffer::make(100/*messages deep*/)) { @@ -73,7 +73,7 @@ struct usrp_e_impl::io_impl{ } //a pirate's life is the life for me! - void recv_pirate_loop(usrp_e_clock_ctrl::sptr); + void recv_pirate_loop(usrp_e100_clock_ctrl::sptr); typedef bounded_buffer recv_booty_type; recv_booty_type::sptr recv_pirate_booty; bounded_buffer::sptr async_msg_fifo; @@ -86,7 +86,7 @@ struct usrp_e_impl::io_impl{ * - while raiding, loot for recv buffers * - put booty into the alignment buffer **********************************************************************/ -void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) +void usrp_e100_impl::io_impl::recv_pirate_loop(usrp_e100_clock_ctrl::sptr clock_ctrl) { set_thread_priority_safe(); recv_pirate_crew_raiding = true; @@ -140,7 +140,7 @@ void usrp_e_impl::io_impl::recv_pirate_loop(usrp_e_clock_ctrl::sptr clock_ctrl) /*********************************************************************** * Helper Functions **********************************************************************/ -void usrp_e_impl::io_init(void){ +void usrp_e100_impl::io_init(void){ //setup otw types _send_otw_type.width = 16; _send_otw_type.shift = 0; @@ -172,11 +172,11 @@ void usrp_e_impl::io_init(void){ //spawn a pirate, yarrr! _io_impl->recv_pirate_crew.create_thread(boost::bind( - &usrp_e_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl + &usrp_e100_impl::io_impl::recv_pirate_loop, _io_impl.get(), _clock_ctrl )); } -void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ +void usrp_e100_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ _io_impl->continuous_streaming = (stream_cmd.stream_mode == stream_cmd_t::STREAM_MODE_START_CONTINUOUS); _iface->poke32(UE_REG_CTRL_RX_STREAM_CMD, dsp_type1::calc_stream_cmd_word( stream_cmd, get_max_recv_samps_per_packet() @@ -185,7 +185,7 @@ void usrp_e_impl::issue_stream_cmd(const stream_cmd_t &stream_cmd){ _iface->poke32(UE_REG_CTRL_RX_TIME_TICKS, stream_cmd.time_spec.get_tick_count(_clock_ctrl->get_fpga_clock_rate())); } -void usrp_e_impl::handle_overrun(size_t){ +void usrp_e100_impl::handle_overrun(size_t){ std::cerr << "O"; //the famous OOOOOOOOOOO _iface->poke32(UE_REG_CTRL_RX_CLEAR_OVERRUN, 0); if (_io_impl->continuous_streaming){ @@ -205,7 +205,7 @@ bool get_send_buffs( return buffs[0].get() != NULL; } -size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ +size_t usrp_e100_impl::get_max_send_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) - sizeof(vrt::if_packet_info_t().cid) //no class id ever used @@ -214,7 +214,7 @@ size_t usrp_e_impl::get_max_send_samps_per_packet(void) const{ return bpp/_send_otw_type.get_sample_size(); } -size_t usrp_e_impl::send( +size_t usrp_e100_impl::send( const std::vector &buffs, size_t num_samps, const tx_metadata_t &metadata, const io_type_t &io_type, send_mode_t send_mode, double timeout @@ -234,7 +234,7 @@ size_t usrp_e_impl::send( /*********************************************************************** * Data Recv **********************************************************************/ -size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ +size_t usrp_e100_impl::get_max_recv_samps_per_packet(void) const{ static const size_t hdr_size = 0 + vrt::max_if_hdr_words32*sizeof(boost::uint32_t) + sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer @@ -244,7 +244,7 @@ size_t usrp_e_impl::get_max_recv_samps_per_packet(void) const{ return bpp/_recv_otw_type.get_sample_size(); } -size_t usrp_e_impl::recv( +size_t usrp_e100_impl::recv( const std::vector &buffs, size_t num_samps, rx_metadata_t &metadata, const io_type_t &io_type, recv_mode_t recv_mode, double timeout @@ -256,15 +256,15 @@ size_t usrp_e_impl::recv( io_type, _recv_otw_type, //input and output types to convert _clock_ctrl->get_fpga_clock_rate(), //master clock tick rate uhd::transport::vrt::if_hdr_unpack_le, - boost::bind(&usrp_e_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), - boost::bind(&usrp_e_impl::handle_overrun, this, _1) + boost::bind(&usrp_e100_impl::io_impl::get_recv_buffs, _io_impl.get(), _1, timeout), + boost::bind(&usrp_e100_impl::handle_overrun, this, _1) ); } /*********************************************************************** * Async Recv **********************************************************************/ -bool usrp_e_impl::recv_async_msg( +bool usrp_e100_impl::recv_async_msg( async_metadata_t &async_metadata, double timeout ){ boost::this_thread::disable_interruption di; //disable because the wait can throw diff --git a/host/lib/usrp/usrp_e100/mboard_impl.cpp b/host/lib/usrp/usrp_e100/mboard_impl.cpp index f0118aa4b..2d5d028e6 100644 --- a/host/lib/usrp/usrp_e100/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e100/mboard_impl.cpp @@ -15,8 +15,8 @@ // along with this program. If not, see . // -#include "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" +#include "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" #include #include #include @@ -30,10 +30,10 @@ using namespace uhd::usrp; /*********************************************************************** * Mboard Initialization **********************************************************************/ -void usrp_e_impl::mboard_init(void){ +void usrp_e100_impl::mboard_init(void){ _mboard_proxy = wax_obj_proxy::make( - boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), - boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) + boost::bind(&usrp_e100_impl::mboard_get, this, _1, _2), + boost::bind(&usrp_e100_impl::mboard_set, this, _1, _2) ); //init the clock config @@ -46,7 +46,7 @@ void usrp_e_impl::mboard_init(void){ /*********************************************************************** * Mboard Get **********************************************************************/ -void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ +void usrp_e100_impl::mboard_get(const wax::obj &key_, wax::obj &val){ named_prop_t key = named_prop_t::extract(key_); //handle the get request conditioned on the key @@ -114,7 +114,7 @@ void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ /*********************************************************************** * Mboard Set **********************************************************************/ -void usrp_e_impl::mboard_set(const wax::obj &key, const wax::obj &val){ +void usrp_e100_impl::mboard_set(const wax::obj &key, const wax::obj &val){ //handle the get request conditioned on the key switch(key.as()){ diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp new file mode 100644 index 000000000..ad623777e --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.cpp @@ -0,0 +1,194 @@ +// +// 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 "usrp_e100_iface.hpp" +#include +#include //ioctl +#include //open, close +#include //ioctl structures and constants +#include +#include //mutex +#include + +using namespace uhd; + +class usrp_e100_iface_impl : public usrp_e100_iface{ +public: + + int get_file_descriptor(void){ + return _node_fd; + } + + /******************************************************************* + * Structors + ******************************************************************/ + usrp_e100_iface_impl(const std::string &node){ + //open the device node and check file descriptor + if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ + throw std::runtime_error(str( + boost::format("Failed to open %s") % node + )); + } + } + + ~usrp_e100_iface_impl(void){ + //close the device node file descriptor + ::close(_node_fd); + } + + /******************************************************************* + * IOCTL: provides the communication base for all other calls + ******************************************************************/ + void ioctl(int request, void *mem){ + boost::mutex::scoped_lock lock(_ctrl_mutex); + + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } + } + + /******************************************************************* + * Peek and Poke + ******************************************************************/ + void poke32(boost::uint32_t addr, boost::uint32_t value){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL32, &data); + } + + void poke16(boost::uint32_t addr, boost::uint16_t value){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + this->ioctl(USRP_E_WRITE_CTL16, &data); + } + + boost::uint32_t peek32(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl32 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL32, &data); + + return data.buf[0]; + } + + boost::uint16_t peek16(boost::uint32_t addr){ + //load the data struct + usrp_e_ctl16 data; + data.offset = addr; + data.count = 1; + + //call the ioctl + this->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; + } + + /******************************************************************* + * I2C + ******************************************************************/ + static const size_t max_i2c_data_bytes = 10; + + void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = bytes.size(); + std::copy(bytes.begin(), bytes.end(), data->data); + + //call the spi ioctl + this->ioctl(USRP_E_I2C_WRITE, data); + } + + byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ + //allocate some memory for this transaction + UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); + boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; + + //load the data struct + usrp_e_i2c *data = reinterpret_cast(mem); + data->addr = addr; + data->len = num_bytes; + + //call the spi ioctl + this->ioctl(USRP_E_I2C_READ, data); + + //unload the data + byte_vector_t bytes(data->len); + UHD_ASSERT_THROW(bytes.size() == num_bytes); + std::copy(data->data, data->data+bytes.size(), bytes.begin()); + return bytes; + } + + /******************************************************************* + * SPI + ******************************************************************/ + boost::uint32_t transact_spi( + int which_slave, + const spi_config_t &config, + boost::uint32_t bits, + size_t num_bits, + bool readback + ){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = which_slave; + data.length = num_bits; + data.data = bits; + + //load the flags + data.flags = 0; + data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; + + //call the spi ioctl + this->ioctl(USRP_E_SPI, &data); + + //unload the data + return data.data; + } + +private: + int _node_fd; + boost::mutex _ctrl_mutex; +}; + +/*********************************************************************** + * Public Make Function + **********************************************************************/ +usrp_e100_iface::sptr usrp_e100_iface::make(const std::string &node){ + return sptr(new usrp_e100_iface_impl(node)); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp new file mode 100644 index 000000000..b52209a42 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_iface.hpp @@ -0,0 +1,112 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#ifndef INCLUDED_USRP_E100_IFACE_HPP +#define INCLUDED_USRP_E100_IFACE_HPP + +#include +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////// +// I2C addresses +//////////////////////////////////////////////////////////////////////// +#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx +#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) +#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) +#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) +//////////////////////////////////////////////////////////////////////// + +/*! + * The usrp-e interface class: + * Provides a set of functions to implementation layer. + * Including spi, peek, poke, control... + */ +class usrp_e100_iface : boost::noncopyable, public uhd::i2c_iface{ +public: + typedef boost::shared_ptr sptr; + + /*! + * Make a new usrp-e interface with the control transport. + * \param node the device node name + * \return a new usrp-e interface object + */ + static sptr make(const std::string &node); + + /*! + * Get the underlying file descriptor. + * \return the file descriptor + */ + virtual int get_file_descriptor(void) = 0; + + /*! + * Perform an ioctl call on the device node file descriptor. + * This will throw when the internal ioctl call fails. + * \param request the control word + * \param mem pointer to some memory + */ + virtual void ioctl(int request, void *mem) = 0; + + /*! + * Write a register (32 bits) + * \param addr the address + * \param data the 32bit data + */ + virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; + + /*! + * Read a register (32 bits) + * \param addr the address + * \return the 32bit data + */ + virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; + + /*! + * Write a register (16 bits) + * \param addr the address + * \param data the 16bit data + */ + virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; + + /*! + * Read a register (16 bits) + * \param addr the address + * \return the 16bit data + */ + virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; + + /*! + * Perform an spi transaction. + * \param which_slave the slave device number + * \param config spi config args + * \param data the bits to write + * \param num_bits how many bits in data + * \param readback true to readback a value + * \return spi data if readback set + */ + virtual boost::uint32_t transact_spi( + int which_slave, + const uhd::spi_config_t &config, + boost::uint32_t data, + size_t num_bits, + bool readback + ) = 0; +}; + +#endif /* INCLUDED_USRP_E100_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp new file mode 100644 index 000000000..73cb1f285 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -0,0 +1,201 @@ +// +// 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 "usrp_e100_impl.hpp" +#include "usrp_e100_regs.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::usrp; +namespace fs = boost::filesystem; + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +static device_addrs_t usrp_e100_find(const device_addr_t &hint){ + device_addrs_t usrp_e100_addrs; + + //return an empty list of addresses when type is set to non-usrp-e + if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e100_addrs; + + //device node not provided, assume its 0 + if (not hint.has_key("node")){ + device_addr_t new_addr = hint; + new_addr["node"] = "/dev/usrp_e1000"; + return usrp_e100_find(new_addr); + } + + //use the given device node name + if (fs::exists(hint["node"])){ + device_addr_t new_addr; + new_addr["type"] = "usrp-e"; + new_addr["node"] = abs_path(hint["node"]); + usrp_e100_addrs.push_back(new_addr); + } + + return usrp_e100_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +static device::sptr usrp_e100_make(const device_addr_t &device_addr){ + + //setup the main interface into fpga + std::string node = device_addr["node"]; + std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; + usrp_e100_iface::sptr iface = usrp_e100_iface::make(node); + + //------------------------------------------------------------------ + //-- Handle the FPGA loading... + //-- The image can be confimed as already loaded when: + //-- 1) The compatibility number matches. + //-- 2) The hash in the hash-file matches. + //------------------------------------------------------------------ + static const char *hash_file_path = "/tmp/usrp_e100100_hash"; + + //extract the fpga path for usrp-e + std::string usrp_e100_fpga_image = find_image_path( + device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100100_fpga.bin" + ); + + //calculate a hash of the fpga file + size_t fpga_hash = 0; + { + std::ifstream file(usrp_e100_fpga_image.c_str()); + if (not file.good()) throw std::runtime_error( + "cannot open fpga file for read: " + usrp_e100_fpga_image + ); + do{ + boost::hash_combine(fpga_hash, file.get()); + } while (file.good()); + file.close(); + } + + //read the compatibility number + boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + + //read the hash in the hash-file + size_t loaded_hash = 0; + try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} + + //if not loaded: load the fpga image and write the hash-file + if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ + iface.reset(); + usrp_e100_load_fpga(usrp_e100_fpga_image); + std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; + iface = usrp_e100_iface::make(node); + try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} + } + + //check that the compatibility is correct + fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + if (fpga_compat_num != USRP_E_COMPAT_NUM){ + throw std::runtime_error(str(boost::format( + "Expected fpga compatibility number 0x%x, but got 0x%x:\n" + "The fpga build is not compatible with the host code build." + ) % USRP_E_COMPAT_NUM % fpga_compat_num)); + } + + return device::sptr(new usrp_e100_impl(iface)); +} + +UHD_STATIC_BLOCK(register_usrp_e100_device){ + device::register_device(&usrp_e100_find, &usrp_e100_make); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e100_impl::usrp_e100_impl(usrp_e100_iface::sptr iface): _iface(iface){ + + //setup interfaces into hardware + _clock_ctrl = usrp_e100_clock_ctrl::make(_iface); + _codec_ctrl = usrp_e100_codec_ctrl::make(_iface); + + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); + + //init the codec properties + codec_init(); + + //init the io send/recv + io_init(); + + //set default subdev specs + this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); + this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); +} + +usrp_e100_impl::~usrp_e100_impl(void){ + /* NOP */ +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp_e100_impl::get(const wax::obj &key_, wax::obj &val){ + named_prop_t key = named_prop_t::extract(key_); + + //handle the get request conditioned on the key + switch(key.as()){ + case DEVICE_PROP_NAME: + val = std::string("usrp-e device"); + return; + + case DEVICE_PROP_MBOARD: + UHD_ASSERT_THROW(key.name == ""); + val = _mboard_proxy->get_link(); + return; + + case DEVICE_PROP_MBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp_e100_impl::set(const wax::obj &, const wax::obj &){ + UHD_THROW_PROP_SET_ERROR(); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp new file mode 100644 index 000000000..fe60ac0be --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.hpp @@ -0,0 +1,164 @@ +// +// 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 "usrp_e100_iface.hpp" +#include "clock_ctrl.hpp" +#include "codec_ctrl.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef INCLUDED_USRP_E100_IMPL_HPP +#define INCLUDED_USRP_E100_IMPL_HPP + +static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; + +//! load an fpga image from a bin file into the usrp-e fpga +extern void usrp_e100_load_fpga(const std::string &bin_file); + +/*! + * Make a usrp-e dboard interface. + * \param iface the usrp-e interface object + * \param clock the clock control interface + * \param codec the codec control interface + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_iface::sptr make_usrp_e100_dboard_iface( + usrp_e100_iface::sptr iface, + usrp_e100_clock_ctrl::sptr clock, + usrp_e100_codec_ctrl::sptr codec +); + +/*! + * Simple wax obj proxy class: + * Provides a wax obj interface for a set and a get function. + * This allows us to create nested properties structures + * while maintaining flattened code within the implementation. + */ +class wax_obj_proxy : public wax::obj{ +public: + typedef boost::function get_t; + typedef boost::function set_t; + typedef boost::shared_ptr sptr; + + static sptr make(const get_t &get, const set_t &set){ + return sptr(new wax_obj_proxy(get, set)); + } + +private: + get_t _get; set_t _set; + wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; + void get(const wax::obj &key, wax::obj &val){return _get(key, val);} + void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} +}; + +/*! + * USRP-E100 implementation guts: + * The implementation details are encapsulated here. + * Handles properties on the mboard, dboard, dsps... + */ +class usrp_e100_impl : public uhd::device{ +public: + //structors + usrp_e100_impl(usrp_e100_iface::sptr); + ~usrp_e100_impl(void); + + //the io interface + size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); + size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); + bool recv_async_msg(uhd::async_metadata_t &, double); + size_t get_max_send_samps_per_packet(void) const; + size_t get_max_recv_samps_per_packet(void) const; + +private: + //interface to ioctls and file descriptor + usrp_e100_iface::sptr _iface; + + //handle io stuff + UHD_PIMPL_DECL(io_impl) _io_impl; + uhd::otw_type_t _send_otw_type, _recv_otw_type; + void io_init(void); + void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); + void handle_overrun(size_t); + + //configuration shadows + uhd::clock_config_t _clock_config; + //TODO otw type recv/send + + //ad9522 clock control + usrp_e100_clock_ctrl::sptr _clock_ctrl; + + //ad9862 codec control + usrp_e100_codec_ctrl::sptr _codec_ctrl; + + //device functions and settings + void get(const wax::obj &, wax::obj &); + void set(const wax::obj &, const wax::obj &); + + //mboard functions and settings + void mboard_init(void); + void mboard_get(const wax::obj &, wax::obj &); + void mboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _mboard_proxy; + uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + uhd::usrp::dboard_iface::sptr _dboard_iface; + + //rx dboard functions and settings + uhd::usrp::dboard_eeprom_t _rx_db_eeprom; + void rx_dboard_get(const wax::obj &, wax::obj &); + void rx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_dboard_proxy; + + //tx dboard functions and settings + uhd::usrp::dboard_eeprom_t _tx_db_eeprom; + void tx_dboard_get(const wax::obj &, wax::obj &); + void tx_dboard_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _tx_dboard_proxy; + + //rx ddc functions and settings + void rx_ddc_init(void); + void rx_ddc_get(const wax::obj &, wax::obj &); + void rx_ddc_set(const wax::obj &, const wax::obj &); + double _ddc_freq; size_t _ddc_decim; + wax_obj_proxy::sptr _rx_ddc_proxy; + + //tx duc functions and settings + void tx_duc_init(void); + void tx_duc_get(const wax::obj &, wax::obj &); + void tx_duc_set(const wax::obj &, const wax::obj &); + double _duc_freq; size_t _duc_interp; + wax_obj_proxy::sptr _tx_duc_proxy; + + //codec functions and settings + void codec_init(void); + void rx_codec_get(const wax::obj &, wax::obj &); + void rx_codec_set(const wax::obj &, const wax::obj &); + void tx_codec_get(const wax::obj &, wax::obj &); + void tx_codec_set(const wax::obj &, const wax::obj &); + wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; +}; + +#endif /* INCLUDED_USRP_E100_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp new file mode 100644 index 000000000..bf378a9b1 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_mmap_zero_copy.cpp @@ -0,0 +1,215 @@ +// +// 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 "usrp_e100_iface.hpp" +#include +#include +#include +#include //mmap +#include //getpagesize +#include //poll +#include +#include +#include + +using namespace uhd; +using namespace uhd::transport; + +static const bool fp_verbose = false; //fast-path verbose +static const bool sp_verbose = false; //slow-path verbose +static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout + +/*********************************************************************** + * The zero copy interface implementation + **********************************************************************/ +class usrp_e100_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { +public: + usrp_e100_mmap_zero_copy_impl(usrp_e100_iface::sptr iface): + _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) + { + //get system sizes + iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); + size_t page_size = getpagesize(); + _frame_size = page_size/2; + + //calculate the memory size + _map_size = + (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + + (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; + + //print sizes summary + if (sp_verbose){ + std::cout << "page_size: " << page_size << std::endl; + std::cout << "frame_size: " << _frame_size << std::endl; + std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; + std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; + std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; + std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; + std::cout << "map_size: " << _map_size << std::endl; + } + + //call mmap to get the memory + _mapped_mem = ::mmap( + NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 + ); + UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); + + //calculate the memory offsets for info and buffers + size_t recv_info_off = 0; + size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); + size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); + size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); + + //print offset summary + if (sp_verbose){ + std::cout << "recv_info_off: " << recv_info_off << std::endl; + std::cout << "recv_buff_off: " << recv_buff_off << std::endl; + std::cout << "send_info_off: " << send_info_off << std::endl; + std::cout << "send_buff_off: " << send_buff_off << std::endl; + } + + //set the internal pointers for info and buffers + typedef ring_buffer_info (*rbi_pta)[]; + char *rb_ptr = reinterpret_cast(_mapped_mem); + _recv_info = reinterpret_cast(rb_ptr + recv_info_off); + _recv_buff = rb_ptr + recv_buff_off; + _send_info = reinterpret_cast(rb_ptr + send_info_off); + _send_buff = rb_ptr + send_buff_off; + } + + ~usrp_e100_mmap_zero_copy_impl(void){ + if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; + ::munmap(_mapped_mem, _map_size); + } + + managed_recv_buffer::sptr get_recv_buff(double timeout){ + if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; + + //grab pointers to the info and buffer + ring_buffer_info *info = (*_recv_info) + _recv_index; + void *mem = _recv_buff + _frame_size*_recv_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_USER)){ + for (size_t i = 0; i < poll_breakout; i++){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLIN; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); + if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; + if (poll_ret > 0) goto found_user_frame; //good poll, continue on + } + return managed_recv_buffer::sptr(); //timed-out for real + } found_user_frame: + + //the process has claimed the frame + info->flags = RB_USER_PROCESS; + + //increment the index for the next call + if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; + + //return the managed buffer for this frame + if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; + return managed_recv_buffer::make_safe( + boost::asio::const_buffer(mem, info->len), + boost::bind(&usrp_e100_mmap_zero_copy_impl::release, shared_from_this(), info) + ); + } + + size_t get_num_recv_frames(void) const{ + return _rb_size.num_rx_frames; + } + + size_t get_recv_frame_size(void) const{ + return _frame_size; + } + + managed_send_buffer::sptr get_send_buff(double timeout){ + if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; + + //grab pointers to the info and buffer + ring_buffer_info *info = (*_send_info) + _send_index; + void *mem = _send_buff + _frame_size*_send_index; + + //poll/wait for a ready frame + if (not (info->flags & RB_KERNEL)){ + pollfd pfd; + pfd.fd = _fd; + pfd.events = POLLOUT; + ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); + if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; + if (poll_ret <= 0) return managed_send_buffer::sptr(); + } + + //increment the index for the next call + if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; + + //return the managed buffer for this frame + if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; + return managed_send_buffer::make_safe( + boost::asio::mutable_buffer(mem, _frame_size), + boost::bind(&usrp_e100_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) + ); + } + + size_t get_num_send_frames(void) const{ + return _rb_size.num_tx_frames; + } + + size_t get_send_frame_size(void) const{ + return _frame_size; + } + +private: + + void release(ring_buffer_info *info){ + if (fp_verbose) std::cout << "recv buff: release" << std::endl; + info->flags = RB_KERNEL; + } + + void commit(ring_buffer_info *info, size_t len){ + if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; + info->len = len; + info->flags = RB_USER; + if (::write(_fd, NULL, 0) < 0){ + std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; + } + } + + int _fd; + + //the mapped memory itself + void *_mapped_mem; + + //mapped memory sizes + usrp_e_ring_buffer_size_t _rb_size; + size_t _frame_size, _map_size; + + //pointers to sections in the mapped memory + ring_buffer_info (*_recv_info)[], (*_send_info)[]; + char *_recv_buff, *_send_buff; + + //indexes into sub-sections of mapped memory + size_t _recv_index, _send_index; +}; + +/*********************************************************************** + * The zero copy interface make function + **********************************************************************/ +zero_copy_if::sptr usrp_e100_make_mmap_zero_copy(usrp_e100_iface::sptr iface){ + return zero_copy_if::sptr(new usrp_e100_mmap_zero_copy_impl(iface)); +} diff --git a/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp new file mode 100644 index 000000000..625fb2c35 --- /dev/null +++ b/host/lib/usrp/usrp_e100/usrp_e100_regs.hpp @@ -0,0 +1,198 @@ + + +//////////////////////////////////////////////////////////////// +// +// Memory map for embedded wishbone bus +// +//////////////////////////////////////////////////////////////// + +// All addresses are byte addresses. All accesses are word (16-bit) accesses. +// This means that address bit 0 is usually 0. +// There are 11 bits of address for the control. + +#ifndef INCLUDED_USRP_E100_REGS_HPP +#define INCLUDED_USRP_E100_REGS_HPP + +///////////////////////////////////////////////////// +// Slave pointers + +#define UE_REG_SLAVE(n) ((n)<<7) +#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) + +///////////////////////////////////////////////////// +// Slave 0 -- Misc Regs + +#define UE_REG_MISC_BASE UE_REG_SLAVE(0) + +#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 +#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 +#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 +#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 +#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 +#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 +#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 +#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 +#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 + +///////////////////////////////////////////////////// +// Slave 1 -- UART +// CLKDIV is 16 bits, others are only 8 + +#define UE_REG_UART_BASE UE_REG_SLAVE(1) + +#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 +#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 +#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 +#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 +#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 + +///////////////////////////////////////////////////// +// Slave 2 -- SPI Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_SPI_BASE UE_REG_SLAVE(2) + +//spi slave constants +#define UE_SPI_SS_AD9522 (1 << 3) +#define UE_SPI_SS_AD9862 (1 << 2) +#define UE_SPI_SS_TX_DB (1 << 1) +#define UE_SPI_SS_RX_DB (1 << 0) + +//////////////////////////////////////////////// +// Slave 3 -- I2C Core +// This should be accessed through the IOCTL +// Users should not touch directly + +#define UE_REG_I2C_BASE UE_REG_SLAVE(3) + + +//////////////////////////////////////////////// +// Slave 4 -- GPIO + +#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) + +#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 +#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 +#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 +#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 +#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 +#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 +#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 +#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 + +//possible bit values for sel when dbg is 0: +#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg +#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic + +//possible bit values for sel when dbg is 1: +#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric + + +//////////////////////////////////////////////////// +// Slave 5 -- Settings Bus +// +// Output-only, no readback, 32 registers total +// Each register must be written 32 bits at a time +// First the address xxx_xx00 and then xxx_xx10 + +#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) + +/////////////////////////////////////////////////// +// Slave 6 -- ATR Controller +// 16 regs + +#define UE_REG_ATR_BASE UE_REG_SLAVE(6) + +#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 +#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 +#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 +#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 +#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 +#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 +#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 +#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 + +///////////////////////////////////////////////// +// DSP RX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) +#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} +#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate +#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic +#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits +#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) + +/////////////////////////////////////////////////// +// VITA RX CTRL regs +/////////////////////////////////////////////////// +// The following 3 are logically a single command register. +// They are clocked into the underlying fifo when time_ticks is written. +#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) +#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) +#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) +#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun +#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter +#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. +#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) +#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) +#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources + +///////////////////////////////////////////////// +// DSP TX Regs +//////////////////////////////////////////////// +#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) +#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} +#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) +#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) +#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) + +///////////////////////////////////////////////// +// VITA TX CTRL regs +//////////////////////////////////////////////// +#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) +#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) +#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) +#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) + +#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) +#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) + +///////////////////////////////////////////////// +// VITA49 64 bit time (write only) +//////////////////////////////////////////////// + /*! + * \brief Time 64 flags + * + *
+   *
+   *    3                   2                   1
+   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   * +-----------------------------------------------------------+-+-+
+   * |                                                           |S|P|
+   * +-----------------------------------------------------------+-+-+
+   *
+   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
+   * S - Source (0=sma, 1=mimo, 0=default)
+   *
+   * 
+ */ +#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS +#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS +#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above +#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) +#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) + +//pps flags (see above) +#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) +#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) +#define UE_FLAG_TIME64_PPS_SMA (0 << 1) +#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) + +#define UE_FLAG_TIME64_LATCH_NOW 1 +#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 + +#endif + diff --git a/host/lib/usrp/usrp_e100/usrp_e_iface.cpp b/host/lib/usrp/usrp_e100/usrp_e_iface.cpp deleted file mode 100644 index f00e92946..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_iface.cpp +++ /dev/null @@ -1,194 +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 "usrp_e_iface.hpp" -#include -#include //ioctl -#include //open, close -#include //ioctl structures and constants -#include -#include //mutex -#include - -using namespace uhd; - -class usrp_e_iface_impl : public usrp_e_iface{ -public: - - int get_file_descriptor(void){ - return _node_fd; - } - - /******************************************************************* - * Structors - ******************************************************************/ - usrp_e_iface_impl(const std::string &node){ - //open the device node and check file descriptor - if ((_node_fd = ::open(node.c_str(), O_RDWR)) < 0){ - throw std::runtime_error(str( - boost::format("Failed to open %s") % node - )); - } - } - - ~usrp_e_iface_impl(void){ - //close the device node file descriptor - ::close(_node_fd); - } - - /******************************************************************* - * IOCTL: provides the communication base for all other calls - ******************************************************************/ - void ioctl(int request, void *mem){ - boost::mutex::scoped_lock lock(_ctrl_mutex); - - if (::ioctl(_node_fd, request, mem) < 0){ - throw std::runtime_error(str( - boost::format("ioctl failed with request %d") % request - )); - } - } - - /******************************************************************* - * Peek and Poke - ******************************************************************/ - void poke32(boost::uint32_t addr, boost::uint32_t value){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL32, &data); - } - - void poke16(boost::uint32_t addr, boost::uint16_t value){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - data.buf[0] = value; - - //call the ioctl - this->ioctl(USRP_E_WRITE_CTL16, &data); - } - - boost::uint32_t peek32(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl32 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL32, &data); - - return data.buf[0]; - } - - boost::uint16_t peek16(boost::uint32_t addr){ - //load the data struct - usrp_e_ctl16 data; - data.offset = addr; - data.count = 1; - - //call the ioctl - this->ioctl(USRP_E_READ_CTL16, &data); - - return data.buf[0]; - } - - /******************************************************************* - * I2C - ******************************************************************/ - static const size_t max_i2c_data_bytes = 10; - - void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(bytes.size() <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c *data = reinterpret_cast(mem); - data->addr = addr; - data->len = bytes.size(); - std::copy(bytes.begin(), bytes.end(), data->data); - - //call the spi ioctl - this->ioctl(USRP_E_I2C_WRITE, data); - } - - byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes){ - //allocate some memory for this transaction - UHD_ASSERT_THROW(num_bytes <= max_i2c_data_bytes); - boost::uint8_t mem[sizeof(usrp_e_i2c) + max_i2c_data_bytes]; - - //load the data struct - usrp_e_i2c *data = reinterpret_cast(mem); - data->addr = addr; - data->len = num_bytes; - - //call the spi ioctl - this->ioctl(USRP_E_I2C_READ, data); - - //unload the data - byte_vector_t bytes(data->len); - UHD_ASSERT_THROW(bytes.size() == num_bytes); - std::copy(data->data, data->data+bytes.size(), bytes.begin()); - return bytes; - } - - /******************************************************************* - * SPI - ******************************************************************/ - boost::uint32_t transact_spi( - int which_slave, - const spi_config_t &config, - boost::uint32_t bits, - size_t num_bits, - bool readback - ){ - //load data struct - usrp_e_spi data; - data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; - data.slave = which_slave; - data.length = num_bits; - data.data = bits; - - //load the flags - data.flags = 0; - data.flags |= (config.miso_edge == spi_config_t::EDGE_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; - data.flags |= (config.mosi_edge == spi_config_t::EDGE_RISE)? UE_SPI_PUSH_FALL : UE_SPI_PUSH_RISE; - - //call the spi ioctl - this->ioctl(USRP_E_SPI, &data); - - //unload the data - return data.data; - } - -private: - int _node_fd; - boost::mutex _ctrl_mutex; -}; - -/*********************************************************************** - * Public Make Function - **********************************************************************/ -usrp_e_iface::sptr usrp_e_iface::make(const std::string &node){ - return sptr(new usrp_e_iface_impl(node)); -} diff --git a/host/lib/usrp/usrp_e100/usrp_e_iface.hpp b/host/lib/usrp/usrp_e100/usrp_e_iface.hpp deleted file mode 100644 index 59aac43d9..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_iface.hpp +++ /dev/null @@ -1,112 +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 . -// - -#ifndef INCLUDED_USRP_E_IFACE_HPP -#define INCLUDED_USRP_E_IFACE_HPP - -#include -#include -#include -#include -#include - -//////////////////////////////////////////////////////////////////////// -// I2C addresses -//////////////////////////////////////////////////////////////////////// -#define I2C_DEV_EEPROM 0x50 // 24LC02[45]: 7-bits 1010xxx -#define I2C_ADDR_MBOARD (I2C_DEV_EEPROM | 0x0) -#define I2C_ADDR_TX_DB (I2C_DEV_EEPROM | 0x4) -#define I2C_ADDR_RX_DB (I2C_DEV_EEPROM | 0x5) -//////////////////////////////////////////////////////////////////////// - -/*! - * The usrp-e interface class: - * Provides a set of functions to implementation layer. - * Including spi, peek, poke, control... - */ -class usrp_e_iface : boost::noncopyable, public uhd::i2c_iface{ -public: - typedef boost::shared_ptr sptr; - - /*! - * Make a new usrp-e interface with the control transport. - * \param node the device node name - * \return a new usrp-e interface object - */ - static sptr make(const std::string &node); - - /*! - * Get the underlying file descriptor. - * \return the file descriptor - */ - virtual int get_file_descriptor(void) = 0; - - /*! - * Perform an ioctl call on the device node file descriptor. - * This will throw when the internal ioctl call fails. - * \param request the control word - * \param mem pointer to some memory - */ - virtual void ioctl(int request, void *mem) = 0; - - /*! - * Write a register (32 bits) - * \param addr the address - * \param data the 32bit data - */ - virtual void poke32(boost::uint32_t addr, boost::uint32_t data) = 0; - - /*! - * Read a register (32 bits) - * \param addr the address - * \return the 32bit data - */ - virtual boost::uint32_t peek32(boost::uint32_t addr) = 0; - - /*! - * Write a register (16 bits) - * \param addr the address - * \param data the 16bit data - */ - virtual void poke16(boost::uint32_t addr, boost::uint16_t data) = 0; - - /*! - * Read a register (16 bits) - * \param addr the address - * \return the 16bit data - */ - virtual boost::uint16_t peek16(boost::uint32_t addr) = 0; - - /*! - * Perform an spi transaction. - * \param which_slave the slave device number - * \param config spi config args - * \param data the bits to write - * \param num_bits how many bits in data - * \param readback true to readback a value - * \return spi data if readback set - */ - virtual boost::uint32_t transact_spi( - int which_slave, - const uhd::spi_config_t &config, - boost::uint32_t data, - size_t num_bits, - bool readback - ) = 0; -}; - -#endif /* INCLUDED_USRP_E_IFACE_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e_impl.cpp deleted file mode 100644 index 70cc399fb..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_impl.cpp +++ /dev/null @@ -1,201 +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 "usrp_e_impl.hpp" -#include "usrp_e_regs.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::usrp; -namespace fs = boost::filesystem; - -/*********************************************************************** - * Helper Functions - **********************************************************************/ -static std::string abs_path(const std::string &file_path){ - return fs::system_complete(fs::path(file_path)).file_string(); -} - -/*********************************************************************** - * Discovery - **********************************************************************/ -static device_addrs_t usrp_e_find(const device_addr_t &hint){ - device_addrs_t usrp_e_addrs; - - //return an empty list of addresses when type is set to non-usrp-e - if (hint.has_key("type") and hint["type"] != "usrp-e") return usrp_e_addrs; - - //device node not provided, assume its 0 - if (not hint.has_key("node")){ - device_addr_t new_addr = hint; - new_addr["node"] = "/dev/usrp_e0"; - return usrp_e_find(new_addr); - } - - //use the given device node name - if (fs::exists(hint["node"])){ - device_addr_t new_addr; - new_addr["type"] = "usrp-e"; - new_addr["node"] = abs_path(hint["node"]); - usrp_e_addrs.push_back(new_addr); - } - - return usrp_e_addrs; -} - -/*********************************************************************** - * Make - **********************************************************************/ -static device::sptr usrp_e_make(const device_addr_t &device_addr){ - - //setup the main interface into fpga - std::string node = device_addr["node"]; - std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; - usrp_e_iface::sptr iface = usrp_e_iface::make(node); - - //------------------------------------------------------------------ - //-- Handle the FPGA loading... - //-- The image can be confimed as already loaded when: - //-- 1) The compatibility number matches. - //-- 2) The hash in the hash-file matches. - //------------------------------------------------------------------ - static const char *hash_file_path = "/tmp/usrp_e100_hash"; - - //extract the fpga path for usrp-e - std::string usrp_e_fpga_image = find_image_path( - device_addr.has_key("fpga")? device_addr["fpga"] : "usrp_e100_fpga.bin" - ); - - //calculate a hash of the fpga file - size_t fpga_hash = 0; - { - std::ifstream file(usrp_e_fpga_image.c_str()); - if (not file.good()) throw std::runtime_error( - "cannot open fpga file for read: " + usrp_e_fpga_image - ); - do{ - boost::hash_combine(fpga_hash, file.get()); - } while (file.good()); - file.close(); - } - - //read the compatibility number - boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); - - //read the hash in the hash-file - size_t loaded_hash = 0; - try{std::ifstream(hash_file_path) >> loaded_hash;}catch(...){} - - //if not loaded: load the fpga image and write the hash-file - if (fpga_compat_num != USRP_E_COMPAT_NUM or loaded_hash != fpga_hash){ - iface.reset(); - usrp_e_load_fpga(usrp_e_fpga_image); - std::cout << boost::format("re-Opening USRP-E on %s") % node << std::endl; - iface = usrp_e_iface::make(node); - try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} - } - - //check that the compatibility is correct - fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); - if (fpga_compat_num != USRP_E_COMPAT_NUM){ - throw std::runtime_error(str(boost::format( - "Expected fpga compatibility number 0x%x, but got 0x%x:\n" - "The fpga build is not compatible with the host code build." - ) % USRP_E_COMPAT_NUM % fpga_compat_num)); - } - - return device::sptr(new usrp_e_impl(iface)); -} - -UHD_STATIC_BLOCK(register_usrp_e_device){ - device::register_device(&usrp_e_find, &usrp_e_make); -} - -/*********************************************************************** - * Structors - **********************************************************************/ -usrp_e_impl::usrp_e_impl(usrp_e_iface::sptr iface): _iface(iface){ - - //setup interfaces into hardware - _clock_ctrl = usrp_e_clock_ctrl::make(_iface); - _codec_ctrl = usrp_e_codec_ctrl::make(_iface); - - //initialize the mboard - mboard_init(); - - //initialize the dboards - dboard_init(); - - //initialize the dsps - rx_ddc_init(); - tx_duc_init(); - - //init the codec properties - codec_init(); - - //init the io send/recv - io_init(); - - //set default subdev specs - this->mboard_set(MBOARD_PROP_RX_SUBDEV_SPEC, subdev_spec_t()); - this->mboard_set(MBOARD_PROP_TX_SUBDEV_SPEC, subdev_spec_t()); -} - -usrp_e_impl::~usrp_e_impl(void){ - /* NOP */ -} - -/*********************************************************************** - * Device Get - **********************************************************************/ -void usrp_e_impl::get(const wax::obj &key_, wax::obj &val){ - named_prop_t key = named_prop_t::extract(key_); - - //handle the get request conditioned on the key - switch(key.as()){ - case DEVICE_PROP_NAME: - val = std::string("usrp-e device"); - return; - - case DEVICE_PROP_MBOARD: - UHD_ASSERT_THROW(key.name == ""); - val = _mboard_proxy->get_link(); - return; - - case DEVICE_PROP_MBOARD_NAMES: - val = prop_names_t(1, ""); //vector of size 1 with empty string - return; - - default: UHD_THROW_PROP_GET_ERROR(); - } -} - -/*********************************************************************** - * Device Set - **********************************************************************/ -void usrp_e_impl::set(const wax::obj &, const wax::obj &){ - UHD_THROW_PROP_SET_ERROR(); -} diff --git a/host/lib/usrp/usrp_e100/usrp_e_impl.hpp b/host/lib/usrp/usrp_e100/usrp_e_impl.hpp deleted file mode 100644 index b5f21810d..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_impl.hpp +++ /dev/null @@ -1,164 +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 "usrp_e_iface.hpp" -#include "clock_ctrl.hpp" -#include "codec_ctrl.hpp" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef INCLUDED_USRP_E_IMPL_HPP -#define INCLUDED_USRP_E_IMPL_HPP - -static const boost::uint16_t USRP_E_COMPAT_NUM = 0x02; - -//! load an fpga image from a bin file into the usrp-e fpga -extern void usrp_e_load_fpga(const std::string &bin_file); - -/*! - * Make a usrp-e dboard interface. - * \param iface the usrp-e interface object - * \param clock the clock control interface - * \param codec the codec control interface - * \return a sptr to a new dboard interface - */ -uhd::usrp::dboard_iface::sptr make_usrp_e_dboard_iface( - usrp_e_iface::sptr iface, - usrp_e_clock_ctrl::sptr clock, - usrp_e_codec_ctrl::sptr codec -); - -/*! - * Simple wax obj proxy class: - * Provides a wax obj interface for a set and a get function. - * This allows us to create nested properties structures - * while maintaining flattened code within the implementation. - */ -class wax_obj_proxy : public wax::obj{ -public: - typedef boost::function get_t; - typedef boost::function set_t; - typedef boost::shared_ptr sptr; - - static sptr make(const get_t &get, const set_t &set){ - return sptr(new wax_obj_proxy(get, set)); - } - -private: - get_t _get; set_t _set; - wax_obj_proxy(const get_t &get, const set_t &set): _get(get), _set(set){}; - void get(const wax::obj &key, wax::obj &val){return _get(key, val);} - void set(const wax::obj &key, const wax::obj &val){return _set(key, val);} -}; - -/*! - * USRP1E implementation guts: - * The implementation details are encapsulated here. - * Handles properties on the mboard, dboard, dsps... - */ -class usrp_e_impl : public uhd::device{ -public: - //structors - usrp_e_impl(usrp_e_iface::sptr); - ~usrp_e_impl(void); - - //the io interface - size_t send(const std::vector &, size_t, const uhd::tx_metadata_t &, const uhd::io_type_t &, send_mode_t, double); - size_t recv(const std::vector &, size_t, uhd::rx_metadata_t &, const uhd::io_type_t &, recv_mode_t, double); - bool recv_async_msg(uhd::async_metadata_t &, double); - size_t get_max_send_samps_per_packet(void) const; - size_t get_max_recv_samps_per_packet(void) const; - -private: - //interface to ioctls and file descriptor - usrp_e_iface::sptr _iface; - - //handle io stuff - UHD_PIMPL_DECL(io_impl) _io_impl; - uhd::otw_type_t _send_otw_type, _recv_otw_type; - void io_init(void); - void issue_stream_cmd(const uhd::stream_cmd_t &stream_cmd); - void handle_overrun(size_t); - - //configuration shadows - uhd::clock_config_t _clock_config; - //TODO otw type recv/send - - //ad9522 clock control - usrp_e_clock_ctrl::sptr _clock_ctrl; - - //ad9862 codec control - usrp_e_codec_ctrl::sptr _codec_ctrl; - - //device functions and settings - void get(const wax::obj &, wax::obj &); - void set(const wax::obj &, const wax::obj &); - - //mboard functions and settings - void mboard_init(void); - void mboard_get(const wax::obj &, wax::obj &); - void mboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _mboard_proxy; - uhd::usrp::subdev_spec_t _rx_subdev_spec, _tx_subdev_spec; - - //xx dboard functions and settings - void dboard_init(void); - uhd::usrp::dboard_manager::sptr _dboard_manager; - uhd::usrp::dboard_iface::sptr _dboard_iface; - - //rx dboard functions and settings - uhd::usrp::dboard_eeprom_t _rx_db_eeprom; - void rx_dboard_get(const wax::obj &, wax::obj &); - void rx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_dboard_proxy; - - //tx dboard functions and settings - uhd::usrp::dboard_eeprom_t _tx_db_eeprom; - void tx_dboard_get(const wax::obj &, wax::obj &); - void tx_dboard_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _tx_dboard_proxy; - - //rx ddc functions and settings - void rx_ddc_init(void); - void rx_ddc_get(const wax::obj &, wax::obj &); - void rx_ddc_set(const wax::obj &, const wax::obj &); - double _ddc_freq; size_t _ddc_decim; - wax_obj_proxy::sptr _rx_ddc_proxy; - - //tx duc functions and settings - void tx_duc_init(void); - void tx_duc_get(const wax::obj &, wax::obj &); - void tx_duc_set(const wax::obj &, const wax::obj &); - double _duc_freq; size_t _duc_interp; - wax_obj_proxy::sptr _tx_duc_proxy; - - //codec functions and settings - void codec_init(void); - void rx_codec_get(const wax::obj &, wax::obj &); - void rx_codec_set(const wax::obj &, const wax::obj &); - void tx_codec_get(const wax::obj &, wax::obj &); - void tx_codec_set(const wax::obj &, const wax::obj &); - wax_obj_proxy::sptr _rx_codec_proxy, _tx_codec_proxy; -}; - -#endif /* INCLUDED_USRP_E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp b/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp deleted file mode 100644 index 274bb043e..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_mmap_zero_copy.cpp +++ /dev/null @@ -1,215 +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 "usrp_e_iface.hpp" -#include -#include -#include -#include //mmap -#include //getpagesize -#include //poll -#include -#include -#include - -using namespace uhd; -using namespace uhd::transport; - -static const bool fp_verbose = false; //fast-path verbose -static const bool sp_verbose = false; //slow-path verbose -static const size_t poll_breakout = 10; //how many poll timeouts constitute a full timeout - -/*********************************************************************** - * The zero copy interface implementation - **********************************************************************/ -class usrp_e_mmap_zero_copy_impl : public zero_copy_if, public boost::enable_shared_from_this { -public: - usrp_e_mmap_zero_copy_impl(usrp_e_iface::sptr iface): - _fd(iface->get_file_descriptor()), _recv_index(0), _send_index(0) - { - //get system sizes - iface->ioctl(USRP_E_GET_RB_INFO, &_rb_size); - size_t page_size = getpagesize(); - _frame_size = page_size/2; - - //calculate the memory size - _map_size = - (_rb_size.num_pages_rx_flags + _rb_size.num_pages_tx_flags) * page_size + - (_rb_size.num_rx_frames + _rb_size.num_tx_frames) * _frame_size; - - //print sizes summary - if (sp_verbose){ - std::cout << "page_size: " << page_size << std::endl; - std::cout << "frame_size: " << _frame_size << std::endl; - std::cout << "num_pages_rx_flags: " << _rb_size.num_pages_rx_flags << std::endl; - std::cout << "num_rx_frames: " << _rb_size.num_rx_frames << std::endl; - std::cout << "num_pages_tx_flags: " << _rb_size.num_pages_tx_flags << std::endl; - std::cout << "num_tx_frames: " << _rb_size.num_tx_frames << std::endl; - std::cout << "map_size: " << _map_size << std::endl; - } - - //call mmap to get the memory - _mapped_mem = ::mmap( - NULL, _map_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0 - ); - UHD_ASSERT_THROW(_mapped_mem != MAP_FAILED); - - //calculate the memory offsets for info and buffers - size_t recv_info_off = 0; - size_t recv_buff_off = recv_info_off + (_rb_size.num_pages_rx_flags * page_size); - size_t send_info_off = recv_buff_off + (_rb_size.num_rx_frames * _frame_size); - size_t send_buff_off = send_info_off + (_rb_size.num_pages_tx_flags * page_size); - - //print offset summary - if (sp_verbose){ - std::cout << "recv_info_off: " << recv_info_off << std::endl; - std::cout << "recv_buff_off: " << recv_buff_off << std::endl; - std::cout << "send_info_off: " << send_info_off << std::endl; - std::cout << "send_buff_off: " << send_buff_off << std::endl; - } - - //set the internal pointers for info and buffers - typedef ring_buffer_info (*rbi_pta)[]; - char *rb_ptr = reinterpret_cast(_mapped_mem); - _recv_info = reinterpret_cast(rb_ptr + recv_info_off); - _recv_buff = rb_ptr + recv_buff_off; - _send_info = reinterpret_cast(rb_ptr + send_info_off); - _send_buff = rb_ptr + send_buff_off; - } - - ~usrp_e_mmap_zero_copy_impl(void){ - if (sp_verbose) std::cout << "cleanup: munmap" << std::endl; - ::munmap(_mapped_mem, _map_size); - } - - managed_recv_buffer::sptr get_recv_buff(double timeout){ - if (fp_verbose) std::cout << "get_recv_buff: " << _recv_index << std::endl; - - //grab pointers to the info and buffer - ring_buffer_info *info = (*_recv_info) + _recv_index; - void *mem = _recv_buff + _frame_size*_recv_index; - - //poll/wait for a ready frame - if (not (info->flags & RB_USER)){ - for (size_t i = 0; i < poll_breakout; i++){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLIN; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3/poll_breakout)); - if (fp_verbose) std::cout << " POLLIN: " << poll_ret << std::endl; - if (poll_ret > 0) goto found_user_frame; //good poll, continue on - } - return managed_recv_buffer::sptr(); //timed-out for real - } found_user_frame: - - //the process has claimed the frame - info->flags = RB_USER_PROCESS; - - //increment the index for the next call - if (++_recv_index == size_t(_rb_size.num_rx_frames)) _recv_index = 0; - - //return the managed buffer for this frame - if (fp_verbose) std::cout << " make_recv_buff: " << info->len << std::endl; - return managed_recv_buffer::make_safe( - boost::asio::const_buffer(mem, info->len), - boost::bind(&usrp_e_mmap_zero_copy_impl::release, shared_from_this(), info) - ); - } - - size_t get_num_recv_frames(void) const{ - return _rb_size.num_rx_frames; - } - - size_t get_recv_frame_size(void) const{ - return _frame_size; - } - - managed_send_buffer::sptr get_send_buff(double timeout){ - if (fp_verbose) std::cout << "get_send_buff: " << _send_index << std::endl; - - //grab pointers to the info and buffer - ring_buffer_info *info = (*_send_info) + _send_index; - void *mem = _send_buff + _frame_size*_send_index; - - //poll/wait for a ready frame - if (not (info->flags & RB_KERNEL)){ - pollfd pfd; - pfd.fd = _fd; - pfd.events = POLLOUT; - ssize_t poll_ret = ::poll(&pfd, 1, size_t(timeout*1e3)); - if (fp_verbose) std::cout << " POLLOUT: " << poll_ret << std::endl; - if (poll_ret <= 0) return managed_send_buffer::sptr(); - } - - //increment the index for the next call - if (++_send_index == size_t(_rb_size.num_tx_frames)) _send_index = 0; - - //return the managed buffer for this frame - if (fp_verbose) std::cout << " make_send_buff: " << _frame_size << std::endl; - return managed_send_buffer::make_safe( - boost::asio::mutable_buffer(mem, _frame_size), - boost::bind(&usrp_e_mmap_zero_copy_impl::commit, shared_from_this(), info, _1) - ); - } - - size_t get_num_send_frames(void) const{ - return _rb_size.num_tx_frames; - } - - size_t get_send_frame_size(void) const{ - return _frame_size; - } - -private: - - void release(ring_buffer_info *info){ - if (fp_verbose) std::cout << "recv buff: release" << std::endl; - info->flags = RB_KERNEL; - } - - void commit(ring_buffer_info *info, size_t len){ - if (fp_verbose) std::cout << "send buff: commit " << len << std::endl; - info->len = len; - info->flags = RB_USER; - if (::write(_fd, NULL, 0) < 0){ - std::cerr << UHD_THROW_SITE_INFO("write error") << std::endl; - } - } - - int _fd; - - //the mapped memory itself - void *_mapped_mem; - - //mapped memory sizes - usrp_e_ring_buffer_size_t _rb_size; - size_t _frame_size, _map_size; - - //pointers to sections in the mapped memory - ring_buffer_info (*_recv_info)[], (*_send_info)[]; - char *_recv_buff, *_send_buff; - - //indexes into sub-sections of mapped memory - size_t _recv_index, _send_index; -}; - -/*********************************************************************** - * The zero copy interface make function - **********************************************************************/ -zero_copy_if::sptr usrp_e_make_mmap_zero_copy(usrp_e_iface::sptr iface){ - return zero_copy_if::sptr(new usrp_e_mmap_zero_copy_impl(iface)); -} diff --git a/host/lib/usrp/usrp_e100/usrp_e_regs.hpp b/host/lib/usrp/usrp_e100/usrp_e_regs.hpp deleted file mode 100644 index 8bfb08b6f..000000000 --- a/host/lib/usrp/usrp_e100/usrp_e_regs.hpp +++ /dev/null @@ -1,198 +0,0 @@ - - -//////////////////////////////////////////////////////////////// -// -// Memory map for embedded wishbone bus -// -//////////////////////////////////////////////////////////////// - -// All addresses are byte addresses. All accesses are word (16-bit) accesses. -// This means that address bit 0 is usually 0. -// There are 11 bits of address for the control. - -#ifndef __USRP_E_REGS_H -#define __USRP_E_REGS_H - -///////////////////////////////////////////////////// -// Slave pointers - -#define UE_REG_SLAVE(n) ((n)<<7) -#define UE_REG_SR_ADDR(n) ((UE_REG_SLAVE(5)) + (4*(n))) - -///////////////////////////////////////////////////// -// Slave 0 -- Misc Regs - -#define UE_REG_MISC_BASE UE_REG_SLAVE(0) - -#define UE_REG_MISC_LED UE_REG_MISC_BASE + 0 -#define UE_REG_MISC_SW UE_REG_MISC_BASE + 2 -#define UE_REG_MISC_CGEN_CTRL UE_REG_MISC_BASE + 4 -#define UE_REG_MISC_CGEN_ST UE_REG_MISC_BASE + 6 -#define UE_REG_MISC_TEST UE_REG_MISC_BASE + 8 -#define UE_REG_MISC_RX_LEN UE_REG_MISC_BASE + 10 -#define UE_REG_MISC_TX_LEN UE_REG_MISC_BASE + 12 -#define UE_REG_MISC_XFER_RATE UE_REG_MISC_BASE + 14 -#define UE_REG_MISC_COMPAT UE_REG_MISC_BASE + 16 - -///////////////////////////////////////////////////// -// Slave 1 -- UART -// CLKDIV is 16 bits, others are only 8 - -#define UE_REG_UART_BASE UE_REG_SLAVE(1) - -#define UE_REG_UART_CLKDIV UE_REG_UART_BASE + 0 -#define UE_REG_UART_TXLEVEL UE_REG_UART_BASE + 2 -#define UE_REG_UART_RXLEVEL UE_REG_UART_BASE + 4 -#define UE_REG_UART_TXCHAR UE_REG_UART_BASE + 6 -#define UE_REG_UART_RXCHAR UE_REG_UART_BASE + 8 - -///////////////////////////////////////////////////// -// Slave 2 -- SPI Core -// This should be accessed through the IOCTL -// Users should not touch directly - -#define UE_REG_SPI_BASE UE_REG_SLAVE(2) - -//spi slave constants -#define UE_SPI_SS_AD9522 (1 << 3) -#define UE_SPI_SS_AD9862 (1 << 2) -#define UE_SPI_SS_TX_DB (1 << 1) -#define UE_SPI_SS_RX_DB (1 << 0) - -//////////////////////////////////////////////// -// Slave 3 -- I2C Core -// This should be accessed through the IOCTL -// Users should not touch directly - -#define UE_REG_I2C_BASE UE_REG_SLAVE(3) - - -//////////////////////////////////////////////// -// Slave 4 -- GPIO - -#define UE_REG_GPIO_BASE UE_REG_SLAVE(4) - -#define UE_REG_GPIO_RX_IO UE_REG_GPIO_BASE + 0 -#define UE_REG_GPIO_TX_IO UE_REG_GPIO_BASE + 2 -#define UE_REG_GPIO_RX_DDR UE_REG_GPIO_BASE + 4 -#define UE_REG_GPIO_TX_DDR UE_REG_GPIO_BASE + 6 -#define UE_REG_GPIO_RX_SEL UE_REG_GPIO_BASE + 8 -#define UE_REG_GPIO_TX_SEL UE_REG_GPIO_BASE + 10 -#define UE_REG_GPIO_RX_DBG UE_REG_GPIO_BASE + 12 -#define UE_REG_GPIO_TX_DBG UE_REG_GPIO_BASE + 14 - -//possible bit values for sel when dbg is 0: -#define GPIO_SEL_SW 0 // if pin is an output, set by software in the io reg -#define GPIO_SEL_ATR 1 // if pin is an output, set by ATR logic - -//possible bit values for sel when dbg is 1: -#define GPIO_SEL_DEBUG_0 0 // if pin is an output, debug lines from FPGA fabric -#define GPIO_SEL_DEBUG_1 1 // if pin is an output, debug lines from FPGA fabric - - -//////////////////////////////////////////////////// -// Slave 5 -- Settings Bus -// -// Output-only, no readback, 32 registers total -// Each register must be written 32 bits at a time -// First the address xxx_xx00 and then xxx_xx10 - -#define UE_REG_SETTINGS_BASE UE_REG_SLAVE(5) - -/////////////////////////////////////////////////// -// Slave 6 -- ATR Controller -// 16 regs - -#define UE_REG_ATR_BASE UE_REG_SLAVE(6) - -#define UE_REG_ATR_IDLE_RXSIDE UE_REG_ATR_BASE + 0 -#define UE_REG_ATR_IDLE_TXSIDE UE_REG_ATR_BASE + 2 -#define UE_REG_ATR_INTX_RXSIDE UE_REG_ATR_BASE + 4 -#define UE_REG_ATR_INTX_TXSIDE UE_REG_ATR_BASE + 6 -#define UE_REG_ATR_INRX_RXSIDE UE_REG_ATR_BASE + 8 -#define UE_REG_ATR_INRX_TXSIDE UE_REG_ATR_BASE + 10 -#define UE_REG_ATR_FULL_RXSIDE UE_REG_ATR_BASE + 12 -#define UE_REG_ATR_FULL_TXSIDE UE_REG_ATR_BASE + 14 - -///////////////////////////////////////////////// -// DSP RX Regs -//////////////////////////////////////////////// -#define UE_REG_DSP_RX_FREQ UE_REG_SR_ADDR(0) -#define UE_REG_DSP_RX_SCALE_IQ UE_REG_SR_ADDR(1) // {scale_i,scale_q} -#define UE_REG_DSP_RX_DECIM_RATE UE_REG_SR_ADDR(2) // hb and decim rate -#define UE_REG_DSP_RX_DCOFFSET_I UE_REG_SR_ADDR(3) // Bit 31 high sets fixed offset mode, using lower 14 bits, // otherwise it is automatic -#define UE_REG_DSP_RX_DCOFFSET_Q UE_REG_SR_ADDR(4) // Bit 31 high sets fixed offset mode, using lower 14 bits -#define UE_REG_DSP_RX_MUX UE_REG_SR_ADDR(5) - -/////////////////////////////////////////////////// -// VITA RX CTRL regs -/////////////////////////////////////////////////// -// The following 3 are logically a single command register. -// They are clocked into the underlying fifo when time_ticks is written. -#define UE_REG_CTRL_RX_STREAM_CMD UE_REG_SR_ADDR(8) // {now, chain, num_samples(30) -#define UE_REG_CTRL_RX_TIME_SECS UE_REG_SR_ADDR(9) -#define UE_REG_CTRL_RX_TIME_TICKS UE_REG_SR_ADDR(10) -#define UE_REG_CTRL_RX_CLEAR_OVERRUN UE_REG_SR_ADDR(11) // write anything to clear overrun -#define UE_REG_CTRL_RX_VRT_HEADER UE_REG_SR_ADDR(12) // word 0 of packet. FPGA fills in packet counter -#define UE_REG_CTRL_RX_VRT_STREAM_ID UE_REG_SR_ADDR(13) // word 1 of packet. -#define UE_REG_CTRL_RX_VRT_TRAILER UE_REG_SR_ADDR(14) -#define UE_REG_CTRL_RX_NSAMPS_PER_PKT UE_REG_SR_ADDR(15) -#define UE_REG_CTRL_RX_NCHANNELS UE_REG_SR_ADDR(16) // 1 in basic case, up to 4 for vector sources - -///////////////////////////////////////////////// -// DSP TX Regs -//////////////////////////////////////////////// -#define UE_REG_DSP_TX_FREQ UE_REG_SR_ADDR(17) -#define UE_REG_DSP_TX_SCALE_IQ UE_REG_SR_ADDR(18) // {scale_i,scale_q} -#define UE_REG_DSP_TX_INTERP_RATE UE_REG_SR_ADDR(19) -#define UE_REG_DSP_TX_UNUSED UE_REG_SR_ADDR(20) -#define UE_REG_DSP_TX_MUX UE_REG_SR_ADDR(21) - -///////////////////////////////////////////////// -// VITA TX CTRL regs -//////////////////////////////////////////////// -#define UE_REG_CTRL_TX_NCHANNELS UE_REG_SR_ADDR(24) -#define UE_REG_CTRL_TX_CLEAR_UNDERRUN UE_REG_SR_ADDR(25) -#define UE_REG_CTRL_TX_REPORT_SID UE_REG_SR_ADDR(26) -#define UE_REG_CTRL_TX_POLICY UE_REG_SR_ADDR(27) - -#define UE_FLAG_CTRL_TX_POLICY_WAIT (0x1 << 0) -#define UE_FLAG_CTRL_TX_POLICY_NEXT_PACKET (0x1 << 1) -#define UE_FLAG_CTRL_TX_POLICY_NEXT_BURST (0x1 << 2) - -///////////////////////////////////////////////// -// VITA49 64 bit time (write only) -//////////////////////////////////////////////// - /*! - * \brief Time 64 flags - * - *
-   *
-   *    3                   2                   1
-   *  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-   * +-----------------------------------------------------------+-+-+
-   * |                                                           |S|P|
-   * +-----------------------------------------------------------+-+-+
-   *
-   * P - PPS edge selection (0=negedge, 1=posedge, default=0)
-   * S - Source (0=sma, 1=mimo, 0=default)
-   *
-   * 
- */ -#define UE_REG_TIME64_SECS UE_REG_SR_ADDR(28) // value to set absolute secs to on next PPS -#define UE_REG_TIME64_TICKS UE_REG_SR_ADDR(29) // value to set absolute ticks to on next PPS -#define UE_REG_TIME64_FLAGS UE_REG_SR_ADDR(30) // flags - see chart above -#define UE_REG_TIME64_IMM UE_REG_SR_ADDR(31) // set immediate (0=latch on next pps, 1=latch immediate, default=0) -#define UE_REG_TIME64_TPS UE_REG_SR_ADDR(31) // clock ticks per second (counter rollover) - -//pps flags (see above) -#define UE_FLAG_TIME64_PPS_NEGEDGE (0 << 0) -#define UE_FLAG_TIME64_PPS_POSEDGE (1 << 0) -#define UE_FLAG_TIME64_PPS_SMA (0 << 1) -#define UE_FLAG_TIME64_PPS_MIMO (1 << 1) - -#define UE_FLAG_TIME64_LATCH_NOW 1 -#define UE_FLAG_TIME64_LATCH_NEXT_PPS 0 - -#endif - -- cgit v1.2.3