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/usrp1e_none.cpp') 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 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/usrp1e_none.cpp') 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