aboutsummaryrefslogtreecommitdiffstats
path: root/host/lib/usrp/usrp2
diff options
context:
space:
mode:
Diffstat (limited to 'host/lib/usrp/usrp2')
-rw-r--r--host/lib/usrp/usrp2/dsp_impl.cpp12
-rw-r--r--host/lib/usrp/usrp2/fw_common.h1
-rw-r--r--host/lib/usrp/usrp2/io_impl.cpp86
-rw-r--r--host/lib/usrp/usrp2/usrp2_impl.hpp3
4 files changed, 73 insertions, 29 deletions
diff --git a/host/lib/usrp/usrp2/dsp_impl.cpp b/host/lib/usrp/usrp2/dsp_impl.cpp
index 22c00d99a..e5c4a4245 100644
--- a/host/lib/usrp/usrp2/dsp_impl.cpp
+++ b/host/lib/usrp/usrp2/dsp_impl.cpp
@@ -36,6 +36,10 @@ static uint32_t calculate_freq_word_and_update_actual_freq(freq_t &freq, freq_t
return freq_word;
}
+static uint32_t calculate_iq_scale_word(int16_t i, int16_t q){
+ return ((i & 0xffff) << 16) | ((q & 0xffff) << 0);
+}
+
void usrp2_impl::init_ddc_config(void){
//create the ddc in the rx dsp dict
_rx_dsps["ddc0"] = wax_obj_proxy(
@@ -61,6 +65,10 @@ void usrp2_impl::update_ddc_config(void){
calculate_freq_word_and_update_actual_freq(_ddc_freq, get_master_clock_freq())
);
out_data.data.ddc_args.decim = htonl(_ddc_decim);
+ static const uint32_t default_rx_scale_iq = 1024;
+ out_data.data.ddc_args.scale_iq = htonl(
+ calculate_iq_scale_word(default_rx_scale_iq, default_rx_scale_iq)
+ );
//send and recv
usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
@@ -209,7 +217,9 @@ void usrp2_impl::update_duc_config(void){
calculate_freq_word_and_update_actual_freq(_duc_freq, get_master_clock_freq())
);
out_data.data.duc_args.interp = htonl(_duc_interp);
- out_data.data.duc_args.scale_iq = htonl(scale);
+ out_data.data.duc_args.scale_iq = htonl(
+ calculate_iq_scale_word(scale, scale)
+ );
//send and recv
usrp2_ctrl_data_t in_data = ctrl_send_and_recv(out_data);
diff --git a/host/lib/usrp/usrp2/fw_common.h b/host/lib/usrp/usrp2/fw_common.h
index 3def8ddaa..aca0abb28 100644
--- a/host/lib/usrp/usrp2/fw_common.h
+++ b/host/lib/usrp/usrp2/fw_common.h
@@ -168,6 +168,7 @@ typedef struct{
struct {
uint32_t freq_word;
uint32_t decim;
+ uint32_t scale_iq;
} ddc_args;
struct {
uint8_t enabled;
diff --git a/host/lib/usrp/usrp2/io_impl.cpp b/host/lib/usrp/usrp2/io_impl.cpp
index c9a7b5fa4..9c7a41e49 100644
--- a/host/lib/usrp/usrp2/io_impl.cpp
+++ b/host/lib/usrp/usrp2/io_impl.cpp
@@ -22,6 +22,7 @@
using namespace uhd;
using namespace uhd::usrp;
+namespace asio = boost::asio;
/***********************************************************************
* Constants
@@ -38,28 +39,28 @@ static const size_t max_vrt_header_words = 5;
* Helper Functions
**********************************************************************/
static inline void host_floats_to_usrp2_shorts(
- int16_t *usrp2_shorts,
+ short *usrp2_shorts,
const float *host_floats,
size_t num_samps
){
for(size_t i = 0; i < num_samps; i++){
- usrp2_shorts[i] = htons(int16_t(host_floats[i]*float_scale_factor));
+ usrp2_shorts[i] = htons(short(host_floats[i]*float_scale_factor));
}
}
static inline void usrp2_shorts_to_host_floats(
float *host_floats,
- const int16_t *usrp2_shorts,
+ const short *usrp2_shorts,
size_t num_samps
){
for(size_t i = 0; i < num_samps; i++){
- host_floats[i] = float(ntohs(usrp2_shorts[i])/float_scale_factor);
+ host_floats[i] = float(short(ntohs(usrp2_shorts[i])))/float_scale_factor;
}
}
static inline void host_shorts_to_usrp2_shorts(
- int16_t *usrp2_shorts,
- const int16_t *host_shorts,
+ short *usrp2_shorts,
+ const short *host_shorts,
size_t num_samps
){
for(size_t i = 0; i < num_samps; i++){
@@ -68,8 +69,8 @@ static inline void host_shorts_to_usrp2_shorts(
}
static inline void usrp2_shorts_to_host_shorts(
- int16_t *host_shorts,
- const int16_t *usrp2_shorts,
+ short *host_shorts,
+ const short *usrp2_shorts,
size_t num_samps
){
for(size_t i = 0; i < num_samps; i++){
@@ -102,16 +103,17 @@ size_t usrp2_impl::send_raw(
}
vrt_hdr_flags |= (metadata.start_of_burst)? (0x1 << 25) : 0;
vrt_hdr_flags |= (metadata.end_of_burst)? (0x1 << 24) : 0;
+ num_vrt_hdr_words += asio::buffer_size(buff)/sizeof(uint32_t);
//fill in complete header word
vrt_hdr[0] = htonl(vrt_hdr_flags |
((_stream_id_to_packet_seq[metadata.stream_id]++ & 0xf) << 16) |
- ((boost::asio::buffer_size(buff)/sizeof(uint32_t)) & 0xffff)
+ (num_vrt_hdr_words & 0xffff)
);
//load the buffer vector
size_t vrt_hdr_size = num_vrt_hdr_words*sizeof(uint32_t);
- buffs[0] = boost::asio::buffer(&vrt_hdr, vrt_hdr_size);
+ buffs[0] = asio::buffer(&vrt_hdr, vrt_hdr_size);
buffs[1] = buff;
//send and return number of samples
@@ -125,11 +127,33 @@ size_t usrp2_impl::recv_raw(
const boost::asio::mutable_buffer &buff,
uhd::metadata_t &metadata
){
+ //handle the case where there is spillover
+ if (asio::buffer_size(_splillover_buff) != 0){
+ size_t bytes_to_copy = std::min(
+ asio::buffer_size(_splillover_buff),
+ asio::buffer_size(buff)
+ );
+ std::memcpy(
+ asio::buffer_cast<void*>(buff),
+ asio::buffer_cast<const void*>(_splillover_buff),
+ bytes_to_copy
+ );
+ _splillover_buff = asio::buffer(
+ asio::buffer_cast<uint8_t*>(_splillover_buff)+bytes_to_copy,
+ asio::buffer_size(_splillover_buff)-bytes_to_copy
+ );
+ //std::cout << boost::format("Copied spillover %d samples") % (bytes_to_copy/sizeof(sc16_t)) << std::endl;
+ return bytes_to_copy/sizeof(sc16_t);
+ }
+
//load the buffer vector
- std::vector<boost::asio::mutable_buffer> buffs(2);
+ std::vector<boost::asio::mutable_buffer> buffs(3);
uint32_t vrt_hdr[max_vrt_header_words];
- buffs[0] = boost::asio::buffer(vrt_hdr, max_vrt_header_words);
- buffs[1] = buff;
+ buffs[0] = asio::buffer(vrt_hdr, max_vrt_header_words*sizeof(uint32_t));
+ buffs[1] = asio::buffer(//make sure its on a word boundary
+ buff, asio::buffer_size(buff) & ~(sizeof(uint32_t) - 1)
+ );
+ buffs[2] = asio::buffer(_spillover_mem, _mtu);
//receive into the buffers
size_t bytes_recvd = _data_transport->recv(buffs);
@@ -146,9 +170,15 @@ size_t usrp2_impl::recv_raw(
metadata.time_spec.secs = ntohl(vrt_hdr[2]);
metadata.time_spec.ticks = ntohl(vrt_hdr[3]);
- //return the number of samples received
- size_t num_words = vrt_header & 0xffff;
- return (num_words*sizeof(uint32_t))/sizeof(sc16_t);
+ //extract the number of bytes received
+ size_t num_words = (vrt_header & 0xffff) - max_vrt_header_words;
+ size_t num_bytes = num_words*sizeof(uint32_t);
+
+ //handle the case where spillover memory was used
+ size_t spillover_size = num_bytes - std::min(num_bytes, asio::buffer_size(buff));
+ _splillover_buff = asio::buffer(_spillover_mem, spillover_size);
+
+ return (num_bytes - spillover_size)/sizeof(sc16_t);
}
/***********************************************************************
@@ -160,13 +190,13 @@ size_t usrp2_impl::send(
const std::string &type
){
if (type == "32fc"){
- size_t num_samps = boost::asio::buffer_size(buff)/sizeof(fc32_t);
+ size_t num_samps = asio::buffer_size(buff)/sizeof(fc32_t);
boost::shared_array<sc16_t> raw_mem(new sc16_t[num_samps]);
boost::asio::mutable_buffer raw_buff(raw_mem.get(), num_samps*sizeof(sc16_t));
host_floats_to_usrp2_shorts(
- boost::asio::buffer_cast<int16_t*>(raw_buff),
- boost::asio::buffer_cast<const float*>(buff),
+ asio::buffer_cast<short*>(raw_buff),
+ asio::buffer_cast<const float*>(buff),
num_samps*2 //double for complex
);
@@ -177,13 +207,13 @@ size_t usrp2_impl::send(
#ifdef HAVE_BIG_ENDIAN
return send_raw(buff, metadata);
#else
- size_t num_samps = boost::asio::buffer_size(buff)/sizeof(sc16_t);
+ size_t num_samps = asio::buffer_size(buff)/sizeof(sc16_t);
boost::shared_array<sc16_t> raw_mem(new sc16_t[num_samps]);
boost::asio::mutable_buffer raw_buff(raw_mem.get(), num_samps*sizeof(sc16_t));
host_shorts_to_usrp2_shorts(
- boost::asio::buffer_cast<int16_t*>(raw_buff),
- boost::asio::buffer_cast<const int16_t*>(buff),
+ asio::buffer_cast<short*>(raw_buff),
+ asio::buffer_cast<const short*>(buff),
num_samps*2 //double for complex
);
@@ -203,15 +233,15 @@ size_t usrp2_impl::recv(
const std::string &type
){
if (type == "32fc"){
- size_t num_samps = boost::asio::buffer_size(buff)/sizeof(fc32_t);
+ size_t num_samps = asio::buffer_size(buff)/sizeof(fc32_t);
boost::shared_array<sc16_t> raw_mem(new sc16_t[num_samps]);
boost::asio::mutable_buffer raw_buff(raw_mem.get(), num_samps*sizeof(sc16_t));
num_samps = recv_raw(raw_buff, metadata);
usrp2_shorts_to_host_floats(
- boost::asio::buffer_cast<float*>(buff),
- boost::asio::buffer_cast<const int16_t*>(raw_buff),
+ asio::buffer_cast<float*>(buff),
+ asio::buffer_cast<const short*>(raw_buff),
num_samps*2 //double for complex
);
@@ -222,15 +252,15 @@ size_t usrp2_impl::recv(
#ifdef HAVE_BIG_ENDIAN
return recv_raw(buff, metadata);
#else
- size_t num_samps = boost::asio::buffer_size(buff)/sizeof(sc16_t);
+ size_t num_samps = asio::buffer_size(buff)/sizeof(sc16_t);
boost::shared_array<sc16_t> raw_mem(new sc16_t[num_samps]);
boost::asio::mutable_buffer raw_buff(raw_mem.get(), num_samps*sizeof(sc16_t));
num_samps = recv_raw(raw_buff, metadata);
usrp2_shorts_to_host_shorts(
- boost::asio::buffer_cast<int16_t*>(buff),
- boost::asio::buffer_cast<const int16_t*>(raw_buff),
+ asio::buffer_cast<short*>(buff),
+ asio::buffer_cast<const short*>(raw_buff),
num_samps*2 //double for complex
);
diff --git a/host/lib/usrp/usrp2/usrp2_impl.hpp b/host/lib/usrp/usrp2/usrp2_impl.hpp
index 9a4c42d42..47b01d1b1 100644
--- a/host/lib/usrp/usrp2/usrp2_impl.hpp
+++ b/host/lib/usrp/usrp2/usrp2_impl.hpp
@@ -106,6 +106,9 @@ private:
size_t send_raw(const boost::asio::const_buffer &, const uhd::metadata_t &);
size_t recv_raw(const boost::asio::mutable_buffer &, uhd::metadata_t &);
uhd::dict<uint32_t, size_t> _stream_id_to_packet_seq;
+ static const size_t _mtu = 1500;
+ uint8_t _spillover_mem[_mtu];
+ boost::asio::mutable_buffer _splillover_buff;
//udp transports for control and data
uhd::transport::udp::sptr _ctrl_transport;