From 5715b2c4937ca094ca8f1d9d9b55c4edcc959981 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 25 Feb 2010 18:32:32 -0800 Subject: Created empty usrp1e cpp file for the case when headers are not found. Worked on the device make and discovery to fix certain problems. Added node param to discover usrps for usrp1e, made addr optional. --- host/lib/usrp/usrp1e/usrp1e_none.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 host/lib/usrp/usrp1e/usrp1e_none.cpp (limited to 'host/lib/usrp/usrp1e') diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp new file mode 100644 index 000000000..1c8cf9a5b --- /dev/null +++ b/host/lib/usrp/usrp1e/usrp1e_none.cpp @@ -0,0 +1,34 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include + +using namespace uhd; +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 usrp1e::discover(const device_addr_t &){ + return device_addrs_t(); //return empty list +} + +device::sptr usrp1e::make(const device_addr_t &){ + throw std::runtime_error("this build has no usrp1e support"); +} -- cgit v1.2.3 From a9f8ba6e37e1349ce61b5022ddaff1c64dd52bd3 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 25 Feb 2010 18:26:00 +0000 Subject: added usrp1e conditional compilation, and checking of device node (aka file for now) --- host/lib/CMakeLists.txt | 14 ++++++-- host/lib/usrp/usrp1e/usrp1e_impl.cpp | 69 ++++++++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/usrp1e_impl.hpp | 23 ++++++++++++ host/lib/usrp/usrp2/usrp2_impl.cpp | 1 - 4 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.cpp create mode 100644 host/lib/usrp/usrp1e/usrp1e_impl.hpp (limited to 'host/lib/usrp/usrp1e') diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index edfefa127..96fba6e53 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -41,9 +41,17 @@ SET(libuhd_sources ######################################################################## # Conditionally add the usrp1e sources ######################################################################## -LIST(APPEND libuhd_sources - usrp/usrp1e/usrp1e_none.cpp -) +INCLUDE(CheckIncludeFile) +CHECK_INCLUDE_FILE("linux/ioctl.h" HAS_LINUX_IOCTL_H) +IF(HAS_LINUX_IOCTL_H) + LIST(APPEND libuhd_sources + usrp/usrp1e/usrp1e_impl.cpp + ) +ELSE(HAS_LINUX_IOCTL_H) + LIST(APPEND libuhd_sources + usrp/usrp1e/usrp1e_none.cpp + ) +ENDIF(HAS_LINUX_IOCTL_H) ######################################################################## # Setup libuhd library diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.cpp b/host/lib/usrp/usrp1e/usrp1e_impl.cpp new file mode 100644 index 000000000..93265ab17 --- /dev/null +++ b/host/lib/usrp/usrp1e/usrp1e_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 . +// + +#include +#include +#include "usrp1e_impl.hpp" + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Helper Functions + **********************************************************************/ +static bool file_exists(const std::string &file_path){ + return access(file_path.c_str(), F_OK) == 0; +} + +/*********************************************************************** + * Discovery + **********************************************************************/ +device_addrs_t usrp1e::discover(const device_addr_t &device_addr){ + device_addrs_t usrp1e_addrs; + + //if a node was provided, use it and only it + if (device_addr.has_key("node")){ + if (not file_exists(device_addr["node"])) return usrp1e_addrs; + device_addr_t new_addr; + new_addr["name"] = "USRP1E"; + new_addr["type"] = "usrp1e"; + new_addr["node"] = device_addr["node"]; + usrp1e_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 file_exists(node)) continue; + device_addr_t new_addr; + new_addr["name"] = "USRP1E"; + new_addr["type"] = "usrp1e"; + new_addr["node"] = node; + usrp1e_addrs.push_back(new_addr); + } + } + + return usrp1e_addrs; +} + +/*********************************************************************** + * Make + **********************************************************************/ +device::sptr usrp1e::make(const device_addr_t &){ + throw std::runtime_error("not implemented yet"); +} diff --git a/host/lib/usrp/usrp1e/usrp1e_impl.hpp b/host/lib/usrp/usrp1e/usrp1e_impl.hpp new file mode 100644 index 000000000..3f5f89ec6 --- /dev/null +++ b/host/lib/usrp/usrp1e/usrp1e_impl.hpp @@ -0,0 +1,23 @@ +// +// 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 + +#ifndef INCLUDED_USRP1E_IMPL_HPP +#define INCLUDED_USRP1E_IMPL_HPP + +#endif /* INCLUDED_USRP1E_IMPL_HPP */ diff --git a/host/lib/usrp/usrp2/usrp2_impl.cpp b/host/lib/usrp/usrp2/usrp2_impl.cpp index 06876d241..5aa5d6e8d 100644 --- a/host/lib/usrp/usrp2/usrp2_impl.cpp +++ b/host/lib/usrp/usrp2/usrp2_impl.cpp @@ -62,7 +62,6 @@ uhd::device_addrs_t usrp2::discover(const device_addr_t &hint){ device_addr_t new_addr; new_addr["name"] = "USRP2"; new_addr["type"] = "usrp2"; - new_addr["transport"] = "udp"; new_addr["addr"] = ip_addr.to_string(); usrp2_addrs.push_back(new_addr); break; -- cgit v1.2.3 From 778a41b393b7d517463950c4ac014d3a2eb8eceb Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 25 Feb 2010 19:43:20 +0000 Subject: added usrp1e fpga loader --- host/include/uhd/usrp/usrp1e.hpp | 6 + host/lib/CMakeLists.txt | 21 ++- host/lib/usrp/usrp1e/fpga-downloader.cc | 262 ++++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/usrp1e_none.cpp | 4 + 4 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 host/lib/usrp/usrp1e/fpga-downloader.cc (limited to 'host/lib/usrp/usrp1e') diff --git a/host/include/uhd/usrp/usrp1e.hpp b/host/include/uhd/usrp/usrp1e.hpp index 00748e55f..60a6a191a 100644 --- a/host/include/uhd/usrp/usrp1e.hpp +++ b/host/include/uhd/usrp/usrp1e.hpp @@ -41,6 +41,12 @@ public: * \return a device sptr to a new usrp1e */ static device::sptr make(const device_addr_t &addr); + + /*! + * Load the FPGA with an image file. + * \param bin_file the name of the fpga image file + */ + static void load_fpga(const std::string &bin_file); }; }} //namespace diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 96fba6e53..33314e729 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -41,17 +41,28 @@ SET(libuhd_sources ######################################################################## # Conditionally add the usrp1e sources ######################################################################## -INCLUDE(CheckIncludeFile) -CHECK_INCLUDE_FILE("linux/ioctl.h" HAS_LINUX_IOCTL_H) -IF(HAS_LINUX_IOCTL_H) +INCLUDE(CheckIncludeFiles) +SET(usrp1e_required_headers + linux/ioctl.h + linux/spi/spidev.h +) +CHECK_INCLUDE_FILES( + "${usrp1e_required_headers}" + HAS_USRP1E_REQUIRED_HEADERS +) + +IF(HAS_USRP1E_REQUIRED_HEADERS) + MESSAGE(STATUS "Building usrp1e support...") LIST(APPEND libuhd_sources + usrp/usrp1e/fpga-downloader.cc usrp/usrp1e/usrp1e_impl.cpp ) -ELSE(HAS_LINUX_IOCTL_H) +ELSE(HAS_USRP1E_REQUIRED_HEADERS) + MESSAGE(STATUS "Skipping usrp1e support...") LIST(APPEND libuhd_sources usrp/usrp1e/usrp1e_none.cpp ) -ENDIF(HAS_LINUX_IOCTL_H) +ENDIF(HAS_USRP1E_REQUIRED_HEADERS) ######################################################################## # Setup libuhd library diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp1e/fpga-downloader.cc new file mode 100644 index 000000000..15023d945 --- /dev/null +++ b/host/lib/usrp/usrp1e/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 . +// + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/* + * 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(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 +void uhd::usrp::usrp1e::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(bit_file, gpio_init_b, gpio_done); +} diff --git a/host/lib/usrp/usrp1e/usrp1e_none.cpp b/host/lib/usrp/usrp1e/usrp1e_none.cpp index 1c8cf9a5b..ac0b12a75 100644 --- a/host/lib/usrp/usrp1e/usrp1e_none.cpp +++ b/host/lib/usrp/usrp1e/usrp1e_none.cpp @@ -32,3 +32,7 @@ device_addrs_t usrp1e::discover(const device_addr_t &){ device::sptr usrp1e::make(const device_addr_t &){ throw std::runtime_error("this build has no usrp1e support"); } + +void usrp1e::load_fpga(const std::string &){ + throw std::runtime_error("this build has no usrp1e support"); +} -- cgit v1.2.3 From 1b965831ae7588c7879d84de4e5fbd78ca614761 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Fri, 26 Feb 2010 11:01:19 +0000 Subject: made app to load usrp1e fpga images, and tested it to be working --- host/apps/CMakeLists.txt | 4 ++- host/apps/usrp1e_load_fpga.cpp | 47 +++++++++++++++++++++++++++++++++ host/lib/usrp/usrp1e/fpga-downloader.cc | 6 ++--- 3 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 host/apps/usrp1e_load_fpga.cpp (limited to 'host/lib/usrp/usrp1e') diff --git a/host/apps/CMakeLists.txt b/host/apps/CMakeLists.txt index f4428f958..a7068e5a4 100644 --- a/host/apps/CMakeLists.txt +++ b/host/apps/CMakeLists.txt @@ -16,7 +16,9 @@ # ADD_EXECUTABLE(discover_usrps discover_usrps.cpp) - TARGET_LINK_LIBRARIES(discover_usrps uhd) +ADD_EXECUTABLE(usrp1e_load_fpga usrp1e_load_fpga.cpp) +TARGET_LINK_LIBRARIES(usrp1e_load_fpga uhd) + INSTALL(TARGETS discover_usrps RUNTIME DESTINATION ${RUNTIME_DIR}) diff --git a/host/apps/usrp1e_load_fpga.cpp b/host/apps/usrp1e_load_fpga.cpp new file mode 100644 index 000000000..d5960b391 --- /dev/null +++ b/host/apps/usrp1e_load_fpga.cpp @@ -0,0 +1,47 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +#include +#include +#include +#include + +namespace po = boost::program_options; + +int main(int argc, char *argv[]){ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("file", po::value(), "path to fpga bin file") + ; + + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help") or vm.count("file") == 0){ + std::cout << boost::format("USRP1E Load FPGA %s") % desc << std::endl; + return ~0; + } + + //load the fpga + std::string file = vm["file"].as(); + uhd::usrp::usrp1e::load_fpga(file); + + return 0; +} diff --git a/host/lib/usrp/usrp1e/fpga-downloader.cc b/host/lib/usrp/usrp1e/fpga-downloader.cc index 15023d945..f7c78b875 100644 --- a/host/lib/usrp/usrp1e/fpga-downloader.cc +++ b/host/lib/usrp/usrp1e/fpga-downloader.cc @@ -43,7 +43,7 @@ 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"; +//static std::string bit_file = "safe_u1e.bin"; const int BUF_SIZE = 4096; @@ -198,7 +198,7 @@ void spidev::send(char *buf, char *rbuf, unsigned int nbytes) } -static void send_file_to_fpga(std::string &file_name, gpio &error, gpio &done) +static void send_file_to_fpga(const std::string &file_name, gpio &error, gpio &done) { std::ifstream bitstream; @@ -258,5 +258,5 @@ void uhd::usrp::usrp1e::load_fpga(const std::string &bin_file){ std::cout << "Done = " << gpio_done.get_value() << std::endl; - send_file_to_fpga(bit_file, gpio_init_b, gpio_done); + send_file_to_fpga(bin_file, gpio_init_b, gpio_done); } -- cgit v1.2.3