diff --git a/srslte/lib/cuhd/src/cuhd_handler.hpp b/srslte/lib/cuhd/src/cuhd_handler.hpp index c9c3fc2a5..82910edeb 100644 --- a/srslte/lib/cuhd/src/cuhd_handler.hpp +++ b/srslte/lib/cuhd/src/cuhd_handler.hpp @@ -45,4 +45,7 @@ public: bool tx_gain_same_rx; float tx_rx_gain_offset; uhd::gain_range_t rx_gain_range; + size_t rx_nof_samples; + size_t tx_nof_samples; + double tx_rate; }; diff --git a/srslte/lib/cuhd/src/cuhd_imp.cpp b/srslte/lib/cuhd/src/cuhd_imp.cpp index cd9456ff1..5b020fa60 100644 --- a/srslte/lib/cuhd/src/cuhd_imp.cpp +++ b/srslte/lib/cuhd/src/cuhd_imp.cpp @@ -162,7 +162,7 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain, bool tx_gain_same_ { cuhd_handler *handler = new cuhd_handler(); std::string _args = std::string(args); - handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000, num_recv_frames=64, num_send_frames=64"); + handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000, recv_frame_size=7696,num_recv_frames=64,send_frame_size=7696,num_send_frames=64"); handler->usrp->set_clock_source("internal"); #ifdef HIDE_MESSAGES @@ -175,6 +175,9 @@ int cuhd_open_(char *args, void **h, bool create_thread_gain, bool tx_gain_same_ uhd::stream_args_t stream_args(cpu, otw); handler->rx_stream = handler->usrp->get_rx_stream(stream_args); handler->tx_stream = handler->usrp->get_tx_stream(stream_args); + + handler->rx_nof_samples = handler->rx_stream->get_max_num_samps(); + handler->tx_nof_samples = handler->tx_stream->get_max_num_samps(); handler->tx_gain_same_rx = tx_gain_same_rx; handler->tx_rx_gain_offset = 0.0; @@ -258,31 +261,7 @@ double cuhd_set_rx_freq_offset(void *h, double freq, double off) { int cuhd_recv(void *h, void *data, uint32_t nsamples, bool blocking) { - cuhd_handler *handler = static_cast < cuhd_handler * >(h); - uhd::rx_metadata_t md; - uint32_t nof_packets = 0; - if (blocking) { - int n = 0, p; - complex_t *data_c = (complex_t *) data; - do { - p = handler->rx_stream->recv(&data_c[n], nsamples - n, md); - if (p == -1) { - return -1; - } - n += p; -#ifdef METADATA_VERBOSE - if (md.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE) { - std::cout << "\nError code: " << md.to_pp_string() << "\n\n"; - } -#endif - nof_packets++; - } while (n < nsamples && - md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE && - nof_packets < 10); - return nsamples; - } else { - return handler->rx_stream->recv(data, nsamples, md, 0.0); - } + return cuhd_recv_with_time(h, data, nsamples, blocking, NULL, NULL); } int cuhd_recv_with_time(void *h, @@ -293,14 +272,16 @@ int cuhd_recv_with_time(void *h, double *frac_secs) { cuhd_handler *handler = static_cast < cuhd_handler * >(h); - uhd::rx_metadata_t md; - uint32_t nof_packets = 0; - int ret = -1; + uhd::rx_metadata_t md, md_first; if (blocking) { int n = 0, p; complex_t *data_c = (complex_t *) data; do { - p = handler->rx_stream->recv(&data_c[n], nsamples - n, md); + size_t rx_samples = handler->rx_nof_samples; + if (rx_samples > nsamples - n) { + rx_samples = nsamples - n; + } + p = handler->rx_stream->recv(&data_c[n], rx_samples, n==0?md_first:md); if (p == -1) { return -1; } @@ -310,19 +291,18 @@ int cuhd_recv_with_time(void *h, std::cout << "\nError code: " << md.to_pp_string() << "\n\n"; } #endif - nof_packets++; } while (n < nsamples && - md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE && - nof_packets < 10); - ret = nsamples; + md.error_code == uhd::rx_metadata_t::ERROR_CODE_NONE); } else { - ret = handler->rx_stream->recv(data, nsamples, md, 0.0); + return handler->rx_stream->recv(data, nsamples, md, 0.0); + } + if (secs) { + *secs = md_first.time_spec.get_full_secs(); } - if (secs && frac_secs) { - *secs = md.time_spec.get_full_secs(); - *frac_secs = md.time_spec.get_frac_secs(); + if (frac_secs) { + *frac_secs = md_first.time_spec.get_frac_secs(); } - return ret; + return nsamples; } double cuhd_set_tx_gain(void *h, double gain) { @@ -335,7 +315,8 @@ double cuhd_set_tx_srate(void *h, double freq) { cuhd_handler *handler = static_cast < cuhd_handler * >(h); handler->usrp->set_tx_rate(freq); - return handler->usrp->get_tx_rate(); + handler->tx_rate = handler->usrp->get_tx_rate(); + return handler->tx_rate; } double cuhd_set_tx_freq(void *h, double freq) @@ -363,26 +344,50 @@ void cuhd_get_time(void *h, time_t *secs, double *frac_secs) { } } -int cuhd_send(void *h, void *data, uint32_t nsamples, bool blocking) -{ - return cuhd_send2(h, data, nsamples, blocking, true, true); -} - -int cuhd_send2(void *h, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst) + +int cuhd_send_timed3(void *h, + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool has_time_spec, + bool blocking, + bool is_start_of_burst, + bool is_end_of_burst) { - cuhd_handler *handler = static_cast < cuhd_handler * >(h); + cuhd_handler* handler = static_cast(h); uhd::tx_metadata_t md; - md.has_time_spec = false; - md.start_of_burst = start_of_burst; - md.end_of_burst = end_of_burst; + md.has_time_spec = has_time_spec; + if (has_time_spec) { + md.time_spec = uhd::time_spec_t(secs, frac_secs); + } + if (blocking) { int n = 0, p; complex_t *data_c = (complex_t *) data; do { - p = handler->tx_stream->send(&data_c[n], nsamples - n, md); + size_t tx_samples = handler->tx_nof_samples; + + // First packet is start of burst if so defined, others are never + if (n == 0) { + md.start_of_burst = is_start_of_burst; + } else { + md.start_of_burst = false; + } + + // middle packets are never end of burst, last one as defined + if (nsamples - n > tx_samples) { + md.end_of_burst = false; + } else { + tx_samples = nsamples - n; + md.end_of_burst = is_end_of_burst; + } + p = handler->tx_stream->send(&data_c[n], tx_samples, md); if (p == -1) { return -1; } + // Increase time spec + md.time_spec += tx_samples/handler->tx_rate; n += p; } while (n < nsamples); return nsamples; @@ -391,6 +396,16 @@ int cuhd_send2(void *h, void *data, uint32_t nsamples, bool blocking, bool start } } +int cuhd_send(void *h, void *data, uint32_t nsamples, bool blocking) +{ + return cuhd_send2(h, data, nsamples, blocking, true, true); +} + +int cuhd_send2(void *h, void *data, uint32_t nsamples, bool blocking, bool start_of_burst, bool end_of_burst) +{ + return cuhd_send_timed3(h, data, nsamples, 0, 0, false, blocking, start_of_burst, end_of_burst); +} + int cuhd_send_timed(void *h, void *data, @@ -400,20 +415,14 @@ int cuhd_send_timed(void *h, { return cuhd_send_timed2(h, data, nsamples, secs, frac_secs, true, true); } - + int cuhd_send_timed2(void *h, - void *data, - int nsamples, - time_t secs, - double frac_secs, - bool is_start_of_burst, - bool is_end_of_burst) + void *data, + int nsamples, + time_t secs, + double frac_secs, + bool is_start_of_burst, + bool is_end_of_burst) { - cuhd_handler* handler = static_cast(h); - uhd::tx_metadata_t md; - md.start_of_burst = is_start_of_burst; - md.end_of_burst = is_end_of_burst; - md.has_time_spec = true; - md.time_spec = uhd::time_spec_t(secs, frac_secs); - return handler->tx_stream->send(data, nsamples, md); + return cuhd_send_timed3(h, data, nsamples, secs, frac_secs, true, true, is_start_of_burst, is_end_of_burst); }