diff options
author | Josh Blum <josh@joshknows.com> | 2010-03-30 14:12:11 +0000 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-03-30 14:12:11 +0000 |
commit | c81a975766a8831cab1e3123af94b4fe4a09d9bc (patch) | |
tree | 7b3185f8829495a023344b162e4f77122705847d /host/lib/usrp/usrp_e | |
parent | f94fa1e464c9e2a87274c991dc6461f7f4c956d8 (diff) | |
download | uhd-c81a975766a8831cab1e3123af94b4fe4a09d9bc.tar.gz uhd-c81a975766a8831cab1e3123af94b4fe4a09d9bc.tar.bz2 uhd-c81a975766a8831cab1e3123af94b4fe4a09d9bc.zip |
compiling with master merge, renamed usrp1e to usrp_e
Diffstat (limited to 'host/lib/usrp/usrp_e')
-rw-r--r-- | host/lib/usrp/usrp_e/dboard_impl.cpp | 76 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/dboard_interface.cpp | 189 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/dsp_impl.cpp | 69 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/fpga-downloader.cc | 262 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/mboard_impl.cpp | 45 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_impl.cpp | 179 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_impl.hpp | 135 | ||||
-rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_none.cpp | 38 |
8 files changed, 993 insertions, 0 deletions
diff --git a/host/lib/usrp/usrp_e/dboard_impl.cpp b/host/lib/usrp/usrp_e/dboard_impl.cpp new file mode 100644 index 000000000..88d04ce7a --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_impl.cpp @@ -0,0 +1,76 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <boost/bind.hpp> +#include <uhd/utils.hpp> +#include "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Dboard Initialization + **********************************************************************/ +void usrp_e_impl::dboard_init(void){ + dboard_id_t rx_dboard_id = dboard_id::NONE; //TODO get these from the eeprom + dboard_id_t tx_dboard_id = dboard_id::NONE; + + //create a new dboard interface and manager + dboard_interface::sptr dboard_interface( + make_usrp_e_dboard_interface(this) + ); + _dboard_manager = dboard_manager::make( + rx_dboard_id, tx_dboard_id, dboard_interface + ); + + //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) + ); + _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) + ); +} + +/*********************************************************************** + * RX Dboard Get + **********************************************************************/ +void usrp_e_impl::rx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX Dboard Set + **********************************************************************/ +void usrp_e_impl::rx_dboard_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Get + **********************************************************************/ +void usrp_e_impl::tx_dboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX Dboard Set + **********************************************************************/ +void usrp_e_impl::tx_dboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/dboard_interface.cpp b/host/lib/usrp/usrp_e/dboard_interface.cpp new file mode 100644 index 000000000..c7c7d8c1f --- /dev/null +++ b/host/lib/usrp/usrp_e/dboard_interface.cpp @@ -0,0 +1,189 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils/assert.hpp> +#include <algorithm> //std::copy +#include "usrp_e_impl.hpp" +#include <linux/usrp1_e.h> + +using namespace uhd::usrp; + +class usrp_e_dboard_interface : public dboard_interface{ +public: + usrp_e_dboard_interface(usrp_e_impl *impl); + ~usrp_e_dboard_interface(void); + + void write_aux_dac(unit_type_t, int, int); + 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); + boost::uint16_t read_gpio(gpio_bank_t); + + void write_i2c(int, const byte_vector_t &); + byte_vector_t read_i2c(int, size_t); + + double get_rx_clock_rate(void); + double get_tx_clock_rate(void); + +private: + byte_vector_t transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback + ); + + usrp_e_impl *_impl; +}; + +/*********************************************************************** + * Make Function + **********************************************************************/ +dboard_interface::sptr make_usrp_e_dboard_interface(usrp_e_impl *impl){ + return dboard_interface::sptr(new usrp_e_dboard_interface(impl)); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_dboard_interface::usrp_e_dboard_interface(usrp_e_impl *impl){ + _impl = impl; +} + +usrp_e_dboard_interface::~usrp_e_dboard_interface(void){ + /* NOP */ +} + +/*********************************************************************** + * Clock Rates + **********************************************************************/ +double usrp_e_dboard_interface::get_rx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +double usrp_e_dboard_interface::get_tx_clock_rate(void){ + throw std::runtime_error("not implemented"); +} + +/*********************************************************************** + * 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::write_gpio(gpio_bank_t bank, boost::uint16_t value, boost::uint16_t mask){ + throw std::runtime_error("not implemented"); +} + +boost::uint16_t usrp_e_dboard_interface::read_gpio(gpio_bank_t bank){ + throw std::runtime_error("not implemented"); +} + +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"); +} + +/*********************************************************************** + * SPI + **********************************************************************/ +dboard_interface::byte_vector_t usrp_e_dboard_interface::transact_spi( + spi_dev_t dev, + spi_latch_t latch, + spi_push_t push, + const byte_vector_t &buf, + bool readback +){ + //load data struct + usrp_e_spi data; + data.readback = (readback)? UE_SPI_TXRX : UE_SPI_TXONLY; + data.slave = (dev == SPI_RX_DEV)? UE_SPI_CTRL_RXNEG : UE_SPI_CTRL_TXNEG; + data.length = buf.size() * 8; //bytes to bits + boost::uint8_t *data_bytes = reinterpret_cast<boost::uint8_t*>(&data.data); + + //load the data + ASSERT_THROW(buf.size() <= sizeof(data.data)); + std::copy(buf.begin(), buf.end(), data_bytes); + + //load the flags + data.flags = 0; + data.flags |= (latch == SPI_LATCH_RISE)? UE_SPI_LATCH_RISE : UE_SPI_LATCH_FALL; + data.flags |= (push == SPI_PUSH_RISE)? UE_SPI_PUSH_RISE : UE_SPI_PUSH_FALL; + + //call the spi ioctl + _impl->ioctl(USRP_E_SPI, &data); + + //unload the data + byte_vector_t ret(data.length/8); //bits to bytes + ASSERT_THROW(ret.size() <= sizeof(data.data)); + std::copy(data_bytes, data_bytes+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * I2C + **********************************************************************/ +static const size_t max_i2c_data_bytes = 10; + +void usrp_e_dboard_interface::write_i2c(int i2c_addr, const byte_vector_t &buf){ + //allocate some memory for this transaction + ASSERT_THROW(buf.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<usrp_e_i2c&>(mem); + data.addr = i2c_addr; + data.len = buf.size(); + std::copy(buf.begin(), buf.end(), data.data); + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_WRITE, &data); +} + +dboard_interface::byte_vector_t usrp_e_dboard_interface::read_i2c(int i2c_addr, size_t num_bytes){ + //allocate some memory for this transaction + 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<usrp_e_i2c&>(mem); + data.addr = i2c_addr; + data.len = num_bytes; + + //call the spi ioctl + _impl->ioctl(USRP_E_I2C_READ, &data); + + //unload the data + byte_vector_t ret(data.len); + ASSERT_THROW(ret.size() == num_bytes); + std::copy(data.data, data.data+ret.size(), ret.begin()); + return ret; +} + +/*********************************************************************** + * Aux DAX/ADC + **********************************************************************/ +void usrp_e_dboard_interface::write_aux_dac(dboard_interface::unit_type_t unit, int which, int value){ + throw std::runtime_error("not implemented"); +} + +int usrp_e_dboard_interface::read_aux_adc(dboard_interface::unit_type_t unit, int which){ + throw std::runtime_error("not implemented"); +} diff --git a/host/lib/usrp/usrp_e/dsp_impl.cpp b/host/lib/usrp/usrp_e/dsp_impl.cpp new file mode 100644 index 000000000..e32c76a3d --- /dev/null +++ b/host/lib/usrp/usrp_e/dsp_impl.cpp @@ -0,0 +1,69 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <boost/bind.hpp> +#include "usrp_e_impl.hpp" + +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) + ); +} + +/*********************************************************************** + * RX DDC Get + **********************************************************************/ +void usrp_e_impl::rx_ddc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * RX DDC Set + **********************************************************************/ +void usrp_e_impl::rx_ddc_set(const wax::obj &, const wax::obj &){ + +} + +/*********************************************************************** + * 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) + ); +} + +/*********************************************************************** + * TX DUC Get + **********************************************************************/ +void usrp_e_impl::tx_duc_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * TX DUC Set + **********************************************************************/ +void usrp_e_impl::tx_duc_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc new file mode 100644 index 000000000..4429786a9 --- /dev/null +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -0,0 +1,262 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <iostream> +#include <sstream> +#include <fstream> +#include <string> +#include <cstdlib> + +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> + +#include <linux/spi/spidev.h> + +/* + * Configuration connections + * + * CCK - MCSPI1_CLK + * DIN - MCSPI1_MOSI + * PROG_B - GPIO_175 - output (change mux) + * DONE - GPIO_173 - input (change mux) + * INIT_B - GPIO_114 - input (change mux) + * +*/ + +const unsigned int PROG_B = 175; +const unsigned int DONE = 173; +const unsigned int INIT_B = 114; + +//static std::string bit_file = "safe_u1e.bin"; + +const int BUF_SIZE = 4096; + +enum gpio_direction {IN, OUT}; + +class gpio { + public: + + gpio(unsigned int gpio_num, gpio_direction pin_direction); + + bool get_value(); + void set_value(bool state); + + private: + + std::stringstream base_path; + std::fstream value_file; +}; + +class spidev { + public: + + spidev(std::string dev_name); + ~spidev(); + + void send(char *wbuf, char *rbuf, unsigned int nbytes); + + private: + + int fd; + +}; + +gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) +{ + std::fstream export_file; + + export_file.open("/sys/class/gpio/export", std::ios::out); + if (!export_file.is_open()) ///\todo Poor error handling + std::cout << "Failed to open gpio export file." << std::endl; + + export_file << gpio_num << std::endl; + + base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; + + std::fstream direction_file; + std::string direction_file_name; + + direction_file_name = base_path.str() + "/direction"; + + direction_file.open(direction_file_name.c_str()); + if (!direction_file.is_open()) + std::cout << "Failed to open direction file." << std::endl; + if (pin_direction == OUT) + direction_file << "out" << std::endl; + else + direction_file << "in" << std::endl; + + std::string value_file_name; + + value_file_name = base_path.str() + "/value"; + + value_file.open(value_file_name.c_str(), std::ios_base::in | std::ios_base::out); + if (!value_file.is_open()) + std::cout << "Failed to open value file." << std::endl; +} + +bool gpio::get_value() +{ + + std::string val; + + std::getline(value_file, val); + value_file.seekg(0); + + if (val == "0") + return false; + else if (val == "1") + return true; + else + std::cout << "Data read from value file|" << val << "|" << std::endl; + + return false; +} + +void gpio::set_value(bool state) +{ + + if (state) + value_file << "1" << std::endl; + else + value_file << "0" << std::endl; +} + +static void prepare_fpga_for_configuration(gpio &prog, gpio &)//init) +{ + + prog.set_value(true); + prog.set_value(false); + prog.set_value(true); + +#if 0 + bool ready_to_program(false); + unsigned int count(0); + do { + ready_to_program = init.get_value(); + count++; + + sleep(1); + } while (count < 10 && !ready_to_program); + + if (count == 10) { + std::cout << "FPGA not ready for programming." << std::endl; + exit(-1); + } +#endif +} + +spidev::spidev(std::string fname) +{ + int ret; + int mode = 0; + int speed = 12000000; + int bits = 8; + + fd = open(fname.c_str(), O_RDWR); + + ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); + ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); + ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); +} + + +spidev::~spidev() +{ + close(fd); +} + +void spidev::send(char *buf, char *rbuf, unsigned int nbytes) +{ + int ret; + + struct spi_ioc_transfer tr; + tr.tx_buf = (unsigned long) buf; + tr.rx_buf = (unsigned long) rbuf; + tr.len = nbytes; + tr.delay_usecs = 0; + tr.speed_hz = 48000000; + tr.bits_per_word = 8; + + ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); + +} + +static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) +{ + std::ifstream bitstream; + + std::cout << "File name - " << file_name.c_str() << std::endl; + + bitstream.open(file_name.c_str(), std::ios::binary); + if (!bitstream.is_open()) + std::cout << "File " << file_name << " not opened succesfully." << std::endl; + + spidev spi("/dev/spidev1.0"); + char buf[BUF_SIZE]; + char rbuf[BUF_SIZE]; + + do { + bitstream.read(buf, BUF_SIZE); + spi.send(buf, rbuf, bitstream.gcount()); + + if (error.get_value()) + std::cout << "INIT_B went high, error occured." << std::endl; + + if (!done.get_value()) + std::cout << "Configuration complete." << std::endl; + + } while (bitstream.gcount() == BUF_SIZE); +} + +/* +int main(int argc, char *argv[]) +{ + + gpio gpio_prog_b(PROG_B, OUT); + gpio gpio_init_b(INIT_B, IN); + gpio gpio_done (DONE, IN); + + if (argc == 2) + bit_file = argv[1]; + + std::cout << "FPGA config file: " << bit_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bit_file, gpio_init_b, gpio_done); +} +*/ + +#include <uhd/usrp/usrp_e.hpp> +void uhd::usrp::usrp_e::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); + + std::cout << "FPGA config file: " << bin_file << std::endl; + + prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); + + std::cout << "Done = " << gpio_done.get_value() << std::endl; + + send_file_to_fpga(bin_file, gpio_init_b, gpio_done); +} diff --git a/host/lib/usrp/usrp_e/mboard_impl.cpp b/host/lib/usrp/usrp_e/mboard_impl.cpp new file mode 100644 index 000000000..333fb2e51 --- /dev/null +++ b/host/lib/usrp/usrp_e/mboard_impl.cpp @@ -0,0 +1,45 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <boost/bind.hpp> +#include "usrp_e_impl.hpp" + +using namespace uhd::usrp; + +/*********************************************************************** + * Mboard Initialization + **********************************************************************/ +void usrp_e_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) + ); +} + +/*********************************************************************** + * Mboard Get + **********************************************************************/ +void usrp_e_impl::mboard_get(const wax::obj &, wax::obj &){ + +} + +/*********************************************************************** + * Mboard Set + **********************************************************************/ +void usrp_e_impl::mboard_set(const wax::obj &, const wax::obj &){ + +} diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp new file mode 100644 index 000000000..e821add8c --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -0,0 +1,179 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include "usrp_e_impl.hpp" +#include <uhd/utils/assert.hpp> +#include <uhd/utils/static.hpp> +#include <boost/format.hpp> +#include <boost/filesystem.hpp> +#include <fcntl.h> //open +#include <sys/ioctl.h> //ioctl + +using namespace uhd; +using namespace uhd::usrp; +namespace fs = boost::filesystem; + +UHD_STATIC_BLOCK(register_usrp_e_device){ + device::register_device(&usrp_e::find, &usrp_e::make); +} + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static std::string abs_path(const std::string &file_path){ + return fs::system_complete(fs::path(file_path)).file_string(); +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +device_addrs_t usrp_e::find(const device_addr_t &device_addr){ + device_addrs_t usrp_e_addrs; + + //if a node was provided, use it and only it + if (device_addr.has_key("node")){ + if (not fs::exists(device_addr["node"])) return usrp_e_addrs; + device_addr_t new_addr; + new_addr["name"] = "USRP-E"; + new_addr["node"] = abs_path(device_addr["node"]); + usrp_e_addrs.push_back(new_addr); + } + + //otherwise look for a few nodes at small indexes + else{ + for(size_t i = 0; i < 5; i++){ + std::string node = str(boost::format("/dev/usrp1_e%d") % i); + if (not fs::exists(node)) continue; + device_addr_t new_addr; + new_addr["name"] = "USRP-E"; + new_addr["node"] = abs_path(node); + usrp_e_addrs.push_back(new_addr); + } + } + + return usrp_e_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +device::sptr usrp_e::make(const device_addr_t &device_addr){ + return sptr(new usrp_e_impl(device_addr["node"])); +} + +/*********************************************************************** + * Structors + **********************************************************************/ +usrp_e_impl::usrp_e_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 + )); + } + + //initialize the mboard + mboard_init(); + + //initialize the dboards + dboard_init(); + + //initialize the dsps + rx_ddc_init(); + tx_duc_init(); +} + +usrp_e_impl::~usrp_e_impl(void){ + //close the device node file descriptor + ::close(_node_fd); +} + +/*********************************************************************** + * Misc Methods + **********************************************************************/ +void usrp_e_impl::ioctl(int request, void *mem){ + if (::ioctl(_node_fd, request, mem) < 0){ + throw std::runtime_error(str( + boost::format("ioctl failed with request %d") % request + )); + } +} + +/*********************************************************************** + * Device Get + **********************************************************************/ +void usrp_e_impl::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<device_prop_t>()){ + case DEVICE_PROP_NAME: + val = std::string("usrp-e device"); + return; + + case DEVICE_PROP_MBOARD: + ASSERT_THROW(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; + + case DEVICE_PROP_MAX_RX_SAMPLES: + val = size_t(_max_num_samples); + return; + + case DEVICE_PROP_MAX_TX_SAMPLES: + val = size_t(_max_num_samples); + return; + + } +} + +/*********************************************************************** + * Device Set + **********************************************************************/ +void usrp_e_impl::set(const wax::obj &, const wax::obj &){ + throw std::runtime_error("Cannot set in usrp-e device"); +} + +/*********************************************************************** + * Device IO (TODO) + **********************************************************************/ +size_t usrp_e_impl::send( + const boost::asio::const_buffer &, + const uhd::tx_metadata_t &, + const io_type_t & +){ + if (true){ + throw std::runtime_error(str(boost::format("usrp-e send: cannot handle type \"%s\"") % "")); + } + return 0; +} + +size_t usrp_e_impl::recv( + const boost::asio::mutable_buffer &, + uhd::rx_metadata_t &, + const io_type_t & +){ + if (true){ + throw std::runtime_error(str(boost::format("usrp-e recv: cannot handle type \"%s\"") % "")); + } + return 0; +} 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 <http://www.gnu.org/licenses/>. +// + +#include <uhd/usrp/usrp_e.hpp> +#include <uhd/usrp/dboard_manager.hpp> + +#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<void(const wax::obj &, wax::obj &)> get_t; + typedef boost::function<void(const wax::obj &, const wax::obj &)> set_t; + typedef boost::shared_ptr<wax_obj_proxy> 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 */ diff --git a/host/lib/usrp/usrp_e/usrp_e_none.cpp b/host/lib/usrp/usrp_e/usrp_e_none.cpp new file mode 100644 index 000000000..09a3c6946 --- /dev/null +++ b/host/lib/usrp/usrp_e/usrp_e_none.cpp @@ -0,0 +1,38 @@ +// +// 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 <http://www.gnu.org/licenses/>. +// + +#include <uhd/usrp/usrp_e.hpp> + +using namespace uhd; +using namespace uhd::usrp; + +/*! + * This file defines the usrp1e discover and make functions + * when the required kernel module headers are not present. + */ + +device_addrs_t usrp_e::find(const device_addr_t &){ + return device_addrs_t(); //return empty list +} + +device::sptr usrp_e::make(const device_addr_t &){ + throw std::runtime_error("this build has no usrp1e support"); +} + +void usrp_e::load_fpga(const std::string &){ + throw std::runtime_error("this build has no usrp1e support"); +} |