aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/x300/x300_image_loader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/x300/x300_image_loader.cpp')
-rw-r--r--host/lib/usrp/x300/x300_image_loader.cpp545
1 files changed, 287 insertions, 258 deletions
diff --git a/host/lib/usrp/x300/x300_image_loader.cpp b/host/lib/usrp/x300/x300_image_loader.cpp
index 4e2c9e580..5cb1f1b85 100644
--- a/host/lib/usrp/x300/x300_image_loader.cpp
+++ b/host/lib/usrp/x300/x300_image_loader.cpp
@@ -5,28 +5,25 @@
// SPDX-License-Identifier: GPL-3.0-or-later
//
-#include <fstream>
-#include <vector>
-
-#include <boost/algorithm/string.hpp>
-#include <boost/filesystem.hpp>
-#include <boost/property_tree/ptree.hpp>
-#include <boost/property_tree/xml_parser.hpp>
-
+#include "cdecode.h"
+#include "x300_fw_common.h"
+#include "x300_impl.hpp"
#include <uhd/config.hpp>
#include <uhd/device.hpp>
-#include <uhd/image_loader.hpp>
#include <uhd/exception.hpp>
-#include <uhd/transport/udp_simple.hpp>
+#include <uhd/image_loader.hpp>
#include <uhd/transport/nirio/niusrprio_session.h>
#include <uhd/transport/nirio/status.h>
+#include <uhd/transport/udp_simple.hpp>
#include <uhd/utils/byteswap.hpp>
#include <uhd/utils/paths.hpp>
#include <uhd/utils/static.hpp>
-
-#include "x300_impl.hpp"
-#include "x300_fw_common.h"
-#include "cdecode.h"
+#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+#include <fstream>
+#include <vector>
namespace fs = boost::filesystem;
@@ -50,65 +47,81 @@ using namespace uhd::transport;
/*
* Bitstream header pattern
*/
-static const uint8_t X300_FPGA_BIT_HEADER[] =
-{
- 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0,
- 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61, 0x00
-};
+static const uint8_t X300_FPGA_BIT_HEADER[] = {0x00,
+ 0x09,
+ 0x0f,
+ 0xf0,
+ 0x0f,
+ 0xf0,
+ 0x0f,
+ 0xf0,
+ 0x0f,
+ 0xf0,
+ 0x00,
+ 0x00,
+ 0x01,
+ 0x61,
+ 0x00};
/*
* Packet structure
*/
-typedef struct {
+typedef struct
+{
uint32_t flags;
uint32_t sector;
uint32_t index;
uint32_t size;
union {
- uint8_t data8[X300_PACKET_SIZE_BYTES];
- uint16_t data16[X300_PACKET_SIZE_BYTES/2];
+ uint8_t data8[X300_PACKET_SIZE_BYTES];
+ uint16_t data16[X300_PACKET_SIZE_BYTES / 2];
};
} x300_fpga_update_data_t;
/*
* X-Series burn session
*/
-typedef struct {
- bool found;
- bool ethernet;
- bool configure; // Reload FPGA after burning to flash (Ethernet only)
- bool verify; // Device will verify the download along the way (Ethernet only)
- bool download; // Host will read the FPGA image on the device to a file
- bool lvbitx;
- uhd::device_addr_t dev_addr;
- std::string ip_addr;
- std::string fpga_type;
- std::string resource;
- std::string filepath;
- std::string outpath;
- std::string rpc_port;
- udp_simple::sptr write_xport;
- udp_simple::sptr read_xport;
- size_t size;
- uint8_t data_in[udp_simple::mtu];
- std::vector<char> bitstream; // .bin image extracted from .lvbitx file
+typedef struct
+{
+ bool found;
+ bool ethernet;
+ bool configure; // Reload FPGA after burning to flash (Ethernet only)
+ bool verify; // Device will verify the download along the way (Ethernet only)
+ bool download; // Host will read the FPGA image on the device to a file
+ bool lvbitx;
+ uhd::device_addr_t dev_addr;
+ std::string ip_addr;
+ std::string fpga_type;
+ std::string resource;
+ std::string filepath;
+ std::string outpath;
+ std::string rpc_port;
+ udp_simple::sptr write_xport;
+ udp_simple::sptr read_xport;
+ size_t size;
+ uint8_t data_in[udp_simple::mtu];
+ std::vector<char> bitstream; // .bin image extracted from .lvbitx file
} x300_session_t;
/*
* Extract the .bin image from the given LVBITX file.
*/
-static void extract_from_lvbitx(x300_session_t &session){
- boost::property_tree::ptree pt;
- boost::property_tree::xml_parser::read_xml(session.filepath.c_str(), pt,
- boost::property_tree::xml_parser::no_comments |
- boost::property_tree::xml_parser::trim_whitespace);
+static void extract_from_lvbitx(x300_session_t& session)
+{
+ boost::property_tree::ptree pt;
+ boost::property_tree::xml_parser::read_xml(session.filepath.c_str(),
+ pt,
+ boost::property_tree::xml_parser::no_comments
+ | boost::property_tree::xml_parser::trim_whitespace);
const std::string encoded_bitstream(pt.get<std::string>("Bitfile.Bitstream"));
std::vector<char> decoded_bitstream(encoded_bitstream.size());
base64_decodestate decode_state;
base64_init_decodestate(&decode_state);
const size_t decoded_size = base64_decode_block(encoded_bitstream.c_str(),
- encoded_bitstream.size(), &decoded_bitstream.front(), &decode_state);
+ encoded_bitstream.size(),
+ &decoded_bitstream.front(),
+ &decode_state);
decoded_bitstream.resize(decoded_size);
session.bitstream.swap(decoded_bitstream);
@@ -118,118 +131,122 @@ static void extract_from_lvbitx(x300_session_t &session){
/*
* Validate X300 image and extract if LVBITX.
*/
-static void x300_validate_image(x300_session_t &session){
- if(not fs::exists(session.filepath)){
- throw uhd::runtime_error(str(boost::format("Could not find image at path \"%s\".")
- % session.filepath));
+static void x300_validate_image(x300_session_t& session)
+{
+ if (not fs::exists(session.filepath)) {
+ throw uhd::runtime_error(str(
+ boost::format("Could not find image at path \"%s\".") % session.filepath));
}
std::string extension = fs::extension(session.filepath);
- session.lvbitx = (extension == ".lvbitx");
+ session.lvbitx = (extension == ".lvbitx");
- if(session.lvbitx){
+ if (session.lvbitx) {
extract_from_lvbitx(session);
- if(session.size > X300_FPGA_BIN_SIZE_BYTES){
- throw uhd::runtime_error(str(boost::format("The specified FPGA image is too large: %d vs. %d")
- % session.size % X300_FPGA_BIN_SIZE_BYTES));
+ if (session.size > X300_FPGA_BIN_SIZE_BYTES) {
+ throw uhd::runtime_error(
+ str(boost::format("The specified FPGA image is too large: %d vs. %d")
+ % session.size % X300_FPGA_BIN_SIZE_BYTES));
}
/*
* PCIe burning just takes a filepath, even for a .lvbitx file,
* so just extract it to validate the size.
*/
- if(!session.ethernet) session.bitstream.clear();
- }
- else if(extension == ".bin" or extension == ".bit"){
+ if (!session.ethernet)
+ session.bitstream.clear();
+ } else if (extension == ".bin" or extension == ".bit") {
uint32_t max_size = (extension == ".bin") ? X300_FPGA_BIN_SIZE_BYTES
- : X300_FPGA_BIT_SIZE_BYTES;
+ : X300_FPGA_BIT_SIZE_BYTES;
session.size = fs::file_size(session.filepath);
- if(session.size > max_size){
- throw uhd::runtime_error(str(boost::format("The specified FPGA image is too large: %d vs. %d")
- % session.size % max_size));
+ if (session.size > max_size) {
+ throw uhd::runtime_error(
+ str(boost::format("The specified FPGA image is too large: %d vs. %d")
+ % session.size % max_size));
return;
}
- }
- else{
- throw uhd::runtime_error(str(boost::format("Invalid extension \"%s\". Extension must be .bin, .bit, or .lvbitx.")
- % extension));
+ } else {
+ throw uhd::runtime_error(
+ str(boost::format(
+ "Invalid extension \"%s\". Extension must be .bin, .bit, or .lvbitx.")
+ % extension));
}
}
-static void x300_setup_session(x300_session_t &session,
- const device_addr_t &args,
- const std::string &filepath,
- const std::string &outpath){
+static void x300_setup_session(x300_session_t& session,
+ const device_addr_t& args,
+ const std::string& filepath,
+ const std::string& outpath)
+{
device_addrs_t devs = x300_find(args);
- if(devs.size() == 0){
+ if (devs.size() == 0) {
session.found = false;
return;
- }
- else if(devs.size() > 1){
- std::string err_msg = "Could not resolve given args to a single X-Series device.\n"
- "Applicable devices:\n";
-
- for(const uhd::device_addr_t &dev: devs){
- std::string identifier = dev.has_key("addr") ? "addr"
- : "resource";
-
- err_msg += str(boost::format(" * %s (%s=%s)\n")
- % dev.get("product", "X3XX")
- % identifier
- % dev.get(identifier));
+ } else if (devs.size() > 1) {
+ std::string err_msg =
+ "Could not resolve given args to a single X-Series device.\n"
+ "Applicable devices:\n";
+
+ for (const uhd::device_addr_t& dev : devs) {
+ std::string identifier = dev.has_key("addr") ? "addr" : "resource";
+
+ err_msg += str(boost::format(" * %s (%s=%s)\n") % dev.get("product", "X3XX")
+ % identifier % dev.get(identifier));
}
- err_msg += "\nSpecify one of these devices with the given args to load an image onto it.";
+ err_msg += "\nSpecify one of these devices with the given args to load an image "
+ "onto it.";
throw uhd::runtime_error(err_msg);
}
- session.found = true;
+ session.found = true;
session.dev_addr = devs[0];
session.ethernet = session.dev_addr.has_key("addr");
- if(session.ethernet){
- session.ip_addr = session.dev_addr["addr"];
- session.configure = args.has_key("configure");
- session.write_xport = udp_simple::make_connected(session.ip_addr,
- BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT));
- session.read_xport = udp_simple::make_connected(session.ip_addr,
- BOOST_STRINGIZE(X300_FPGA_READ_UDP_PORT));
- session.verify = args.has_key("verify");
+ if (session.ethernet) {
+ session.ip_addr = session.dev_addr["addr"];
+ session.configure = args.has_key("configure");
+ session.write_xport = udp_simple::make_connected(
+ session.ip_addr, BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT));
+ session.read_xport = udp_simple::make_connected(
+ session.ip_addr, BOOST_STRINGIZE(X300_FPGA_READ_UDP_PORT));
+ session.verify = args.has_key("verify");
session.download = args.has_key("download");
- }
- else{
+ } else {
session.resource = session.dev_addr["resource"];
session.rpc_port = args.get("rpc-port", "5444");
}
/*
- * The user can specify an FPGA type (1G, HGS, XGS), rather than a filename. If the user
- * does not specify one, this will default to the type currently on the device. If this
- * cannot be determined, then the user is forced to specify a filename.
+ * The user can specify an FPGA type (1G, HGS, XGS), rather than a filename. If the
+ * user does not specify one, this will default to the type currently on the device.
+ * If this cannot be determined, then the user is forced to specify a filename.
*/
session.fpga_type = args.get("fpga", session.dev_addr.get("fpga", ""));
- if(filepath == ""){
- if(!session.dev_addr.has_key("product") or session.fpga_type == ""){
- throw uhd::runtime_error("Found a device but could not auto-generate an image filename.");
- }
- else session.filepath = find_image_path(str(boost::format("usrp_%s_fpga_%s.bit")
- % (to_lower_copy(session.dev_addr["product"]))
- % session.fpga_type));
- }
- else session.filepath = filepath;
+ if (filepath == "") {
+ if (!session.dev_addr.has_key("product") or session.fpga_type == "") {
+ throw uhd::runtime_error(
+ "Found a device but could not auto-generate an image filename.");
+ } else
+ session.filepath = find_image_path(
+ str(boost::format("usrp_%s_fpga_%s.bit")
+ % (to_lower_copy(session.dev_addr["product"])) % session.fpga_type));
+ } else
+ session.filepath = filepath;
/*
* The user can specify an output image path, or UHD will use the
* system temporary path by default
*/
- if(outpath == ""){
- if(!session.dev_addr.has_key("product") or session.fpga_type == ""){
- throw uhd::runtime_error("Found a device but could not auto-generate an image filename.");
+ if (outpath == "") {
+ if (!session.dev_addr.has_key("product") or session.fpga_type == "") {
+ throw uhd::runtime_error(
+ "Found a device but could not auto-generate an image filename.");
}
- std::string filename = str(boost::format("usrp_%s_fpga_%s")
- % (to_lower_copy(session.dev_addr["product"]))
- % session.fpga_type);
+ std::string filename =
+ str(boost::format("usrp_%s_fpga_%s")
+ % (to_lower_copy(session.dev_addr["product"])) % session.fpga_type);
session.outpath = get_tmp_path() + "/" + filename;
} else {
@@ -244,172 +261,180 @@ static void x300_setup_session(x300_session_t &session,
* Ethernet communication functions
*/
static UHD_INLINE size_t x300_send_and_recv(udp_simple::sptr xport,
- uint32_t pkt_code,
- x300_fpga_update_data_t *pkt_out,
- uint8_t* data){
+ uint32_t pkt_code,
+ x300_fpga_update_data_t* pkt_out,
+ uint8_t* data)
+{
pkt_out->flags = uhd::htonx<uint32_t>(pkt_code);
xport->send(boost::asio::buffer(pkt_out, sizeof(*pkt_out)));
return xport->recv(boost::asio::buffer(data, udp_simple::mtu), UDP_TIMEOUT);
}
-static UHD_INLINE bool x300_recv_ok(const x300_fpga_update_data_t *pkt_in,
- size_t len){
- return (len > 0 and
- ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR) != X300_FPGA_PROG_FLAGS_ERROR));
+static UHD_INLINE bool x300_recv_ok(const x300_fpga_update_data_t* pkt_in, size_t len)
+{
+ return (len > 0
+ and ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)
+ != X300_FPGA_PROG_FLAGS_ERROR));
}
// Image data needs to be bitswapped
-static UHD_INLINE void x300_bitswap(uint8_t *num){
+static UHD_INLINE void x300_bitswap(uint8_t* num)
+{
*num = ((*num & 0xF0) >> 4) | ((*num & 0x0F) << 4);
*num = ((*num & 0xCC) >> 2) | ((*num & 0x33) << 2);
*num = ((*num & 0xAA) >> 1) | ((*num & 0x55) << 1);
}
-static void x300_ethernet_load(x300_session_t &session){
-
+static void x300_ethernet_load(x300_session_t& session)
+{
// UDP receive buffer
x300_fpga_update_data_t pkt_out;
- const x300_fpga_update_data_t *pkt_in = reinterpret_cast<const x300_fpga_update_data_t*>(session.data_in);
+ const x300_fpga_update_data_t* pkt_in =
+ reinterpret_cast<const x300_fpga_update_data_t*>(session.data_in);
// Initialize write session
uint32_t flags = X300_FPGA_PROG_FLAGS_ACK | X300_FPGA_PROG_FLAGS_INIT;
- size_t len = x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in);
- if(x300_recv_ok(pkt_in, len)){
+ size_t len =
+ x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in);
+ if (x300_recv_ok(pkt_in, len)) {
std::cout << "-- Initializing FPGA loading..." << std::flush;
- }
- else if(len == 0){
+ } else if (len == 0) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else{
+ } else {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Device reported an error during initialization.");
}
std::cout << "successful." << std::endl;
- if(session.verify){
- std::cout << "-- NOTE: Device is verifying the image it is receiving, increasing the loading time." << std::endl;
+ if (session.verify) {
+ std::cout << "-- NOTE: Device is verifying the image it is receiving, increasing "
+ "the loading time."
+ << std::endl;
}
size_t current_pos = 0;
- size_t sectors = (session.size / X300_FLASH_SECTOR_SIZE);
+ size_t sectors = (session.size / X300_FLASH_SECTOR_SIZE);
std::ifstream image(session.filepath.c_str(), std::ios::binary);
// Each sector
- for(size_t i = 0; i < session.size; i += X300_FLASH_SECTOR_SIZE){
-
+ for (size_t i = 0; i < session.size; i += X300_FLASH_SECTOR_SIZE) {
// Print progress percentage at beginning of each sector
std::cout << boost::format("\r-- Loading %s FPGA image: %d%% (%d/%d sectors)")
- % session.fpga_type
- % (int(double(i) / double(session.size) * 100.0))
- % (i / X300_FLASH_SECTOR_SIZE)
- % sectors
- << std::flush;
+ % session.fpga_type
+ % (int(double(i) / double(session.size) * 100.0))
+ % (i / X300_FLASH_SECTOR_SIZE) % sectors
+ << std::flush;
// Each packet
- for(size_t j = i; (j < session.size and j < (i+X300_FLASH_SECTOR_SIZE)); j += X300_PACKET_SIZE_BYTES){
+ for (size_t j = i; (j < session.size and j < (i + X300_FLASH_SECTOR_SIZE));
+ j += X300_PACKET_SIZE_BYTES) {
flags = X300_FPGA_PROG_FLAGS_ACK;
- if(j == i) flags |= X300_FPGA_PROG_FLAGS_ERASE; // Erase at beginning of sector
- if(session.verify) flags |= X300_FPGA_PROG_FLAGS_VERIFY;
+ if (j == i)
+ flags |= X300_FPGA_PROG_FLAGS_ERASE; // Erase at beginning of sector
+ if (session.verify)
+ flags |= X300_FPGA_PROG_FLAGS_VERIFY;
// Set burn location
- pkt_out.sector = htonx<uint32_t>(X300_FPGA_SECTOR_START + (i/X300_FLASH_SECTOR_SIZE));
- pkt_out.index = htonx<uint32_t>((j % X300_FLASH_SECTOR_SIZE) / 2);
- pkt_out.size = htonx<uint32_t>(X300_PACKET_SIZE_BYTES / 2);
+ pkt_out.sector =
+ htonx<uint32_t>(X300_FPGA_SECTOR_START + (i / X300_FLASH_SECTOR_SIZE));
+ pkt_out.index = htonx<uint32_t>((j % X300_FLASH_SECTOR_SIZE) / 2);
+ pkt_out.size = htonx<uint32_t>(X300_PACKET_SIZE_BYTES / 2);
// Read next piece of image
memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES);
- if(session.lvbitx){
- memcpy(pkt_out.data8, &session.bitstream[current_pos], X300_PACKET_SIZE_BYTES);
+ if (session.lvbitx) {
+ memcpy(pkt_out.data8,
+ &session.bitstream[current_pos],
+ X300_PACKET_SIZE_BYTES);
current_pos += X300_PACKET_SIZE_BYTES;
- }
- else{
+ } else {
image.read((char*)pkt_out.data8, X300_PACKET_SIZE_BYTES);
}
// Data must be bitswapped and byteswapped
- for(size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++){
+ for (size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++) {
x300_bitswap(&pkt_out.data8[k]);
}
- for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){
+ for (size_t k = 0; k < (X300_PACKET_SIZE_BYTES / 2); k++) {
pkt_out.data16[k] = htonx<uint16_t>(pkt_out.data16[k]);
}
- len = x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in);
- if(len == 0){
- if(!session.lvbitx) image.close();
+ len =
+ x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in);
+ if (len == 0) {
+ if (!session.lvbitx)
+ image.close();
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else if((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)){
- if(!session.lvbitx) image.close();
+ } else if ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)) {
+ if (!session.lvbitx)
+ image.close();
throw uhd::runtime_error("Device reported an error.");
}
}
}
- if(!session.lvbitx){
+ if (!session.lvbitx) {
image.close();
}
std::cout << boost::format("\r-- Loading %s FPGA image: 100%% (%d/%d sectors)")
- % session.fpga_type
- % sectors
- % sectors
- << std::endl;
+ % session.fpga_type % sectors % sectors
+ << std::endl;
// Cleanup
- if(!session.lvbitx) image.close();
- flags = (X300_FPGA_PROG_FLAGS_CLEANUP | X300_FPGA_PROG_FLAGS_ACK);
+ if (!session.lvbitx)
+ image.close();
+ flags = (X300_FPGA_PROG_FLAGS_CLEANUP | X300_FPGA_PROG_FLAGS_ACK);
pkt_out.sector = pkt_out.index = pkt_out.size = 0;
memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES);
std::cout << "-- Finalizing image load..." << std::flush;
len = x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in);
- if(len == 0){
+ if (len == 0) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else if((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)){
+ } else if ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Device reported an error during cleanup.");
- }
- else std::cout << "successful." << std::endl;
+ } else
+ std::cout << "successful." << std::endl;
// Save new FPGA image (if option set)
- if(session.configure){
+ if (session.configure) {
flags = (X300_FPGA_PROG_CONFIGURE | X300_FPGA_PROG_FLAGS_ACK);
x300_send_and_recv(session.write_xport, flags, &pkt_out, session.data_in);
std::cout << "-- Saving image onto device..." << std::flush;
- if(len == 0){
+ if (len == 0) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else if((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)){
+ } else if ((ntohl(pkt_in->flags) & X300_FPGA_PROG_FLAGS_ERROR)) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Device reported an error while saving the image.");
- }
- else std::cout << "successful." << std::endl;
+ } else
+ std::cout << "successful." << std::endl;
}
- std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.") % session.dev_addr.get("product", "")) << std::endl;
+ std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.")
+ % session.dev_addr.get("product", ""))
+ << std::endl;
}
-static void x300_ethernet_read(x300_session_t &session){
-
+static void x300_ethernet_read(x300_session_t& session)
+{
// UDP receive buffer
x300_fpga_update_data_t pkt_out;
memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES);
- x300_fpga_update_data_t *pkt_in = reinterpret_cast<x300_fpga_update_data_t*>(session.data_in);
+ x300_fpga_update_data_t* pkt_in =
+ reinterpret_cast<x300_fpga_update_data_t*>(session.data_in);
// Initialize read session
uint32_t flags = X300_FPGA_READ_FLAGS_ACK | X300_FPGA_READ_FLAGS_INIT;
size_t len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in);
- if(x300_recv_ok(pkt_in, len)){
+ if (x300_recv_ok(pkt_in, len)) {
std::cout << "-- Initializing FPGA reading..." << std::flush;
- }
- else if(len == 0){
+ } else if (len == 0) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else{
+ } else {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Device reported an error during initialization.");
}
@@ -426,83 +451,79 @@ static void x300_ethernet_read(x300_session_t &session){
pkt_out.size = htonx<uint32_t>(X300_PACKET_SIZE_BYTES / 2);
len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in);
- if(len == 0){
+ if (len == 0) {
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else if((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)){
+ } else if ((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)) {
throw uhd::runtime_error("Device reported an error.");
}
// Data must be bitswapped and byteswapped
- for(size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++){
+ for (size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++) {
x300_bitswap(&pkt_in->data8[k]);
}
- for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){
+ for (size_t k = 0; k < (X300_PACKET_SIZE_BYTES / 2); k++) {
pkt_in->data16[k] = htonx<uint16_t>(pkt_in->data16[k]);
}
// Assume the largest size first
size_t image_size = X300_FPGA_BIT_SIZE_BYTES;
- size_t sectors = (image_size / X300_FLASH_SECTOR_SIZE);
+ size_t sectors = (image_size / X300_FLASH_SECTOR_SIZE);
std::string extension(".bit");
// Check for the beginning header sequence to determine
// the total amount of data (.bit vs .bin) on the flash
// The .bit file format includes header information not part of a .bin
- for (size_t i = 0; i < sizeof(X300_FPGA_BIT_HEADER); i++)
- {
- if (pkt_in->data8[i] != X300_FPGA_BIT_HEADER[i])
- {
- std::cout << "-- No *.bit header detected, FPGA image is a raw stream (*.bin)!" << std::endl;
+ for (size_t i = 0; i < sizeof(X300_FPGA_BIT_HEADER); i++) {
+ if (pkt_in->data8[i] != X300_FPGA_BIT_HEADER[i]) {
+ std::cout
+ << "-- No *.bit header detected, FPGA image is a raw stream (*.bin)!"
+ << std::endl;
image_size = X300_FPGA_BIN_SIZE_BYTES;
- sectors = (image_size / X300_FLASH_SECTOR_SIZE);
- extension = std::string(".bin");
+ sectors = (image_size / X300_FLASH_SECTOR_SIZE);
+ extension = std::string(".bin");
break;
}
}
session.outpath += extension;
std::ofstream image(session.outpath.c_str(), std::ios::binary);
- std::cout << boost::format("-- Output FPGA file: %s\n")
- % session.outpath;
+ std::cout << boost::format("-- Output FPGA file: %s\n") % session.outpath;
// Write the first packet
image.write((char*)pkt_in->data8, X300_PACKET_SIZE_BYTES);
// Each sector
size_t pkt_count = X300_PACKET_SIZE_BYTES;
- for(size_t i = 0; i < image_size; i += X300_FLASH_SECTOR_SIZE){
-
+ for (size_t i = 0; i < image_size; i += X300_FLASH_SECTOR_SIZE) {
// Once we determine the image size, print the progress percentage
std::cout << boost::format("\r-- Reading %s FPGA image: %d%% (%d/%d sectors)")
- % session.fpga_type
- % (int(double(i) / double(image_size) * 100.0))
- % (i / X300_FLASH_SECTOR_SIZE)
- % sectors
+ % session.fpga_type
+ % (int(double(i) / double(image_size) * 100.0))
+ % (i / X300_FLASH_SECTOR_SIZE) % sectors
<< std::flush;
// Each packet
- while (pkt_count < image_size and pkt_count < (i + X300_FLASH_SECTOR_SIZE))
- {
+ while (pkt_count < image_size and pkt_count < (i + X300_FLASH_SECTOR_SIZE)) {
// Set burn location
- pkt_out.sector = htonx<uint32_t>(X300_FPGA_SECTOR_START + (i/X300_FLASH_SECTOR_SIZE));
- pkt_out.index = htonx<uint32_t>((pkt_count % X300_FLASH_SECTOR_SIZE) / 2);
+ pkt_out.sector =
+ htonx<uint32_t>(X300_FPGA_SECTOR_START + (i / X300_FLASH_SECTOR_SIZE));
+ pkt_out.index = htonx<uint32_t>((pkt_count % X300_FLASH_SECTOR_SIZE) / 2);
- len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in);
- if(len == 0){
+ len =
+ x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in);
+ if (len == 0) {
image.close();
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else if((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)){
+ } else if ((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)) {
image.close();
throw uhd::runtime_error("Device reported an error.");
}
// Data must be bitswapped and byteswapped
- for(size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++){
+ for (size_t k = 0; k < X300_PACKET_SIZE_BYTES; k++) {
x300_bitswap(&pkt_in->data8[k]);
}
- for(size_t k = 0; k < (X300_PACKET_SIZE_BYTES/2); k++){
+ for (size_t k = 0; k < (X300_PACKET_SIZE_BYTES / 2); k++) {
pkt_in->data16[k] = htonx<uint16_t>(pkt_in->data16[k]);
}
@@ -510,8 +531,7 @@ static void x300_ethernet_read(x300_session_t &session){
// If this is the last packet, get rid of the extra zero padding
// due to packet size
size_t nbytes = X300_PACKET_SIZE_BYTES;
- if (pkt_count > (image_size - X300_PACKET_SIZE_BYTES))
- {
+ if (pkt_count > (image_size - X300_PACKET_SIZE_BYTES)) {
nbytes = (image_size - pkt_count);
}
@@ -526,85 +546,94 @@ static void x300_ethernet_read(x300_session_t &session){
}
std::cout << boost::format("\r-- Reading %s FPGA image: 100%% (%d/%d sectors)")
- % session.fpga_type
- % sectors
- % sectors
+ % session.fpga_type % sectors % sectors
<< std::endl;
// Cleanup
image.close();
- flags = (X300_FPGA_READ_FLAGS_CLEANUP | X300_FPGA_READ_FLAGS_ACK);
+ flags = (X300_FPGA_READ_FLAGS_CLEANUP | X300_FPGA_READ_FLAGS_ACK);
pkt_out.sector = pkt_out.index = pkt_out.size = 0;
memset(pkt_out.data8, 0, X300_PACKET_SIZE_BYTES);
std::cout << "-- Finalizing image read for verification..." << std::flush;
len = x300_send_and_recv(session.read_xport, flags, &pkt_out, session.data_in);
- if(len == 0){
+ if (len == 0) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Timed out waiting for reply from device.");
- }
- else if((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)){
+ } else if ((ntohl(pkt_in->flags) & X300_FPGA_READ_FLAGS_ERROR)) {
std::cout << "failed." << std::endl;
throw uhd::runtime_error("Device reported an error during cleanup.");
- }
- else std::cout << "successful image read." << std::endl;
+ } else
+ std::cout << "successful image read." << std::endl;
}
-static void x300_pcie_load(x300_session_t &session){
-
- std::cout << boost::format("\r-- Loading %s FPGA image (this will take 5-10 minutes)...")
- % session.fpga_type
- << std::flush;
+static void x300_pcie_load(x300_session_t& session)
+{
+ std::cout << boost::format(
+ "\r-- Loading %s FPGA image (this will take 5-10 minutes)...")
+ % session.fpga_type
+ << std::flush;
nirio_status status = NiRio_Status_Success;
niusrprio::niusrprio_session fpga_session(session.resource, session.rpc_port);
- nirio_status_chain(fpga_session.download_bitstream_to_flash(session.filepath), status);
+ nirio_status_chain(
+ fpga_session.download_bitstream_to_flash(session.filepath), status);
- if(nirio_status_fatal(status)){
+ if (nirio_status_fatal(status)) {
std::cout << "failed." << std::endl;
- niusrprio::nirio_status_to_exception(status, "NI-RIO reported the following error:");
- }
- else std::cout << "successful." << std::endl;
- std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.") % session.dev_addr.get("product", "")) << std::endl;
+ niusrprio::nirio_status_to_exception(
+ status, "NI-RIO reported the following error:");
+ } else
+ std::cout << "successful." << std::endl;
+ std::cout << str(boost::format("Power-cycle the USRP %s to use the new image.")
+ % session.dev_addr.get("product", ""))
+ << std::endl;
}
-static bool x300_image_loader(const image_loader::image_loader_args_t &image_loader_args){
+static bool x300_image_loader(const image_loader::image_loader_args_t& image_loader_args)
+{
// See if any X3x0 with the given args is found
device_addrs_t devs = x300_find(image_loader_args.args);
- if (devs.size() == 0) return false;
+ if (devs.size() == 0)
+ return false;
x300_session_t session;
x300_setup_session(session,
- image_loader_args.args,
- image_loader_args.fpga_path,
- image_loader_args.out_path);
+ image_loader_args.args,
+ image_loader_args.fpga_path,
+ image_loader_args.out_path);
- if(!session.found) return false;
+ if (!session.found)
+ return false;
std::cout << boost::format("Unit: USRP %s (%s, %s)\nFPGA Image: %s\n")
- % session.dev_addr["product"]
- % session.dev_addr["serial"]
- % session.dev_addr[session.ethernet ? "addr" : "resource"]
- % session.filepath;
+ % session.dev_addr["product"] % session.dev_addr["serial"]
+ % session.dev_addr[session.ethernet ? "addr" : "resource"]
+ % session.filepath;
// Download the FPGA image to a file
- if(image_loader_args.download) {
+ if (image_loader_args.download) {
std::cout << "Attempting to download the FPGA image ..." << std::endl;
x300_ethernet_read(session);
}
- if (not image_loader_args.load_fpga) return true;
+ if (not image_loader_args.load_fpga)
+ return true;
- if (session.ethernet) x300_ethernet_load(session);
- else x300_pcie_load(session);
+ if (session.ethernet)
+ x300_ethernet_load(session);
+ else
+ x300_pcie_load(session);
return true;
}
-UHD_STATIC_BLOCK(register_x300_image_loader){
- std::string recovery_instructions = "Aborting. Your USRP X-Series device will likely be unusable. Visit\n"
- "http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs_jtag\n"
- "for details on restoring your device.";
+UHD_STATIC_BLOCK(register_x300_image_loader)
+{
+ std::string recovery_instructions =
+ "Aborting. Your USRP X-Series device will likely be unusable. Visit\n"
+ "http://files.ettus.com/manual/page_usrp_x3x0.html#x3x0_load_fpga_imgs_jtag\n"
+ "for details on restoring your device.";
image_loader::register_image_loader("x300", x300_image_loader, recovery_instructions);
}