aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils')
-rw-r--r--host/utils/usrp_n2xx_simple_net_burner.cpp24
-rw-r--r--host/utils/usrp_x3xx_fpga_burner.cpp47
2 files changed, 53 insertions, 18 deletions
diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp
index 290612f8b..277e807d9 100644
--- a/host/utils/usrp_n2xx_simple_net_burner.cpp
+++ b/host/utils/usrp_n2xx_simple_net_burner.cpp
@@ -1,5 +1,5 @@
//
-// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2012-2014 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
@@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
+#include <csignal>
#include <iostream>
#include <map>
#include <fstream>
@@ -46,6 +47,25 @@ using namespace boost::algorithm;
using namespace uhd;
using namespace uhd::transport;
+/***********************************************************************
+ * Signal handlers
+ **********************************************************************/
+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-N Series unit 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-N Series unit will be bricked." << std::endl
+ << "Refer to http://files.ettus.com/uhd_docs/manual/html/usrp2.html#device-recovery-and-bricking" << std::endl
+ << "for details on restoring your device." << std::endl;
+ exit(EXIT_FAILURE);
+ }
+}
+
//Mapping revision numbers to filenames
std::map<boost::uint32_t, std::string> filename_map = boost::assign::map_list_of
(0xa, "n200_r3")
@@ -498,7 +518,7 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << boost::format(" * Sector size: %3.2f\n\n") % flash_info[0];
//Burning images
-
+ std::signal(SIGINT, &sig_int_handler);
if(burn_fpga){
erase_image(udp_transport, false, flash_info[1]);
write_image(udp_transport, false, fpga_image, flash_info[1], fpga_image_size);
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 <http://www.gnu.org/licenses/>.
//
+#include <csignal>
#include <iostream>
#include <map>
#include <fstream>
@@ -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<boost::uint32_t>(send_packet.flags);
-
+
send_packet.sector = htonx<boost::uint32_t>(X300_FPGA_SECTOR_START + (i/X300_FLASH_SECTOR_SIZE));
send_packet.index = htonx<boost::uint32_t>((j % X300_FLASH_SECTOR_SIZE) / 2);
send_packet.size = htonx<boost::uint32_t>(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<boost::uint16_t>(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<const x300_fpga_update_data_t *>(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<const x300_fpga_update_data_t *>(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));