diff options
| author | Josh Blum <josh@joshknows.com> | 2010-10-27 13:10:48 -0700 | 
|---|---|---|
| committer | Josh Blum <josh@joshknows.com> | 2010-10-27 13:10:48 -0700 | 
| commit | fa7704be20005a705efdc96aa785d80911638107 (patch) | |
| tree | c19fcf6e272468389371f116578f770278eac44d /host | |
| parent | 9585a0b6fd88efd2a8bd43c8b034ae21264b9fc4 (diff) | |
| download | uhd-fa7704be20005a705efdc96aa785d80911638107.tar.gz uhd-fa7704be20005a705efdc96aa785d80911638107.tar.bz2 uhd-fa7704be20005a705efdc96aa785d80911638107.zip | |
usrp-e: implemented fpga loading and compat checking
Diffstat (limited to 'host')
| -rw-r--r-- | host/examples/rx_to_file.cpp | 8 | ||||
| -rw-r--r-- | host/examples/rx_to_udp.cpp | 8 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/fpga-downloader.cc | 30 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_impl.cpp | 69 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_impl.hpp | 4 | ||||
| -rw-r--r-- | host/lib/usrp/usrp_e/usrp_e_regs.hpp | 2 | 
6 files changed, 94 insertions, 27 deletions
| diff --git a/host/examples/rx_to_file.cpp b/host/examples/rx_to_file.cpp index 79d3e9d8b..f08f7cee3 100644 --- a/host/examples/rx_to_file.cpp +++ b/host/examples/rx_to_file.cpp @@ -17,7 +17,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/simple_usrp.hpp> +#include <uhd/usrp/single_usrp.hpp>  #include <boost/program_options.hpp>  #include <boost/format.hpp>  #include <iostream> @@ -40,7 +40,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      po::options_description desc("Allowed options");      desc.add_options()          ("help", "help message") -        ("args", po::value<std::string>(&args)->default_value(""), "simple uhd device address args") +        ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")          ("secs", po::value<time_t>(&seconds_in_future)->default_value(3), "number of seconds in the future to receive")          ("nsamps", po::value<size_t>(&total_num_samps)->default_value(1000), "total number of samples to receive")          ("rxrate", po::value<double>(&rx_rate)->default_value(100e6/16), "rate of incoming samples") @@ -53,7 +53,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //print the help message      if (vm.count("help")){ -        std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; +        std::cout << boost::format("UHD RX to File %s") % desc << std::endl;          return ~0;      } @@ -62,7 +62,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); +    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args);      uhd::device::sptr dev = sdev->get_device();      std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; diff --git a/host/examples/rx_to_udp.cpp b/host/examples/rx_to_udp.cpp index 34b278599..c8b3d506b 100644 --- a/host/examples/rx_to_udp.cpp +++ b/host/examples/rx_to_udp.cpp @@ -17,7 +17,7 @@  #include <uhd/utils/thread_priority.hpp>  #include <uhd/utils/safe_main.hpp> -#include <uhd/usrp/simple_usrp.hpp> +#include <uhd/usrp/single_usrp.hpp>  #include <boost/program_options.hpp>  #include <boost/format.hpp>  #include <iostream> @@ -46,7 +46,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      po::options_description desc("Allowed options");      desc.add_options()          ("help", "help message") -        ("args", po::value<std::string>(&args)->default_value(""), "simple uhd device address args") +        ("args", po::value<std::string>(&args)->default_value(""), "single uhd device address args")          ("secs", po::value<time_t>(&seconds_in_future)->default_value(3), "number of seconds in the future to receive")          ("nsamps", po::value<size_t>(&total_num_samps)->default_value(1000), "total number of samples to receive")          ("rxrate", po::value<double>(&rx_rate)->default_value(100e6/16), "rate of incoming samples") @@ -61,7 +61,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //print the help message      if (vm.count("help")){ -        std::cout << boost::format("UHD RX Timed Samples %s") % desc << std::endl; +        std::cout << boost::format("UHD RX to UDP %s") % desc << std::endl;          return ~0;      } @@ -70,7 +70,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){      //create a usrp device      std::cout << std::endl;      std::cout << boost::format("Creating the usrp device with: %s...") % args << std::endl; -    uhd::usrp::simple_usrp::sptr sdev = uhd::usrp::simple_usrp::make(args); +    uhd::usrp::single_usrp::sptr sdev = uhd::usrp::single_usrp::make(args);      uhd::device::sptr dev = sdev->get_device();      std::cout << boost::format("Using Device: %s") % sdev->get_pp_string() << std::endl; diff --git a/host/lib/usrp/usrp_e/fpga-downloader.cc b/host/lib/usrp/usrp_e/fpga-downloader.cc index ff8671e98..b0d56e856 100644 --- a/host/lib/usrp/usrp_e/fpga-downloader.cc +++ b/host/lib/usrp/usrp_e/fpga-downloader.cc @@ -15,11 +15,14 @@  // along with this program.  If not, see <http://www.gnu.org/licenses/>.  // +#include <uhd/config.hpp> +  #include <iostream>  #include <sstream>  #include <fstream>  #include <string>  #include <cstdlib> +#include <stdexcept>  #include <fcntl.h>  #include <sys/types.h> @@ -82,8 +85,9 @@ 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; +	if (not export_file.is_open()) throw std::runtime_error( +		"Failed to open gpio export file." +	);  	export_file << gpio_num << std::endl; @@ -92,15 +96,17 @@ gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction)  	std::fstream direction_file;  	std::string direction_file_name; -	direction_file_name = base_path.str() + "/direction"; +	if (gpio_num != 114) { +		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; +		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; @@ -251,11 +257,11 @@ void usrp_e_load_fpga(const std::string &bin_file){  	gpio gpio_init_b(INIT_B, IN);  	gpio gpio_done  (DONE,   IN); -	std::cout << "FPGA config file: " << bin_file << std::endl; +	std::cout << "Loading FPGA image: " << bin_file << "... " << std::flush;  	prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); -	std::cout << "Done = " << gpio_done.get_value() << std::endl; +	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/usrp_e_impl.cpp b/host/lib/usrp/usrp_e/usrp_e_impl.cpp index 5c0e1dbb0..0a7295ff9 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.cpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.cpp @@ -16,13 +16,17 @@  //  #include "usrp_e_impl.hpp" +#include "usrp_e_regs.hpp"  #include <uhd/usrp/device_props.hpp>  #include <uhd/usrp/mboard_props.hpp>  #include <uhd/utils/assert.hpp>  #include <uhd/utils/static.hpp> +#include <uhd/utils/images.hpp>  #include <boost/format.hpp>  #include <boost/filesystem.hpp> +#include <boost/functional/hash.hpp>  #include <iostream> +#include <fstream>  using namespace uhd;  using namespace uhd::usrp; @@ -66,7 +70,64 @@ static device_addrs_t usrp_e_find(const device_addr_t &hint){   * Make   **********************************************************************/  static device::sptr usrp_e_make(const device_addr_t &device_addr){ -    return device::sptr(new usrp_e_impl(device_addr["node"])); + +    //The fpga is loaded when: +    // 1) The compatibility number matches. +    // 2) The hash in the hash-file matches. + +    //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. +    //------------------------------------------------------------------ + +    //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){ +        usrp_e_load_fpga(usrp_e_fpga_image); +        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){ @@ -76,11 +137,9 @@ UHD_STATIC_BLOCK(register_usrp_e_device){  /***********************************************************************   * Structors   **********************************************************************/ -usrp_e_impl::usrp_e_impl(const std::string &node){ -    std::cout << boost::format("Opening USRP-E on %s") % node << std::endl; +usrp_e_impl::usrp_e_impl(usrp_e_iface::sptr iface): _iface(iface){ -    //setup various interfaces into hardware -    _iface = usrp_e_iface::make(node); +    //setup interfaces into hardware      _clock_ctrl = usrp_e_clock_ctrl::make(_iface);      _codec_ctrl = usrp_e_codec_ctrl::make(_iface); diff --git a/host/lib/usrp/usrp_e/usrp_e_impl.hpp b/host/lib/usrp/usrp_e/usrp_e_impl.hpp index 9799cd645..421a9623d 100644 --- a/host/lib/usrp/usrp_e/usrp_e_impl.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_impl.hpp @@ -31,6 +31,8 @@  #define INCLUDED_USRP_E_IMPL_HPP  static const double MASTER_CLOCK_RATE = 64e6; //TODO get from clock control +static const char *hash_file_path = "/tmp/usrp_e100_hash"; +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); @@ -79,7 +81,7 @@ private:  class usrp_e_impl : public uhd::device{  public:      //structors -    usrp_e_impl(const std::string &node); +    usrp_e_impl(usrp_e_iface::sptr);      ~usrp_e_impl(void);      //the io interface diff --git a/host/lib/usrp/usrp_e/usrp_e_regs.hpp b/host/lib/usrp/usrp_e/usrp_e_regs.hpp index a4f42093e..f74358f00 100644 --- a/host/lib/usrp/usrp_e/usrp_e_regs.hpp +++ b/host/lib/usrp/usrp_e/usrp_e_regs.hpp @@ -30,7 +30,7 @@  #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_COMPAT     UE_REG_MISC_BASE + 12  /////////////////////////////////////////////////////  // Slave 1 -- UART | 
