summaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/b200
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2013-11-27 15:12:46 -0800
committerBen Hilburn <ben.hilburn@ettus.com>2013-11-27 15:12:46 -0800
commitabc682eda8d84d5a366ca32ca87e81e0890e69e2 (patch)
tree214fad451457ac68198ded45524ea51fe557c98a /host/lib/usrp/b200
parent8ea4820ec0a7e45c61c2a14d9a76ee5d35d59382 (diff)
downloaduhd-abc682eda8d84d5a366ca32ca87e81e0890e69e2.tar.gz
uhd-abc682eda8d84d5a366ca32ca87e81e0890e69e2.tar.bz2
uhd-abc682eda8d84d5a366ca32ca87e81e0890e69e2.zip
Final merge of Balint's 'kitchen_sink' B200 fixes.
Diffstat (limited to 'host/lib/usrp/b200')
-rw-r--r--host/lib/usrp/b200/b200_iface.cpp252
-rw-r--r--host/lib/usrp/b200/b200_impl.hpp4
-rw-r--r--host/lib/usrp/b200/b200_io_impl.cpp4
3 files changed, 177 insertions, 83 deletions
diff --git a/host/lib/usrp/b200/b200_iface.cpp b/host/lib/usrp/b200/b200_iface.cpp
index 7a52f1969..b60c72fa8 100644
--- a/host/lib/usrp/b200/b200_iface.cpp
+++ b/host/lib/usrp/b200/b200_iface.cpp
@@ -63,6 +63,7 @@ const static boost::uint8_t B200_VREQ_FX3_RESET = 0x99;
const static boost::uint8_t B200_VREQ_EEPROM_WRITE = 0xBA;
const static boost::uint8_t B200_VREQ_EEPROM_READ = 0xBB;
+const static boost::uint8_t FX3_STATE_UNDEFINED = 0x00;
const static boost::uint8_t FX3_STATE_FPGA_READY = 0x01;
const static boost::uint8_t FX3_STATE_CONFIGURING_FPGA = 0x02;
const static boost::uint8_t FX3_STATE_BUSY = 0x03;
@@ -89,6 +90,9 @@ typedef boost::uint32_t hash_type;
*/
static hash_type generate_hash(const char *filename)
{
+ if (filename == NULL)
+ return hash_type(0);
+
std::ifstream file(filename);
if (not file){
throw uhd::io_error(std::string("cannot open input file ") + filename);
@@ -121,15 +125,15 @@ static hash_type generate_hash(const char *filename)
* \param record a line from an Intel HEX file
* \return true if record is valid, false otherwise
*/
-bool checksum(std::string *record) {
+bool checksum(const std::string& record) {
- size_t len = record->length();
+ size_t len = record.length();
unsigned int i;
unsigned char sum = 0;
unsigned int val;
for (i = 1; i < len; i += 2) {
- std::istringstream(record->substr(i, 2)) >> std::hex >> val;
+ std::istringstream(record.substr(i, 2)) >> std::hex >> val;
sum += val;
}
@@ -150,25 +154,25 @@ bool checksum(std::string *record) {
* \param data output data
* \return true if record is sucessfully read, false on error
*/
-bool parse_record(std::string *record, boost::uint16_t &len, \
+bool parse_record(const std::string& record, boost::uint16_t &len, \
boost::uint16_t &addr, boost::uint16_t &type, unsigned char* data) {
unsigned int i;
std::string _data;
unsigned int val;
- if (record->substr(0, 1) != ":")
+ if (record.substr(0, 1) != ":")
return false;
- std::istringstream(record->substr(1, 2)) >> std::hex >> len;
- std::istringstream(record->substr(3, 4)) >> std::hex >> addr;
- std::istringstream(record->substr(7, 2)) >> std::hex >> type;
+ std::istringstream(record.substr(1, 2)) >> std::hex >> len;
+ std::istringstream(record.substr(3, 4)) >> std::hex >> addr;
+ std::istringstream(record.substr(7, 2)) >> std::hex >> type;
if (len > (2 * (record->length() - 9))) // sanity check to prevent buffer overrun
return false;
for (i = 0; i < len; i++) {
- std::istringstream(record->substr(9 + 2 * i, 2)) >> std::hex >> val;
+ std::istringstream(record.substr(9 + 2 * i, 2)) >> std::hex >> val;
data[i] = (unsigned char) val;
}
@@ -183,19 +187,16 @@ class b200_iface_impl : public b200_iface{
public:
b200_iface_impl(usb_control::sptr usb_ctrl):
- _usb_ctrl(usb_ctrl)
- {
+ _usb_ctrl(usb_ctrl) {
//NOP
}
-
int fx3_control_write(boost::uint8_t request,
boost::uint16_t value,
boost::uint16_t index,
unsigned char *buff,
boost::uint16_t length,
- boost::int32_t timeout = 0)
- {
+ boost::int32_t timeout = 0) {
return _usb_ctrl->submit(VRT_VENDOR_OUT, // bmReqeustType
request, // bRequest
value, // wValue
@@ -205,14 +206,12 @@ public:
timeout); // timeout
}
-
int fx3_control_read(boost::uint8_t request,
boost::uint16_t value,
boost::uint16_t index,
unsigned char *buff,
boost::uint16_t length,
- boost::int32_t timeout = 0)
- {
+ boost::int32_t timeout = 0) {
return _usb_ctrl->submit(VRT_VENDOR_IN, // bmReqeustType
request, // bRequest
value, // wValue
@@ -222,7 +221,6 @@ public:
timeout); // timeout
}
-
void write_i2c(UHD_UNUSED(boost::uint16_t addr), UHD_UNUSED(const byte_vector_t &bytes))
{
throw uhd::not_implemented_error("b200 write i2c");
@@ -235,26 +233,33 @@ public:
}
void write_eeprom(boost::uint16_t addr, boost::uint16_t offset,
- const byte_vector_t &bytes)
- {
- fx3_control_write(B200_VREQ_EEPROM_WRITE,
+ const byte_vector_t &bytes) {
+ int ret = fx3_control_write(B200_VREQ_EEPROM_WRITE,
0, offset | (boost::uint16_t(addr) << 8),
(unsigned char *) &bytes[0],
bytes.size());
+
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to write EEPROM (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if ((size_t)ret != bytes.size())
+ throw uhd::io_error((boost::format("Short write on write EEPROM (expecting: %d, returned: %d)") % bytes.size() % ret).str());
}
byte_vector_t read_eeprom(
boost::uint16_t addr,
boost::uint16_t offset,
- size_t num_bytes
- ){
+ size_t num_bytes) {
byte_vector_t recv_bytes(num_bytes);
int bytes_read = fx3_control_read(B200_VREQ_EEPROM_READ,
0, offset | (boost::uint16_t(addr) << 8),
(unsigned char*) &recv_bytes[0],
num_bytes);
- if (bytes_read != num_bytes)
- throw uhd::io_error("Failed to read data from EEPROM.");
+
+ if (bytes_read < 0)
+ throw uhd::io_error((boost::format("Failed to read EEPROM (%d: %s)") % bytes_read % libusb_error_name(bytes_read)).str());
+ else if ((size_t)bytes_read != num_bytes)
+ throw uhd::io_error((boost::format("Short read on read EEPROM (expecting: %d, returned: %d)") % num_bytes % bytes_read).str());
+
return recv_bytes;
}
@@ -262,8 +267,7 @@ public:
unsigned char *tx_data,
size_t num_tx_bits,
unsigned char *rx_data,
- size_t num_rx_bits
- ){
+ size_t num_rx_bits) {
int ret = 0;
boost::uint16_t tx_length = num_tx_bits / 8;
@@ -275,9 +279,10 @@ public:
0x00, tx_data, tx_length);
}
- if(ret < 0) {
- throw uhd::io_error("transact_spi: fx3_control_write failed!");
- }
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to write SPI (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != tx_length)
+ throw uhd::io_error((boost::format("Short write on write SPI (expecting: %d, returned: %d)") % tx_length % ret).str());
if(num_rx_bits) {
@@ -286,24 +291,37 @@ public:
ret = fx3_control_read(B200_VREQ_LOOP, 0x00, \
0x00, rx_data, total_length);
- if(ret < 0) {
- throw uhd::io_error("transact_spi: readback failed!");
- }
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to readback (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != total_length)
+ throw uhd::io_error((boost::format("Short read on readback (expecting: %d, returned: %d)") % total_length % ret).str());
}
}
void ad9361_transact(const unsigned char in_buff[64], unsigned char out_buff[64]) {
- fx3_control_write(B200_VREQ_AD9361_CTRL_WRITE, 0x00, 0x00, (unsigned char *)in_buff, 64);
- int ret = 0;
- for (size_t i = 0; i < 30; i++)
+ const int bytes_to_write = 64;
+ const int bytes_to_read = 64;
+ const size_t read_retries = 30;
+
+ int ret = fx3_control_write(B200_VREQ_AD9361_CTRL_WRITE, 0x00, 0x00, (unsigned char *)in_buff, bytes_to_write);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to write AD9361 (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_write)
+ throw uhd::io_error((boost::format("Short write on write AD9361 (expecting: %d, returned: %d)") % bytes_to_write % ret).str());
+
+ for (size_t i = 0; i < read_retries; i++)
{
- ret = fx3_control_read(B200_VREQ_AD9361_CTRL_READ, 0x00, 0x00, out_buff, 64, 1000);
- if (ret == 64) return;
+ ret = fx3_control_read(B200_VREQ_AD9361_CTRL_READ, 0x00, 0x00, out_buff, bytes_to_read, 1000);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to read AD9361 (%d: %s)") % ret % libusb_error_name(ret)).str());
+
+ if (ret == bytes_to_read)
+ return;
}
- throw uhd::io_error(str(boost::format("ad9361_transact failed with usb error: %d") % ret));
+
+ throw uhd::io_error(str(boost::format("Failed to read complete AD9361 (expecting: %d, last read: %d)") % bytes_to_read % ret));
}
-
void load_firmware(const std::string filestring, UHD_UNUSED(bool force) = false)
{
const char *filename = filestring.c_str();
@@ -338,7 +356,7 @@ public:
continue;
/* Check for valid Intel HEX record. */
- if (!checksum(&record) || !parse_record(&record, len, \
+ if (!checksum(record) || !parse_record(record, len, \
lower_address_bits, type, data)) {
throw uhd::io_error("fx3_load_firmware: bad intel hex record checksum");
}
@@ -411,48 +429,74 @@ public:
throw uhd::io_error("fx3_load_firmware: No EOF record found.");
}
-
void reset_fx3(void) {
unsigned char data[4];
memset(data, 0x00, sizeof(data));
+ const int bytes_to_send = sizeof(data);
- fx3_control_write(B200_VREQ_FX3_RESET, 0x00, 0x00, data, 4);
+ int ret = fx3_control_write(B200_VREQ_FX3_RESET, 0x00, 0x00, data, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to reset FX3 (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on reset FX3 (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
void reset_gpif(void) {
unsigned char data[4];
memset(data, 0x00, sizeof(data));
+ const int bytes_to_send = sizeof(data);
- fx3_control_write(B200_VREQ_GPIF_RESET, 0x00, 0x00, data, 4);
+ int ret = fx3_control_write(B200_VREQ_GPIF_RESET, 0x00, 0x00, data, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to reset GPIF (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on reset GPIF (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
- void set_fpga_reset_pin(const bool reset)
- {
+ void set_fpga_reset_pin(const bool reset) {
unsigned char data[4];
memset(data, (reset)? 0xFF : 0x00, sizeof(data));
+ const int bytes_to_send = sizeof(data);
UHD_THROW_INVALID_CODE_PATH();
// Below is dead code as long as UHD_THROW_INVALID_CODE_PATH(); is declared above.
// It is preserved here in a comment in case it is needed later:
- // fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, 4);
+ /*
+ int ret = fx3_control_write(B200_VREQ_FPGA_RESET, 0x00, 0x00, data, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to reset FPGA (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on reset FPGA (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
+ */
}
boost::uint8_t get_usb_speed(void) {
unsigned char rx_data[1];
+ memset(rx_data, 0x00, sizeof(rx_data));
+ const int bytes_to_recv = sizeof(rx_data);
- fx3_control_read(B200_VREQ_GET_USB, 0x00, 0x00, rx_data, 1);
+ int ret = fx3_control_read(B200_VREQ_GET_USB, 0x00, 0x00, rx_data, bytes_to_recv);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get USB speed (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get USB speed (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
return boost::lexical_cast<boost::uint8_t>(rx_data[0]);
}
-
boost::uint8_t get_fx3_status(void) {
unsigned char rx_data[1];
+ memset(rx_data, 0x00, sizeof(rx_data));
+ const int bytes_to_recv = sizeof(rx_data);
- fx3_control_read(B200_VREQ_GET_STATUS, 0x00, 0x00, &rx_data[0], 1);
+ int ret = fx3_control_read(B200_VREQ_GET_STATUS, 0x00, 0x00, rx_data, bytes_to_recv);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get FX3 status (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get FX3 status (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
return boost::lexical_cast<boost::uint8_t>(rx_data[0]);
}
@@ -460,40 +504,72 @@ public:
boost::uint16_t get_compat_num(void) {
unsigned char rx_data[2];
+ memset(rx_data, 0x00, sizeof(rx_data));
+ const int bytes_to_recv = sizeof(rx_data);
- fx3_control_read(B200_VREQ_GET_COMPAT , 0x00, 0x00, rx_data, 2);
-
- boost::uint16_t compat = 0x0000;
- compat |= (((uint16_t) rx_data[0]) << 8);
- compat |= (rx_data[1] & 0x00FF);
+ int ret = fx3_control_read(B200_VREQ_GET_COMPAT , 0x00, 0x00, rx_data, bytes_to_recv);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get compat num (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get compat num (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
- return compat;
+ return (((uint16_t)rx_data[0]) << 8) | rx_data[1];
}
void usrp_get_firmware_hash(hash_type &hash) {
- fx3_control_read(B200_VREQ_GET_FW_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4, 500);
+ const int bytes_to_recv = 4;
+ if (sizeof(hash_type) != bytes_to_recv)
+ throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_recv).str());
+
+ int ret = fx3_control_read(B200_VREQ_GET_FW_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_recv, 500);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get firmware hash (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get firmware hash (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
}
void usrp_set_firmware_hash(hash_type hash) {
- fx3_control_write(B200_VREQ_SET_FW_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4);
+ const int bytes_to_send = 4;
+ if (sizeof(hash_type) != bytes_to_send)
+ throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_send).str());
+
+ int ret = fx3_control_write(B200_VREQ_SET_FW_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to set firmware hash (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on set firmware hash (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
void usrp_get_fpga_hash(hash_type &hash) {
- fx3_control_read(B200_VREQ_GET_FPGA_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4, 500);
+ const int bytes_to_recv = 4;
+ if (sizeof(hash_type) != bytes_to_recv)
+ throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_recv).str());
+
+ int ret = fx3_control_read(B200_VREQ_GET_FPGA_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_recv, 500);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to get FPGA hash (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_recv)
+ throw uhd::io_error((boost::format("Short read on get FPGA hash (expecting: %d, returned: %d)") % bytes_to_recv % ret).str());
}
void usrp_set_fpga_hash(hash_type hash) {
- fx3_control_write(B200_VREQ_SET_FPGA_HASH, 0x00, 0x00,
- (unsigned char*) &hash, 4);
+ const int bytes_to_send = 4;
+ if (sizeof(hash_type) != bytes_to_send)
+ throw uhd::type_error((boost::format("hash_type is %d bytes but transfer length is %d bytes") % sizeof(hash_type) % bytes_to_send).str());
+
+ int ret = fx3_control_write(B200_VREQ_SET_FPGA_HASH, 0x00, 0x00, (unsigned char*) &hash, bytes_to_send);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to set FPGA hash (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_send)
+ throw uhd::io_error((boost::format("Short write on set FPGA hash (expecting: %d, returned: %d)") % bytes_to_send % ret).str());
}
boost::uint32_t load_fpga(const std::string filestring) {
boost::uint8_t fx3_state = 0;
boost::uint32_t wait_count;
+ int ret = 0;
+ int bytes_to_xfer = 0;
const char *filename = filestring.c_str();
@@ -515,9 +591,12 @@ public:
// Request loopback read, which will indicate the firmware's current control request buffer size
// Make sure that if operating as USB2, requested length is within spec
- int nread = fx3_control_read(B200_VREQ_LOOP, 0, 0, out_buff, std::min(transfer_size, (int)sizeof(out_buff)), 1000);
- if (nread <= 0)
- throw uhd::io_error("load_fpga: unable to complete firmware loopback request.");
+ int ntoread = std::min(transfer_size, (int)sizeof(out_buff));
+ int nread = fx3_control_read(B200_VREQ_LOOP, 0, 0, out_buff, ntoread, 1000);
+ if (nread < 0)
+ throw uhd::io_error((boost::format("load_fpga: unable to complete firmware loopback request (%d: %s)") % nread % libusb_error_name(nread)).str());
+ else if (nread != ntoread)
+ throw uhd::io_error((boost::format("load_fpga: short read on firmware loopback request (expecting: %d, returned: %d)") % ntoread % nread).str());
transfer_size = std::min(transfer_size, nread); // Select the smaller value
size_t file_size = 0;
@@ -529,18 +608,26 @@ public:
std::ifstream file;
file.open(filename, std::ios::in | std::ios::binary);
- if(!file.good()) {
+ if (!file.good()) {
throw uhd::io_error("load_fpga: cannot open FPGA input file.");
}
+
+ // Zero the hash, in case we abort programming another image and revert to the previously programmed image
+ usrp_set_fpga_hash(0);
memset(out_buff, 0x00, sizeof(out_buff));
- fx3_control_write(B200_VREQ_FPGA_CONFIG, 0, 0, out_buff, 1, 1000);
+ bytes_to_xfer = 1;
+ ret = fx3_control_write(B200_VREQ_FPGA_CONFIG, 0, 0, out_buff, bytes_to_xfer, 1000);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to start FPGA config (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_xfer)
+ throw uhd::io_error((boost::format("Short write on start FPGA config (expecting: %d, returned: %d)") % bytes_to_xfer % ret).str());
wait_count = 0;
do {
fx3_state = get_fx3_status();
- if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR)) {
+ if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) {
return fx3_state;
}
@@ -552,13 +639,18 @@ public:
if (load_img_msg) UHD_MSG(status) << "Loading FPGA image: " \
<< filestring << "..." << std::flush;
- fx3_control_write(B200_VREQ_FPGA_START, 0, 0, out_buff, 1, 1000);
+ bytes_to_xfer = 1;
+ ret = fx3_control_write(B200_VREQ_FPGA_START, 0, 0, out_buff, bytes_to_xfer, 1000);
+ if (ret < 0)
+ throw uhd::io_error((boost::format("Failed to start FPGA bitstream (%d: %s)") % ret % libusb_error_name(ret)).str());
+ else if (ret != bytes_to_xfer)
+ throw uhd::io_error((boost::format("Short write on start FPGA bitstream (expecting: %d, returned: %d)") % bytes_to_xfer % ret).str());
wait_count = 0;
do {
fx3_state = get_fx3_status();
- if((wait_count >= 1000) || (fx3_state == FX3_STATE_ERROR)) {
+ if((wait_count >= 1000) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) {
return fx3_state;
}
@@ -568,19 +660,20 @@ public:
} while(fx3_state != FX3_STATE_CONFIGURING_FPGA);
size_t bytes_sent = 0;
- while(!file.eof()) {
+ while (!file.eof()) {
file.read((char *) out_buff, transfer_size);
const std::streamsize n = file.gcount();
- if(n == 0) continue;
+ if(n == 0)
+ continue;
boost::uint16_t transfer_count = boost::uint16_t(n);
/* Send the data to the device. */
int nwritten = fx3_control_write(B200_VREQ_FPGA_DATA, 0, 0, out_buff, transfer_count, 5000);
- if (nwritten <= 0)
- throw uhd::io_error("load_fpga: cannot write bitstream to FX3.");
+ if (nwritten < 0)
+ throw uhd::io_error((boost::format("load_fpga: cannot write bitstream to FX3 (%d: %s)") % nwritten % libusb_error_name(nwritten)).str());
else if (nwritten != transfer_count)
- throw uhd::io_error("load_fpga: short write while transferring bitstream to FX3.");
+ throw uhd::io_error((boost::format("load_fpga: short write while transferring bitstream to FX3 (expecting: %d, returned: %d)") % transfer_count % nwritten).str());
if (load_img_msg)
{
@@ -601,7 +694,7 @@ public:
do {
fx3_state = get_fx3_status();
- if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR)) {
+ if((wait_count >= 500) || (fx3_state == FX3_STATE_ERROR) || (fx3_state == FX3_STATE_UNDEFINED)) {
return fx3_state;
}
@@ -612,7 +705,8 @@ public:
usrp_set_fpga_hash(hash);
- if (load_img_msg) UHD_MSG(status) << "\b\b\b\b done" << std::endl;
+ if (load_img_msg)
+ UHD_MSG(status) << "\b\b\b\b done" << std::endl;
return 0;
}
diff --git a/host/lib/usrp/b200/b200_impl.hpp b/host/lib/usrp/b200/b200_impl.hpp
index 362c45347..bee42679b 100644
--- a/host/lib/usrp/b200/b200_impl.hpp
+++ b/host/lib/usrp/b200/b200_impl.hpp
@@ -44,9 +44,9 @@
#include <uhd/transport/bounded_buffer.hpp>
#include <boost/weak_ptr.hpp>
#include "recv_packet_demuxer_3000.hpp"
-static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 0x03;
+static const boost::uint8_t B200_FW_COMPAT_NUM_MAJOR = 0x04;
static const boost::uint8_t B200_FW_COMPAT_NUM_MINOR = 0x00;
-static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x02;
+static const boost::uint16_t B200_FPGA_COMPAT_NUM = 0x03;
static const double B200_LINK_RATE_BPS = (5e9)/8; //practical link rate (5 Gbps)
static const double B200_BUS_CLOCK_RATE = 100e6;
static const double B200_DEFAULT_TICK_RATE = 32e6;
diff --git a/host/lib/usrp/b200/b200_io_impl.cpp b/host/lib/usrp/b200/b200_io_impl.cpp
index 4fe90bd4a..4768aa37b 100644
--- a/host/lib/usrp/b200/b200_io_impl.cpp
+++ b/host/lib/usrp/b200/b200_io_impl.cpp
@@ -249,14 +249,14 @@ rx_streamer::sptr b200_impl::get_rx_stream(const uhd::stream_args_t &args_)
//calculate packet size
static const size_t hdr_size = 0
+ vrt::max_if_hdr_words32*sizeof(boost::uint32_t)
- //+ sizeof(vrt::if_packet_info_t().tlr) //forced to have trailer
+ //+ sizeof(vrt::if_packet_info_t().tlr) //no longer using trailer
- sizeof(vrt::if_packet_info_t().cid) //no class id ever used
- sizeof(vrt::if_packet_info_t().tsi) //no int time ever used
;
const size_t bpp = _data_transport->get_recv_frame_size() - hdr_size;
const size_t bpi = convert::get_bytes_per_item(args.otw_format);
size_t spp = unsigned(args.args.cast<double>("spp", bpp/bpi));
- spp = std::min<size_t>(2000, spp); //magic maximum for framing at full rate
+ spp = std::min<size_t>(4092, spp); //FPGA FIFO maximum for framing at full rate
//make the new streamer given the samples per packet
if (not my_streamer) my_streamer = boost::make_shared<sph::recv_packet_streamer>(spp);