summaryrefslogtreecommitdiffstats
path: root/host/lib
diff options
context:
space:
mode:
authorNick Foster <nick@nerdnetworks.org>2010-09-29 17:51:16 -0700
committerNick Foster <nick@nerdnetworks.org>2010-09-29 17:51:16 -0700
commit9c58df56e805cc924aef980f466cd45a42b2d1a4 (patch)
treee9948fd27458df4d59a37378fc1137ace97a51f9 /host/lib
parent6fe533e19a29ea6cd241b70c38081499a8f3ba55 (diff)
parent83596f1feb73a15a1ef8741c1c520e8cae46c2a6 (diff)
downloaduhd-9c58df56e805cc924aef980f466cd45a42b2d1a4.tar.gz
uhd-9c58df56e805cc924aef980f466cd45a42b2d1a4.tar.bz2
uhd-9c58df56e805cc924aef980f466cd45a42b2d1a4.zip
Merge branch 'get_codec_rate' of ettus.sourcerepo.com:ettus/uhdpriv into tvrx_uhd
Diffstat (limited to 'host/lib')
-rw-r--r--host/lib/transport/libusb1_control.cpp2
-rw-r--r--host/lib/transport/libusb1_zero_copy.cpp140
-rw-r--r--host/lib/usrp/usrp1/dboard_iface.cpp5
-rw-r--r--host/lib/usrp/usrp1/usrp1_ctrl.cpp11
-rw-r--r--host/lib/usrp/usrp1/usrp1_impl.cpp41
-rw-r--r--host/lib/usrp/usrp2/dboard_iface.cpp4
6 files changed, 118 insertions, 85 deletions
diff --git a/host/lib/transport/libusb1_control.cpp b/host/lib/transport/libusb1_control.cpp
index c989a788c..f903907d0 100644
--- a/host/lib/transport/libusb1_control.cpp
+++ b/host/lib/transport/libusb1_control.cpp
@@ -33,7 +33,7 @@ public:
_handle->claim_interface(0 /* control interface */);
}
- size_t submit(boost::uint8_t request_type,
+ ssize_t submit(boost::uint8_t request_type,
boost::uint8_t request,
boost::uint16_t value,
boost::uint16_t index,
diff --git a/host/lib/transport/libusb1_zero_copy.cpp b/host/lib/transport/libusb1_zero_copy.cpp
index b089d11e0..f2dcff6b5 100644
--- a/host/lib/transport/libusb1_zero_copy.cpp
+++ b/host/lib/transport/libusb1_zero_copy.cpp
@@ -30,6 +30,9 @@ using namespace uhd::transport;
const int libusb_timeout = 0;
+static const size_t DEFAULT_NUM_XFERS = 16; //num xfers
+static const size_t DEFAULT_XFER_SIZE = 32*512; //bytes
+
/***********************************************************************
* Helper functions
***********************************************************************/
@@ -56,7 +59,7 @@ void pp_transfer(libusb_transfer *lut)
* create a bidirectional interface. It is a zero copy implementation
* with respect to libusb, however, each send and recv requires a copy
* operation from kernel to userspace; this is due to the usbfs
- * interface provided by the kernel.
+ * interface provided by the kernel.
**********************************************************************/
class usb_endpoint {
public:
@@ -107,7 +110,7 @@ private:
//! a list of shared arrays for the transfer buffers
std::vector<boost::shared_array<boost::uint8_t> > _buffers;
- // Calls for processing asynchronous I/O
+ // Calls for processing asynchronous I/O
libusb_transfer *allocate_transfer(int buff_len);
void print_transfer_status(libusb_transfer *lut);
};
@@ -142,7 +145,7 @@ void usb_endpoint::callback_handle_transfer(libusb_transfer *lut){
* Constructor
* Allocate libusb transfers and mark as free. For IN endpoints,
* submit the transfers so that they're ready to return when
- * data is available.
+ * data is available.
*/
usb_endpoint::usb_endpoint(
libusb::device_handle::sptr handle,
@@ -194,7 +197,7 @@ usb_endpoint::~usb_endpoint(void){
/*
- * Allocate a libusb transfer
+ * Allocate a libusb transfer
* The allocated transfer - and buffer it contains - is repeatedly
* submitted, reaped, and reused and should not be freed until shutdown.
* \param buff_len size of the individual buffer held by each transfer
@@ -225,7 +228,7 @@ libusb_transfer *usb_endpoint::allocate_transfer(int buff_len){
* Asynchonous transfer submission
* Submit a libusb transfer to libusb add pending status
* \param lut pointer to libusb_transfer
- * \return true on success or false on error
+ * \return true on success or false on error
*/
void usb_endpoint::submit(libusb_transfer *lut){
UHD_ASSERT_THROW(libusb_submit_transfer(lut) == 0);
@@ -281,14 +284,14 @@ libusb_transfer *usb_endpoint::get_lut_with_wait(size_t timeout_ms){
}
/***********************************************************************
- * Managed buffers
+ * Managed buffers
**********************************************************************/
/*
* Libusb managed receive buffer
* Construct a recv buffer from a libusb transfer. The memory held by
* the libusb transfer is exposed through the managed buffer interface.
* Upon destruction, the transfer and buffer are resubmitted to the
- * endpoint for further use.
+ * endpoint for further use.
*/
class libusb_managed_recv_buffer_impl : public managed_recv_buffer {
public:
@@ -307,7 +310,7 @@ public:
private:
const boost::asio::const_buffer &get() const
{
- return _buff;
+ return _buff;
}
libusb_transfer *_lut;
@@ -327,9 +330,8 @@ private:
class libusb_managed_send_buffer_impl : public managed_send_buffer {
public:
libusb_managed_send_buffer_impl(libusb_transfer *lut,
- usb_endpoint::sptr endpoint,
- size_t buff_size)
- : _buff(lut->buffer, buff_size), _committed(false)
+ usb_endpoint::sptr endpoint)
+ : _buff(lut->buffer, lut->length), _committed(false)
{
_lut = lut;
_endpoint = endpoint;
@@ -349,7 +351,7 @@ public:
std::cerr << "UHD: send buffer already committed" << std::endl;
return 0;
}
-
+
UHD_ASSERT_THROW(num_bytes <= boost::asio::buffer_size(_buff));
_lut->length = num_bytes;
@@ -369,7 +371,7 @@ public:
private:
const boost::asio::mutable_buffer &get() const
{
- return _buff;
+ return _buff;
}
libusb_transfer *_lut;
@@ -385,61 +387,71 @@ private:
class libusb_zero_copy_impl : public usb_zero_copy
{
private:
- usb_endpoint::sptr _rx_ep, _tx_ep;
-
libusb::device_handle::sptr _handle;
-
- size_t _recv_buff_size;
- size_t _send_buff_size;
- size_t _num_frames;
+ size_t _recv_num_frames, _send_num_frames;
+ usb_endpoint::sptr _recv_ep, _send_ep;
public:
typedef boost::shared_ptr<libusb_zero_copy_impl> sptr;
- libusb_zero_copy_impl(libusb::device_handle::sptr handle,
- unsigned int rx_endpoint,
- unsigned int tx_endpoint,
- size_t recv_buff_size,
- size_t send_buff_size);
+ libusb_zero_copy_impl(
+ libusb::device_handle::sptr handle,
+ unsigned int recv_endpoint, unsigned int send_endpoint,
+ size_t recv_xfer_size, size_t recv_num_xfers,
+ size_t send_xfer_size, size_t send_num_xfers
+ );
managed_recv_buffer::sptr get_recv_buff(void);
managed_send_buffer::sptr get_send_buff(void);
- size_t get_num_recv_frames(void) const { return _num_frames; }
- size_t get_num_send_frames(void) const { return _num_frames; }
+ size_t get_num_recv_frames(void) const { return _recv_num_frames; }
+ size_t get_num_send_frames(void) const { return _send_num_frames; }
};
/*
* Constructor
* Initializes libusb, opens devices, and sets up interfaces for I/O.
- * Finally, creates endpoints for asynchronous I/O.
+ * Finally, creates endpoints for asynchronous I/O.
*/
-libusb_zero_copy_impl::libusb_zero_copy_impl(libusb::device_handle::sptr handle,
- unsigned int rx_endpoint,
- unsigned int tx_endpoint,
- size_t buff_size,
- size_t block_size)
- : _handle(handle),
- _recv_buff_size(block_size), _send_buff_size(block_size),
- _num_frames(buff_size / block_size)
-{
- _handle->claim_interface(2 /*in interface*/);
+libusb_zero_copy_impl::libusb_zero_copy_impl(
+ libusb::device_handle::sptr handle,
+ unsigned int recv_endpoint, unsigned int send_endpoint,
+ size_t recv_xfer_size, size_t recv_num_xfers,
+ size_t send_xfer_size, size_t send_num_xfers
+){
+ _handle = handle;
+
+ //if the sizes are left at 0 (automatic) -> use the defaults
+ if (recv_xfer_size == 0) recv_xfer_size = DEFAULT_XFER_SIZE;
+ if (recv_num_xfers == 0) recv_num_xfers = DEFAULT_NUM_XFERS;
+ if (send_xfer_size == 0) send_xfer_size = DEFAULT_XFER_SIZE;
+ if (send_num_xfers == 0) send_num_xfers = DEFAULT_NUM_XFERS;
+
+ //sanity check the transfer sizes
+ UHD_ASSERT_THROW(recv_xfer_size % 512 == 0);
+ UHD_ASSERT_THROW(send_xfer_size % 512 == 0);
+
+ //store the num xfers for the num frames count
+ _recv_num_frames = recv_num_xfers;
+ _send_num_frames = send_num_xfers;
+
+ _handle->claim_interface(2 /*in interface*/);
_handle->claim_interface(1 /*out interface*/);
- _rx_ep = usb_endpoint::sptr(new usb_endpoint(
+ _recv_ep = usb_endpoint::sptr(new usb_endpoint(
_handle, // libusb device_handle
- rx_endpoint, // USB endpoint number
+ recv_endpoint, // USB endpoint number
true, // IN endpoint
- _recv_buff_size, // buffer size per transfer
- _num_frames // number of libusb transfers
+ recv_xfer_size, // buffer size per transfer
+ recv_num_xfers // number of libusb transfers
));
- _tx_ep = usb_endpoint::sptr(new usb_endpoint(
+ _send_ep = usb_endpoint::sptr(new usb_endpoint(
_handle, // libusb device_handle
- tx_endpoint, // USB endpoint number
+ send_endpoint, // USB endpoint number
false, // OUT endpoint
- _send_buff_size, // buffer size per transfer
- _num_frames // number of libusb transfers
+ send_xfer_size, // buffer size per transfer
+ send_num_xfers // number of libusb transfers
));
}
@@ -447,17 +459,17 @@ libusb_zero_copy_impl::libusb_zero_copy_impl(libusb::device_handle::sptr handle,
* Construct a managed receive buffer from a completed libusb transfer
* (happy with buffer full of data) obtained from the receive endpoint.
* Return empty pointer if no transfer is available (timeout or error).
- * \return pointer to a managed receive buffer
+ * \return pointer to a managed receive buffer
*/
managed_recv_buffer::sptr libusb_zero_copy_impl::get_recv_buff(void){
- libusb_transfer *lut = _rx_ep->get_lut_with_wait(/* TODO timeout API */);
+ libusb_transfer *lut = _recv_ep->get_lut_with_wait(/* TODO timeout API */);
if (lut == NULL) {
return managed_recv_buffer::sptr();
}
else {
return managed_recv_buffer::sptr(
new libusb_managed_recv_buffer_impl(lut,
- _rx_ep));
+ _recv_ep));
}
}
@@ -466,38 +478,36 @@ managed_recv_buffer::sptr libusb_zero_copy_impl::get_recv_buff(void){
* Construct a managed send buffer from a free libusb transfer (with
* empty buffer). Return empty pointer of no transfer is available
* (timeout or error).
- * \return pointer to a managed send buffer
+ * \return pointer to a managed send buffer
*/
managed_send_buffer::sptr libusb_zero_copy_impl::get_send_buff(void){
- libusb_transfer *lut = _tx_ep->get_lut_with_wait(/* TODO timeout API */);
+ libusb_transfer *lut = _send_ep->get_lut_with_wait(/* TODO timeout API */);
if (lut == NULL) {
return managed_send_buffer::sptr();
}
else {
return managed_send_buffer::sptr(
new libusb_managed_send_buffer_impl(lut,
- _tx_ep,
- _send_buff_size));
+ _send_ep));
}
}
-
/***********************************************************************
* USB zero_copy make functions
**********************************************************************/
-usb_zero_copy::sptr usb_zero_copy::make(usb_device_handle::sptr handle,
- unsigned int rx_endpoint,
- unsigned int tx_endpoint,
- size_t buff_size,
- size_t block_size)
-
-{
+usb_zero_copy::sptr usb_zero_copy::make(
+ usb_device_handle::sptr handle,
+ unsigned int recv_endpoint, unsigned int send_endpoint,
+ size_t recv_xfer_size, size_t recv_num_xfers,
+ size_t send_xfer_size, size_t send_num_xfers
+){
libusb::device_handle::sptr dev_handle(libusb::device_handle::get_cached_handle(
boost::static_pointer_cast<libusb::special_handle>(handle)->get_device()
));
- return sptr(new libusb_zero_copy_impl(dev_handle,
- rx_endpoint,
- tx_endpoint,
- buff_size,
- block_size));
+ return sptr(new libusb_zero_copy_impl(
+ dev_handle,
+ recv_endpoint, send_endpoint,
+ recv_xfer_size, recv_num_xfers,
+ send_xfer_size, send_num_xfers
+ ));
}
diff --git a/host/lib/usrp/usrp1/dboard_iface.cpp b/host/lib/usrp/usrp1/dboard_iface.cpp
index 4791b55ce..4f0549a37 100644
--- a/host/lib/usrp/usrp1/dboard_iface.cpp
+++ b/host/lib/usrp/usrp1/dboard_iface.cpp
@@ -93,6 +93,7 @@ public:
std::vector<double> get_clock_rates(unit_t);
double get_clock_rate(unit_t);
void set_clock_enabled(unit_t, bool);
+ double get_codec_rate(unit_t);
private:
usrp1_iface::sptr _iface;
@@ -170,6 +171,10 @@ void usrp1_dboard_iface::set_clock_enabled(unit_t, bool)
//TODO we can only enable for special case anyway...
}
+double usrp1_dboard_iface::get_codec_rate(unit_t){
+ return _clock->get_master_clock_freq();
+}
+
/***********************************************************************
* GPIO
**********************************************************************/
diff --git a/host/lib/usrp/usrp1/usrp1_ctrl.cpp b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
index 76e8ce368..5043aed7d 100644
--- a/host/lib/usrp/usrp1/usrp1_ctrl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_ctrl.cpp
@@ -180,7 +180,7 @@ public:
unsigned char reset_n = 0;
//hit the reset line
- if (load_img_msg) std::cout << "Loading firmware image " << filestring << "..." << std::flush;
+ if (load_img_msg) std::cout << "Loading firmware image: " << filestring << "..." << std::flush;
usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
&reset_y, 1);
@@ -209,9 +209,9 @@ public:
}
//type 0x01 is end
else if (type == 0x01) {
+ usrp_set_firmware_hash(hash); //set hash before reset
usrp_control_write(FX2_FIRMWARE_LOAD, 0xe600, 0,
&reset_n, 1);
- usrp_set_firmware_hash(hash);
file.close();
//wait for things to settle
@@ -267,11 +267,12 @@ public:
return -1;
}
- ssize_t n;
- while ((n = file.readsome((char *)buf, sizeof(buf))) > 0) {
+ while (not file.eof()) {
+ file.read((char *)buf, sizeof(buf));
+ size_t n = file.gcount();
ret = usrp_control_write(VRQ_FPGA_LOAD, 0, FL_XFER,
buf, n);
- if (ret != n) {
+ if (ret < 0 or size_t(ret) != n) {
std::cerr << "fpga load error " << ret << std::endl;
file.close();
return -1;
diff --git a/host/lib/usrp/usrp1/usrp1_impl.cpp b/host/lib/usrp/usrp1/usrp1_impl.cpp
index 80ea49e9d..793e3027d 100644
--- a/host/lib/usrp/usrp1/usrp1_impl.cpp
+++ b/host/lib/usrp/usrp1/usrp1_impl.cpp
@@ -30,6 +30,7 @@
#include <boost/assign/list_of.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread/thread.hpp>
+#include <boost/lexical_cast.hpp>
#include <iostream>
using namespace uhd;
@@ -74,14 +75,14 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
boost::uint16_t vid = hint.has_key("uninit") ? FX2_VENDOR_ID : USRP1_VENDOR_ID;
boost::uint16_t pid = hint.has_key("uninit") ? FX2_PRODUCT_ID : USRP1_PRODUCT_ID;
- //see what we got on the USB bus
- std::vector<usb_device_handle::sptr> device_list =
- usb_device_handle::get_device_list(vid, pid);
-
- if(device_list.size() == 0) return usrp1_addrs; //return nothing if no USRPs found
+ // Important note:
+ // The get device list calls are nested inside the for loop.
+ // This allows the usb guts to decontruct when not in use,
+ // so that re-enumeration after fw load can occur successfully.
+ // This requirement is a courtesy of libusb1.0 on windows.
//find the usrps and load firmware
- BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
usb_control::sptr ctrl_transport = usb_control::make(handle);
usrp_ctrl::sptr usrp_ctrl = usrp_ctrl::make(ctrl_transport);
usrp_ctrl->usrp_load_firmware(usrp1_fw_image);
@@ -90,9 +91,8 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
//get descriptors again with serial number, but using the initialized VID/PID now since we have firmware
vid = USRP1_VENDOR_ID;
pid = USRP1_PRODUCT_ID;
- device_list = usb_device_handle::get_device_list(vid, pid);
- BOOST_FOREACH(usb_device_handle::sptr handle, device_list) {
+ BOOST_FOREACH(usb_device_handle::sptr handle, usb_device_handle::get_device_list(vid, pid)) {
device_addr_t new_addr;
new_addr["type"] = "usrp1";
new_addr["serial"] = handle->get_serial();
@@ -108,6 +108,15 @@ static device_addrs_t usrp1_find(const device_addr_t &hint)
/***********************************************************************
* Make
**********************************************************************/
+template<typename output_type> static output_type cast_from_dev_addr(
+ const device_addr_t &device_addr,
+ const std::string &key,
+ output_type def_val
+){
+ return (device_addr.has_key(key))?
+ boost::lexical_cast<output_type>(device_addr[key]) : def_val;
+}
+
static device::sptr usrp1_make(const device_addr_t &device_addr)
{
//extract the FPGA path for the USRP1
@@ -131,11 +140,15 @@ static device::sptr usrp1_make(const device_addr_t &device_addr)
usrp_ctrl = usrp_ctrl::make(ctrl_transport);
usrp_ctrl->usrp_load_fpga(usrp1_fpga_image);
- data_transport = usb_zero_copy::make(handle, // identifier
- 6, // IN endpoint
- 2, // OUT endpoint
- 2 * (1 << 20), // buffer size
- 16384); // transfer size
+ data_transport = usb_zero_copy::make(
+ handle, // identifier
+ 6, // IN endpoint
+ 2, // OUT endpoint
+ size_t(cast_from_dev_addr<double>(device_addr, "recv_xfer_size", 0)),
+ size_t(cast_from_dev_addr<double>(device_addr, "recv_num_xfers", 0)),
+ size_t(cast_from_dev_addr<double>(device_addr, "send_xfer_size", 0)),
+ size_t(cast_from_dev_addr<double>(device_addr, "send_num_xfers", 0))
+ );
break;
}
}
@@ -174,7 +187,7 @@ usrp1_impl::usrp1_impl(uhd::transport::usb_zero_copy::sptr data_transport,
//initialize the mboard
mboard_init();
- //initialize the dboards
+ //initialize the dboards
dboard_init();
//initialize the dsps
diff --git a/host/lib/usrp/usrp2/dboard_iface.cpp b/host/lib/usrp/usrp2/dboard_iface.cpp
index f6d2b718a..fdfbf0d17 100644
--- a/host/lib/usrp/usrp2/dboard_iface.cpp
+++ b/host/lib/usrp/usrp2/dboard_iface.cpp
@@ -61,6 +61,7 @@ public:
double get_clock_rate(unit_t);
std::vector<double> get_clock_rates(unit_t);
void set_clock_enabled(unit_t, bool);
+ double get_codec_rate(unit_t);
void write_spi(
unit_t unit,
@@ -158,6 +159,9 @@ void usrp2_dboard_iface::set_clock_enabled(unit_t unit, bool enb){
}
}
+double usrp2_dboard_iface::get_codec_rate(unit_t){
+ return _clock_ctrl->get_master_clock_rate();
+}
/***********************************************************************
* GPIO
**********************************************************************/