diff options
Diffstat (limited to 'host/lib')
| -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 | 
4 files changed, 86 insertions, 19 deletions
| 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 | 
