diff options
-rw-r--r-- | host/lib/usrp/usrp_e100/usrp_e100_impl.cpp | 70 | ||||
-rw-r--r-- | host/usrp_e_utils/usrp-e-utility.cpp | 3 |
2 files changed, 34 insertions, 39 deletions
diff --git a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp index 5fba0c153..e9e9b6e20 100644 --- a/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp +++ b/host/lib/usrp/usrp_e100/usrp_e100_impl.cpp @@ -76,6 +76,15 @@ static device_addrs_t usrp_e100_find(const device_addr_t &hint){ /*********************************************************************** * Make **********************************************************************/ +static size_t hash_fpga_file(const std::string &file_path){ + size_t hash = 0; + std::ifstream file(file_path.c_str()); + if (not file.good()) throw uhd::io_error("cannot open fpga file for read: " + file_path); + while (file.good()) boost::hash_combine(hash, file.get()); + file.close(); + return hash; +} + static device::sptr usrp_e100_make(const device_addr_t &device_addr){ //setup the main interface into fpga @@ -83,55 +92,44 @@ static device::sptr usrp_e100_make(const device_addr_t &device_addr){ UHD_MSG(status) << boost::format("Opening USRP-E on %s") % node << std::endl; usrp_e100_iface::sptr iface = usrp_e100_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. - //------------------------------------------------------------------ - static const char *hash_file_path = "/tmp/usrp_e100_hash"; - //extract the fpga path for usrp-e - std::string usrp_e100_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_e100_fpga_image.c_str()); - if (not file.good()) throw uhd::io_error( - "cannot open fpga file for read: " + usrp_e100_fpga_image - ); - do{ - boost::hash_combine(fpga_hash, file.get()); - } while (file.good()); - file.close(); - } + std::string usrp_e100_fpga_image = find_image_path(device_addr.get("fpga", "usrp_e100_fpga.bin")); - //read the compatibility number - boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + //compute a hash of the fpga file + const boost::uint32_t file_hash = boost::uint32_t(hash_fpga_file(usrp_e100_fpga_image)); - //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_FPGA_COMPAT_NUM or loaded_hash != fpga_hash){ + //When the hash does not match: + // - unload the iface to free the node + // - load the fpga configuration file + // - re-open the iface on the node + if (iface->peek32(UE_REG_RB_MISC_TEST32) != file_hash){ iface.reset(); usrp_e100_load_fpga(usrp_e100_fpga_image); sleep(1); ///\todo do this better one day. UHD_MSG(status) << boost::format("re-Opening USRP-E on %s") % node << std::endl; iface = usrp_e100_iface::make(node); - try{std::ofstream(hash_file_path) << fpga_hash;}catch(...){} + } + + //store the hash into the FPGA register + iface->poke32(UE_REG_SR_MISC_TEST32, file_hash); + + //check that the hash can be readback correctly + if (iface->peek32(UE_REG_RB_MISC_TEST32) != file_hash){ + UHD_MSG(error) << boost::format( + "The FPGA hash readback failed!\n" + "The FPGA is either clocked improperly\n" + "or the FPGA build is not compatible.\n" + ); } //check that the compatibility is correct - fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); + const boost::uint16_t fpga_compat_num = iface->peek16(UE_REG_MISC_COMPAT); if (fpga_compat_num != USRP_E_FPGA_COMPAT_NUM){ throw uhd::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." + "\nPlease update the FPGA image for your device.\n" + "See the application notes for USRP E-Series for instructions.\n" + "Expected FPGA compatibility number 0x%x, but got 0x%x:\n" + "The FPGA build is not compatible with the host code build." ) % USRP_E_FPGA_COMPAT_NUM % fpga_compat_num)); } diff --git a/host/usrp_e_utils/usrp-e-utility.cpp b/host/usrp_e_utils/usrp-e-utility.cpp index b926cf49d..47a2c0900 100644 --- a/host/usrp_e_utils/usrp-e-utility.cpp +++ b/host/usrp_e_utils/usrp-e-utility.cpp @@ -64,9 +64,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ " usrp-e-utility --reclk --fpga=/usr/share/uhd/images/usrp_e1xx_pt_fpga.bin" ); clock_genconfig_main(); - if (std::system("rm /tmp/usrp*hash") != 0){ //clear hash so driver must reload - std::cerr << "No hash to remove! Don't worry, its not a problem." << std::endl; - } } std::cout << "Done!" << std::endl; |