From c81a975766a8831cab1e3123af94b4fe4a09d9bc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 14:12:11 +0000 Subject: compiling with master merge, renamed usrp1e to usrp_e --- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 135 +++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 host/lib/usrp/usrp_e/usrp_e_impl.hpp (limited to 'host/lib/usrp/usrp_e/usrp_e_impl.hpp') diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp new file mode 100644 index 000000000..e593b13ad --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -0,0 +1,135 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include + +#ifndef INCLUDED_USRP_E_IMPL_HPP +#define INCLUDED_USRP_E_IMPL_HPP + +class usrp_e_impl; // dummy class declaration + +/*! + * Make a usrp_e dboard interface. + * \param impl a pointer to the usrp_e impl object + * \return a sptr to a new dboard interface + */ +uhd::usrp::dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl); + +/*! + * 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)); + } + + ~wax_obj_proxy(void){ + /* NOP */ + } + +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(const std::string &node); + ~usrp_e_impl(void); + + //the io interface + size_t send(const boost::asio::const_buffer &, const uhd::tx_metadata_t &, const uhd::io_type_t &); + size_t recv(const boost::asio::mutable_buffer &, uhd::rx_metadata_t &, const uhd::io_type_t &); + + /*! + * 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 + */ + void ioctl(int request, void *mem); + +private: + static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); + int _node_fd; + + //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; + + //xx dboard functions and settings + void dboard_init(void); + uhd::usrp::dboard_manager::sptr _dboard_manager; + + //rx dboard functions and settings + 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 + 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 &); + 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 &); + wax_obj_proxy::sptr _tx_duc_proxy; +}; + +#endif /* INCLUDED_USRP_E_IMPL_HPP */ -- cgit v1.2.3 From 03be4d0673c5e0f597db7d27f535956a591bbeb7 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Tue, 30 Mar 2010 17:52:27 +0000 Subject: filled in some gpio handling code, some mboard impl, added usrp_e_regs (like memory map) --- host/include/uhd/types/clock_config.hpp | 1 + host/lib/usrp/usrp_e/dboard_impl.cpp | 1 - host/lib/usrp/usrp_e/dboard_interface.cpp | 89 +++++++++++++++++++++++++++---- host/lib/usrp/usrp_e/mboard_impl.cpp | 77 ++++++++++++++++++++++++-- host/lib/usrp/usrp_e/usrp_e_impl.hpp | 3 ++ host/lib/usrp/usrp_e/usrp_e_regs.hpp | 49 +++++++++++++++++ 6 files changed, 206 insertions(+), 14 deletions(-) create mode 100644 host/lib/usrp/usrp_e/usrp_e_regs.hpp (limited to 'host/lib/usrp/usrp_e/usrp_e_impl.hpp') diff --git a/host/include/uhd/types/clock_config.hpp b/host/include/uhd/types/clock_config.hpp index 42d74ad90..9342fbb7b 100644 --- a/host/include/uhd/types/clock_config.hpp +++ b/host/include/uhd/types/clock_config.hpp @@ -29,6 +29,7 @@ namespace uhd{ */ struct UHD_API clock_config_t{ enum ref_source_t { + REF_AUTO = 'a', //automatic (device specific) REF_INT = 'i', //internal reference REF_SMA = 's', //external sma port REF_MIMO = 'm' //mimo cable (usrp2 only) diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp index 88d04ce7a..7c87361e0 100644 --- a/host/lib/usrp/usrp_e/dboard_impl.cpp +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -16,7 +16,6 @@ // #include -#include #include "usrp_e_impl.hpp" using namespace uhd::usrp; diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp index c7c7d8c1f..a343d93b8 100644 --- a/host/lib/usrp/usrp_e/dboard_interface.cpp +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -15,10 +15,14 @@ // along with this program. If not, see . // +#include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp" +#include #include +#include #include //std::copy -#include "usrp_e_impl.hpp" -#include +#include +#include using namespace uhd::usrp; @@ -31,8 +35,8 @@ public: int read_aux_adc(unit_type_t, int); void set_atr_reg(gpio_bank_t, boost::uint16_t, boost::uint16_t, boost::uint16_t); - void set_gpio_ddr(gpio_bank_t, boost::uint16_t, boost::uint16_t); - void write_gpio(gpio_bank_t, boost::uint16_t, boost::uint16_t); + void set_gpio_ddr(gpio_bank_t, boost::uint16_t); + void write_gpio(gpio_bank_t, boost::uint16_t); boost::uint16_t read_gpio(gpio_bank_t); void write_i2c(int, const byte_vector_t &); @@ -85,20 +89,85 @@ double usrp_e_dboard_interface::get_tx_clock_rate(void){ /*********************************************************************** * GPIO **********************************************************************/ -void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::set_gpio_ddr(gpio_bank_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_ddr)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_ddr)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + _impl->ioctl(USRP_E_WRITE_CTL16, &data); } -void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); +void usrp_e_dboard_interface::write_gpio(gpio_bank_t bank, boost::uint16_t value){ + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + data.buf[0] = value; + + //call the ioctl + _impl->ioctl(USRP_E_WRITE_CTL16, &data); } boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ - throw std::runtime_error("not implemented"); + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_io)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_io)) + ; + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 1; + + //call the ioctl + _impl->ioctl(USRP_E_READ_CTL16, &data); + + return data.buf[0]; } void usrp_e_dboard_interface::set_atr_reg(gpio_bank_t bank, boost::uint16_t tx_value, boost::uint16_t rx_value, boost::uint16_t mask){ - throw std::runtime_error("not implemented"); + //define mapping of gpio bank to register address + static const uhd::dict bank_to_addr = boost::assign::map_list_of + (GPIO_RX_BANK, GPIO_BASE + offsetof(gpio_regs_t, rx_sel_low)) + (GPIO_TX_BANK, GPIO_BASE + offsetof(gpio_regs_t, tx_sel_low)) + ; + + //set the gpio selection mux to atr or software controlled + boost::uint16_t low_sel = 0, high_sel = 0; + for(size_t i = 0; i < 16; i++){ + boost::uint16_t code = (mask & (1 << i))? GPIO_SEL_ATR : GPIO_SEL_SW; + if(i < 8) low_sel |= code << (2*i-0); + else high_sel |= code << (2*i-8); + } + + //load the data struct + usrp_e_ctl16 data; + data.offset = bank_to_addr[bank]; + data.count = 2; + data.buf[0] = low_sel; + data.buf[1] = high_sel; + + //call the ioctl + _impl->ioctl(USRP_E_READ_CTL16, &data); + + //----------------------------------------> TODO + //TODO set the atr regs } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp index 333fb2e51..1d3f9f466 100644 --- a/host/lib/usrp/usrp_e/mboard_impl.cpp +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -15,9 +15,12 @@ // along with this program. If not, see . // -#include #include "usrp_e_impl.hpp" +#include +#include +#include +using namespace uhd; using namespace uhd::usrp; /*********************************************************************** @@ -28,13 +31,81 @@ void usrp_e_impl::mboard_init(void){ boost::bind(&usrp_e_impl::mboard_get, this, _1, _2), boost::bind(&usrp_e_impl::mboard_set, this, _1, _2) ); + + //init the clock config + _clock_config.ref_source = clock_config_t::REF_AUTO; + _clock_config.pps_source = clock_config_t::PPS_SMA; + + //TODO poke the clock config regs } /*********************************************************************** * Mboard Get **********************************************************************/ -void usrp_e_impl::mboard_get(const wax::obj &, wax::obj &){ - +void usrp_e_impl::mboard_get(const wax::obj &key_, wax::obj &val){ + wax::obj key; std::string name; + boost::tie(key, name) = extract_named_prop(key_); + + + //handle the get request conditioned on the key + switch(key.as()){ + case MBOARD_PROP_NAME: + val = std::string("usrp-e mboard"); + return; + + case MBOARD_PROP_OTHERS: + val = prop_names_t(); + return; + + case MBOARD_PROP_RX_DBOARD: + ASSERT_THROW(name == ""); + val = _rx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_TX_DBOARD: + ASSERT_THROW(name == ""); + val = _tx_dboard_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DBOARD_NAMES: + val = prop_names_t(1, ""); //vector of size 1 with empty string + return; + + case MBOARD_PROP_CLOCK_RATE: + //val = TODO probably remove this property + return; + + case MBOARD_PROP_RX_DSP: + ASSERT_THROW(name == "ddc0"); + val = _rx_ddc_proxy->get_link(); + return; + + case MBOARD_PROP_RX_DSP_NAMES: + val = prop_names_t(1, "ddc0"); + return; + + case MBOARD_PROP_TX_DSP: + ASSERT_THROW(name == "duc0"); + val = _tx_duc_proxy->get_link(); + return; + + case MBOARD_PROP_TX_DSP_NAMES: + val = prop_names_t(1, "duc0"); + return; + + case MBOARD_PROP_CLOCK_CONFIG: + val = _clock_config; + return; + + case MBOARD_PROP_TIME_NOW: + case MBOARD_PROP_TIME_NEXT_PPS: + throw std::runtime_error("Error: trying to get write-only property on usrp-e mboard"); + + } } /*********************************************************************** diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index e593b13ad..643589754 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include @@ -95,6 +96,8 @@ private: static const size_t _max_num_samples = 2048/sizeof(boost::uint32_t); int _node_fd; + uhd::clock_config_t _clock_config; + //device functions and settings void get(const wax::obj &, wax::obj &); void set(const wax::obj &, const wax::obj &); diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp new file mode 100644 index 000000000..219f459a5 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -0,0 +1,49 @@ +// +// 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_REGS_HPP +#define INCLUDED_USRP_E_REGS_HPP + +#include + +//////////////////////////////////////////////// +// GPIO, Slave 4 +// +// These go to the daughterboard i/o pins + +#define GPIO_BASE 0x40 + +struct gpio_regs_t{ + boost::uint16_t rx_io; // tx data in high 16, rx in low 16 + boost::uint16_t tx_io; + boost::uint16_t rx_ddr; // 32 bits, 1 means output. tx in high 16, rx in low 16 + boost::uint16_t tx_ddr; + boost::uint16_t tx_sel_low; // 16 2-bit fields select which source goes to TX DB + boost::uint16_t tx_sel_high; + boost::uint16_t rx_sel_low; // 16 2-bit fields select which source goes to RX DB + boost::uint16_t rx_sel_high; +}; + +// each 2-bit sel field is layed out this way +#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 +#define GPIO_SEL_DEBUG_0 2 // if pin is an output, debug lines from FPGA fabric +#define GPIO_SEL_DEBUG_1 3 // if pin is an output, debug lines from FPGA fabric + +//#define gpio_base ((gpio_regs_t *) GPIO_BASE) + +#endif /* INCLUDED_USRP_E_REGS_HPP */ -- cgit v1.2.3