From ff1546f8137f7f92bb250f685561b0c34cc0e053 Mon Sep 17 00:00:00 2001 From: Ben Hilburn Date: Fri, 14 Feb 2014 12:05:07 -0800 Subject: Pushing the bulk of UHD-3.7.0 code. --- host/utils/usrp_x3xx_fpga_burner.cpp | 47 ++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'host/utils/usrp_x3xx_fpga_burner.cpp') diff --git a/host/utils/usrp_x3xx_fpga_burner.cpp b/host/utils/usrp_x3xx_fpga_burner.cpp index 07bc63559..2f0202e84 100644 --- a/host/utils/usrp_x3xx_fpga_burner.cpp +++ b/host/utils/usrp_x3xx_fpga_burner.cpp @@ -15,6 +15,7 @@ // along with this program. If not, see . // +#include #include #include #include @@ -81,6 +82,22 @@ namespace po = boost::program_options; using namespace uhd; using namespace uhd::transport; +static int num_ctrl_c = 0; +void sig_int_handler(int){ + num_ctrl_c++; + if(num_ctrl_c == 1){ + std::cout << std::endl << "Are you sure you want to abort the image burning? If you do, your " + "USRP-X series device will be bricked!" << std::endl + << "Press Ctrl+C again to abort the image burning procedure." << std::endl << std::endl; + } + else{ + std::cout << std::endl << "Aborting. Your USRP X-Series device will be bricked." << std::endl + << "Refer to http://files.ettus.com/uhd_docs/manual/html/usrp_x3x0.html#use-jtag-to-load-fpga-images" << std::endl + << "for details on restoring your device." << std::endl; + exit(EXIT_FAILURE); + } +} + typedef struct { boost::uint32_t flags; boost::uint32_t sector; @@ -232,21 +249,16 @@ void ethernet_burn(udp_simple::sptr udp_transport, std::string fpga_path, bool v throw std::runtime_error("Failed to start image burning! Did you specify the correct IP address? If so, power-cycle the device and try again."); } - std::cout << "Progress: " << std::flush; - - int percentage = -1; - int last_percentage = -1; size_t current_pos = 0; + size_t sectors = fpga_image_size / X300_FLASH_SECTOR_SIZE; //Each sector for(size_t i = 0; i < fpga_image_size; i += X300_FLASH_SECTOR_SIZE){ - //Print percentage at beginning of first sector after each 10% - percentage = int(double(i)/double(fpga_image_size)*100); - if((percentage != last_percentage) and (percentage % 10 == 0)){ //Don't print same percentage twice - std::cout << percentage << "%..." << std::flush; - } - last_percentage = percentage; + //Print progress percentage at beginning of each sector + std::cout << "\rProgress: " << int(double(i)/double(fpga_image_size)*100) + << "% (" << (i / X300_FLASH_SECTOR_SIZE) << "/" + << sectors << " sectors)" << std::flush; //Each packet for(size_t j = i; (j < fpga_image_size and j < (i+X300_FLASH_SECTOR_SIZE)); j += X300_PACKET_SIZE_BYTES){ @@ -256,7 +268,7 @@ void ethernet_burn(udp_simple::sptr udp_transport, std::string fpga_path, bool v if(verify) send_packet.flags |= X300_FPGA_PROG_FLAGS_VERIFY; if(j == i) send_packet.flags |= X300_FPGA_PROG_FLAGS_ERASE; //Erase the sector before writing send_packet.flags = htonx(send_packet.flags); - + send_packet.sector = htonx(X300_FPGA_SECTOR_START + (i/X300_FLASH_SECTOR_SIZE)); send_packet.index = htonx((j % X300_FLASH_SECTOR_SIZE) / 2); send_packet.size = htonx(X300_PACKET_SIZE_BYTES / 2); @@ -297,10 +309,12 @@ void ethernet_burn(udp_simple::sptr udp_transport, std::string fpga_path, bool v for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){ send_packet.data[k] = htonx(send_packet.data[k]); } - + udp_transport->send(boost::asio::buffer(&send_packet, sizeof(send_packet))); - udp_transport->recv(boost::asio::buffer(x300_data_in_mem), UDP_TIMEOUT); + if (udp_transport->recv(boost::asio::buffer(x300_data_in_mem), UDP_TIMEOUT) == 0) + throw std::runtime_error("Timed out waiting for ACK!"); + const x300_fpga_update_data_t *update_data_in = reinterpret_cast(x300_data_in_mem); if((ntohl(update_data_in->flags) & X300_FPGA_PROG_FLAGS_ERROR) == X300_FPGA_PROG_FLAGS_ERROR){ @@ -319,14 +333,15 @@ void ethernet_burn(udp_simple::sptr udp_transport, std::string fpga_path, bool v memset(cleanup_packet.data, 0, sizeof(cleanup_packet.data)); udp_transport->send(boost::asio::buffer(&cleanup_packet, sizeof(cleanup_packet))); - udp_transport->recv(boost::asio::buffer(x300_data_in_mem), UDP_TIMEOUT); + if (udp_transport->recv(boost::asio::buffer(x300_data_in_mem), UDP_TIMEOUT) == 0) + throw std::runtime_error("Timed out waiting for ACK!"); const x300_fpga_update_data_t *cleanup_data_in = reinterpret_cast(x300_data_in_mem); if((ntohl(cleanup_data_in->flags) & X300_FPGA_PROG_FLAGS_ERROR) == X300_FPGA_PROG_FLAGS_ERROR){ throw std::runtime_error("Transfer or data verification failed!"); } - std::cout << "100%" << std::endl; + std::cout << "\rProgress: " << "100% (" << sectors << "/" << sectors << " sectors)" << std::endl; } void pcie_burn(std::string resource, std::string rpc_port, std::string fpga_path) @@ -460,7 +475,6 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ } } - /* * Check validity of image through extension */ @@ -469,6 +483,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){ throw std::runtime_error("The image filename must end in .bin, .bit, or .lvbitx."); } + std::signal(SIGINT, &sig_int_handler); if(vm.count("addr")){ udp_simple::sptr udp_transport = udp_simple::make_connected(ip_addr, BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT)); -- cgit v1.2.3