diff --git a/srsapps/radio/include/srsapps/radio/radio_uhd.h b/srsapps/radio/include/srsapps/radio/radio_uhd.h index 1b560220f..acc21e8df 100644 --- a/srsapps/radio/include/srsapps/radio/radio_uhd.h +++ b/srsapps/radio/include/srsapps/radio/radio_uhd.h @@ -81,7 +81,7 @@ namespace srslte { void *uhd; static const double lo_offset = 8e6; // LO offset (in Hz) - static const double burst_settle_time = 0.3e-3; // Start of burst settle time (off->on RF transition time) + static const double burst_settle_time = 0.4e-3; // Start of burst settle time (off->on RF transition time) const static uint32_t burst_settle_max_samples = 12288; // 30.72 MHz is maximum frequency srslte_timestamp_t end_of_burst_time; diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h index b87d76c1f..e6b3c8f83 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/mac.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/mac.h @@ -159,6 +159,7 @@ private: trace tr_start_time; trace tr_end_time; bool tr_enabled; + bool is_first_of_burst; void tr_log_start(uint32_t tti); void tr_log_end(uint32_t tti); void set_phy_crnti(uint16_t phy_rnti); diff --git a/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h b/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h index 955901c67..9b39b84f5 100644 --- a/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h +++ b/srsapps/ue/mac/include/srsapps/ue/mac/proc_bsr.h @@ -89,6 +89,7 @@ private: bool timer_retx; bool sr_is_sent; + uint32_t last_print; void update_pending_data(); bool check_highest_channel(); bool check_single_channel(); diff --git a/srsapps/ue/mac/src/mac.cc b/srsapps/ue/mac/src/mac.cc index 1078cf841..c5bef4cca 100644 --- a/srsapps/ue/mac/src/mac.cc +++ b/srsapps/ue/mac/src/mac.cc @@ -56,6 +56,7 @@ bool mac::init(phy *phy_h_, tti_sync* ttisync_, log* log_h_) demux_unit.init(phy_h, log_h, &mac_io_lch, &timers_db); ra_procedure.init(¶ms_db, phy_h, log_h, &timers_db, &mux_unit, &demux_unit); sr_procedure.init(log_h, ¶ms_db, phy_h); + is_first_of_burst = true; reset(); if (threads_new_rt_prio(&mac_thread, mac_thread_fnc, this, 5)) { @@ -251,6 +252,28 @@ void mac::main_radio_loop() { if (ra_procedure.is_contention_resolution() || ra_procedure.is_successful()) { process_ul_grants(tti); } + ul_buffer *ul_buffer = phy_h->get_ul_buffer(tti+4); + + // Generate scheduling request if we have to + if (phy_h->sr_is_ready_to_send(tti+4)) { + ul_buffer->generate_sr(); + } + + // The UL buffer is released when successfully transmitted. + if (ul_buffer->is_released()) { + ul_buffer->ready(); + is_first_of_burst = false; + } else if (ul_buffer->uci_ready() || ul_buffer->srs_is_ready_to_send()) { + // If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal + ul_buffer->generate_data(); + ul_buffer->ready(); + is_first_of_burst = false; + } else { + if (!is_first_of_burst) { + ul_buffer->set_end_of_burst(); + is_first_of_burst = true; + } + } timers_db.step_all(); diff --git a/srsapps/ue/mac/src/proc_bsr.cc b/srsapps/ue/mac/src/proc_bsr.cc index 5b6d0aeed..d0cc37437 100644 --- a/srsapps/ue/mac/src/proc_bsr.cc +++ b/srsapps/ue/mac/src/proc_bsr.cc @@ -44,6 +44,7 @@ bsr_proc::bsr_proc() priorities[i] = -1; last_pending_data[i] = 0; } + last_print = 0; triggered_bsr_type=NONE; } @@ -67,14 +68,14 @@ void bsr_proc::timer_expired(uint32_t timer_id) { case mac::BSR_TIMER_PERIODIC: if (triggered_bsr_type == NONE) { // Check condition 4 in Sec 5.4.5 - //triggered_bsr_type = PERIODIC; - Info("BSR PERIODIC disabled\n"); + triggered_bsr_type = PERIODIC; + Info("Triggering BSR PERIODIC\n"); } break; case mac::BSR_TIMER_RETX: // Enable reTx of SR - //triggered_bsr_type = REGULAR; - Info("BSR reTX disabled\n"); + triggered_bsr_type = REGULAR; + Info("Triggering BSR reTX\n"); sr_is_sent = false; break; } @@ -151,7 +152,7 @@ bool bsr_proc::generate_bsr(bsr_t *bsr, uint32_t nof_padding_bytes) { for (int i=0;iNOF_UL_LCH;i++) { if (lcg[i] >= 0) { uint32_t n = mac_io_h->get(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8; - bsr->buff_size[lcg[i]] += n; + bsr->buff_size[lcg[i]] += 8*n; if (n > 0) { nof_lcg++; ret = true; @@ -216,6 +217,18 @@ void bsr_proc::step(uint32_t tti) check_highest_channel(); update_pending_data(); + + + if ((tti - last_print)%10240 > 40) { + char str[128]; + bzero(str, 128); + for (int i=0;iget(i+mac_io::MAC_LCH_CCCH_UL)->pending_data()/8, last_pending_data[i]); + } + Info("QUEUE status: %s\n", str); + last_print = tti; + } + } char* bsr_proc::bsr_type_tostring(triggered_bsr_type_t type) { diff --git a/srsapps/ue/mac/test/CMakeLists.txt b/srsapps/ue/mac/test/CMakeLists.txt index 0bedf25be..fd0cec8b9 100644 --- a/srsapps/ue/mac/test/CMakeLists.txt +++ b/srsapps/ue/mac/test/CMakeLists.txt @@ -25,4 +25,7 @@ IF(UHD_FOUND AND OPENLTE_FOUND) INCLUDE_DIRECTORIES(${OPENLTE_INCLUDE_DIRS}) ADD_EXECUTABLE(mac_test mac_test.cc) TARGET_LINK_LIBRARIES(mac_test srsapps_common srsapps_ue_mac srsapps_ue_phy srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd) -ENDIF(UHD_FOUND AND OPENLTE_FOUND) + + ADD_EXECUTABLE(mac_test mac_test.cc) + TARGET_LINK_LIBRARIES(mac_test srsapps_common srsapps_ue_mac srsapps_ue_phy srsapps_radio srslte ${OPENLTE_LIBRARIES} srslte_uhd) + ENDIF(UHD_FOUND AND OPENLTE_FOUND) diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h index 638b0c997..b510f5072 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy.h @@ -125,12 +125,15 @@ public: void write_trace(std::string filename); void main_radio_loop(); - + bool sr_is_ready_to_send(uint32_t tti); + private: enum { IDLE, RXTX } phy_state; + static const int NOF_ULDL_QUEUES = 6; + tti_sync *ttisync; radio *radio_handler; log *log_h; @@ -158,7 +161,6 @@ private: double last_gain; bool sr_enabled; - bool sr_is_ready_to_send(uint32_t tti); bool init_(radio *radio_handler, tti_sync *ttisync, log *log_h, bool do_agc); static void *phy_thread_fnc(void *arg); diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h index 9a765828d..b9115a659 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h @@ -33,6 +33,7 @@ #include "srsapps/ue/phy/ul_sched_grant.h" #include "srsapps/ue/phy/dl_sched_grant.h" #include "srsapps/ue/phy/phy_params.h" +#include "srsapps/radio/radio.h" #ifndef UEULBUFFER_H #define UEULBUFFER_H @@ -47,7 +48,7 @@ namespace ue { class ul_buffer : public queue::element { public: - bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h); + bool init_cell(srslte_cell_t cell, phy_params *params_db, log *log_h, radio *radio_h); void free_cell(); void set_crnti(uint16_t rnti); void set_current_tx_nb(uint32_t current_tx_nb); @@ -60,12 +61,18 @@ namespace ue { bool generate_data(); bool generate_data(ul_sched_grant *pusch_grant, uint8_t *payload); bool generate_data(ul_sched_grant *pusch_grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload); - bool send(radio* radio_handler, float time_adv_sec, float cfo, srslte_timestamp_t rx_time); - static const uint32_t tx_advance_sf = 2; // Number of subframes to advance transmission + void set_tx_params(float cfo, float time_adv_sec, srslte_timestamp_t tx_time); + void set_end_of_burst(); + bool is_end_of_burst(); + static const uint32_t tx_advance_sf = 1; // Number of subframes to advance transmission static const bool normalize_amp = true; private: log *log_h; phy_params *params_db; + radio *radio_h; + float cfo; + bool tti_is_end_of_burst; + srslte_timestamp_t tx_time; srslte_cell_t cell; srslte_ue_ul_t ue_ul; bool cell_initiated; diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index e32a7bf76..b38d45ffd 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -94,8 +94,8 @@ bool phy::init_(srslte::radio* radio_handler_, srslte::ue::tti_sync* ttisync_, l ttisync = ttisync_; log_h = log_h_; radio_handler = radio_handler_; - ul_buffer_queue = new queue(6, sizeof(ul_buffer)); - dl_buffer_queue = new queue(6, sizeof(dl_buffer)); + ul_buffer_queue = new queue(NOF_ULDL_QUEUES, sizeof(ul_buffer)); + dl_buffer_queue = new queue(NOF_ULDL_QUEUES, sizeof(dl_buffer)); do_agc = do_agc_; last_gain = 1e4; time_adv_sec = 0; @@ -118,7 +118,7 @@ void phy::stop() pthread_join(phy_thread, NULL); - for (int i=0;i<6;i++) { + for (int i=0;iget(i))->free_cell(); ((dl_buffer*) dl_buffer_queue->get(i))->free_cell(); } @@ -171,7 +171,7 @@ bool phy::send_prach(uint32_t preamble_idx, int allowed_subframe, int target_pow if (phy_state == RXTX) { srslte_agc_lock(&ue_sync.agc, true); old_gain = radio_handler->get_tx_gain(); - radio_handler->set_tx_gain(10); + radio_handler->set_tx_gain(80); Info("Stopped AGC. Set TX gain to %.1f dB\n", radio_handler->get_tx_gain()); return prach_buffer.prepare_to_send(preamble_idx, allowed_subframe, target_power_dbm); } @@ -224,7 +224,7 @@ bool phy::measure() } void phy::set_crnti(uint16_t rnti) { - for(uint32_t i=0;i<6;i++) { + for(uint32_t i=0;iget(i))->set_crnti(rnti); ((dl_buffer*) dl_buffer_queue->get(i))->set_crnti(rnti); @@ -319,8 +319,8 @@ bool phy::set_cell(srslte_cell_t cell_) { } srslte_ue_sync_set_cfo(&ue_sync, cellsearch_cfo); - for(uint32_t i=0;i<6;i++) { - ((ul_buffer*) ul_buffer_queue->get(i))->init_cell(cell, ¶ms_db, log_h); + for(uint32_t i=0;iget(i))->init_cell(cell, ¶ms_db, log_h, radio_handler); ((dl_buffer*) dl_buffer_queue->get(i))->init_cell(cell, ¶ms_db, log_h); ((dl_buffer*) dl_buffer_queue->get(i))->buffer_id = i; ((ul_buffer*) ul_buffer_queue->get(i))->ready(); @@ -345,7 +345,7 @@ bool phy::init_prach() { ul_buffer* phy::get_ul_buffer(uint32_t tti) { - if ((tti + 1)%10240 < get_current_tti() && tti > 6) { + if (tti + 1 < get_current_tti() && tti > NOF_ULDL_QUEUES) { Warning("Warning access to PHY UL buffer too late. Requested TTI=%d while PHY is in %d\n", tti, get_current_tti()); } return (ul_buffer*) ul_buffer_queue->get(tti); @@ -519,15 +519,10 @@ void phy::run_rx_tx_state() log_h->step(current_tti); float cfo = srslte_ue_sync_get_cfo(&ue_sync)/15000; - bool tx_zeros = true; - - // Advance transmission time for the next tti srslte_timestamp_add(&last_rx_time, 0, 1e-3); - // Generate scheduling request if we have to - if (sr_is_ready_to_send(current_tti+ul_buffer::tx_advance_sf)) { - get_ul_buffer_adv(current_tti)->generate_sr(); - } + /* Set CFO and next TX time for UL buffer for TTI+4 */ + get_ul_buffer(current_tti+4)->set_tx_params(cfo, time_adv_sec, last_rx_time); // Every subframe, TX a PRACH or a PUSCH/PUCCH if (prach_buffer.is_ready_to_send(current_tti)) { @@ -536,25 +531,10 @@ void phy::run_rx_tx_state() radio_handler->tx_end(); radio_handler->set_tx_gain(old_gain); srslte_agc_lock(&ue_sync.agc, false); - Info("Restoring AGC. Set TX gain to %.1f dB\n", old_gain); - - // If we don't transmit PRACH, check if need to transmit PUSCH/PUCCH - } else if (get_ul_buffer_adv(current_tti)->is_released() || - get_ul_buffer_adv(current_tti)->uci_ready() || - get_ul_buffer_adv(current_tti)->srs_is_ready_to_send()) - { - // If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal - if (!get_ul_buffer_adv(current_tti)->is_released()) { - get_ul_buffer_adv(current_tti)->generate_data(); - } - // And transmit - get_ul_buffer_adv(current_tti)->send(radio_handler, time_adv_sec, cfo, last_rx_time); - is_first_of_burst = false; - } else { - if (!is_first_of_burst) { - radio_handler->tx_end(); - is_first_of_burst = true; - } + Info("Restoring AGC. Set TX gain to %.1f dB\n", old_gain); + } else if (get_ul_buffer_adv(current_tti)->is_end_of_burst()) { + radio_handler->tx_end(); + Info("Sending TX END\n"); } // Receive alligned buffer for the current tti diff --git a/srsapps/ue/phy/src/ul_buffer.cc b/srsapps/ue/phy/src/ul_buffer.cc index f5daf3e64..e8b4e6357 100644 --- a/srsapps/ue/phy/src/ul_buffer.cc +++ b/srsapps/ue/phy/src/ul_buffer.cc @@ -41,16 +41,18 @@ namespace srslte { namespace ue { -bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_) { +bool ul_buffer::init_cell(srslte_cell_t cell_, phy_params *params_db_, log *log_h_, radio *radio_h_) { cell = cell_; log_h = log_h_; + radio_h = radio_h_; params_db = params_db_; current_tx_nb = 0; + tti_is_end_of_burst = false; if (!srslte_ue_ul_init(&ue_ul, cell)) { srslte_ue_ul_set_normalization(&ue_ul, false); signal_buffer = (cf_t*) srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); cell_initiated = (signal_buffer)?true:false; - srslte_ue_ul_set_cfo_enable(&ue_ul, false); + srslte_ue_ul_set_cfo_enable(&ue_ul, true); bzero(&uci_data, sizeof(srslte_uci_data_t)); uci_pending = false; return cell_initiated; @@ -209,6 +211,8 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof uci_data.I_offset_cqi = params_db->get_param(phy_params::UCI_I_OFFSET_CQI); uci_data.I_offset_ri = params_db->get_param(phy_params::UCI_I_OFFSET_RI); + srslte_ue_ul_set_cfo(&ue_ul, cfo); + int n = 0; // Transmit on PUSCH if UL grant available, otherwise in PUCCH if (grant) { @@ -230,8 +234,8 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof grant->get_rnti(), signal_buffer); - Info("PUSCH: TTI=%d, TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n", - tti, grant->get_tbs(), srslte_mod_string(ue_ul.pusch_cfg.grant.mcs.mod), ue_ul.pusch_cfg.grant.n_prb[0], + Info("PUSCH: TTI=%d, CFO= %.1f KHz TBS=%d, mod=%s, rb_start=%d n_prb=%d, ack=%s, sr=%s, rnti=%d, shortened=%s\n", + tti, cfo*15e3, grant->get_tbs(), srslte_mod_string(ue_ul.pusch_cfg.grant.mcs.mod), ue_ul.pusch_cfg.grant.n_prb[0], ue_ul.pusch_cfg.grant.L_prb, uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", grant->get_rnti(), ue_ul.pusch.shortened?"yes":"no"); @@ -240,18 +244,37 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof } else if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len) { n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti%10, signal_buffer); - Info("PUCCH: TTI=%d n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, last_n_cce, + Info("PUCCH: TTI=%d, CFO= %.1f KHz n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, cfo*15e3, last_n_cce, uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", ue_ul.pucch.shortened?"yes":"no"); } else { n = srslte_ue_ul_srs_encode(&ue_ul, tti, signal_buffer); - Info("SRS only: TX at TTI=%d\n", tti); + Info("SRS: TTI=%d, CFO= %.1f KHz \n", tti, cfo*15e3); } + // Reset UCI data bzero(&uci_data, sizeof(srslte_uci_data_t)); uci_pending = false; + + // Compute peak + float max = 0; + if (normalize_amp) { + float *t = (float*) signal_buffer; + for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) { + if (fabsf(t[i]) > max) { + max = fabsf(t[i]); + } + } + + // Normalize before TX + srslte_vec_sc_prod_cfc(signal_buffer, 0.7/max, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); + } + + radio_h->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time); + release(); + if (n < 0) { fprintf(stderr, "Error in UL buffer: Error encoding %s\n", signal_buffer?"PUSCH":"PUCCH"); return false; @@ -266,47 +289,23 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof int nof_tx = 0; -bool ul_buffer::send(srslte::radio* radio_handler, float time_adv_sec, float cfo, srslte_timestamp_t rx_time) -{ - // send packet next timeslot minus time advance - srslte_timestamp_t tx_time; - srslte_timestamp_copy(&tx_time, &rx_time); - srslte_timestamp_add(&tx_time, 0, tx_advance_sf*1e-3 - time_adv_sec); +void ul_buffer::set_tx_params(float cfo_, float time_adv_sec, srslte_timestamp_t tx_time_) +{ + tti_is_end_of_burst = false; + cfo = cfo_; + srslte_timestamp_copy(&tx_time, &tx_time_); + srslte_timestamp_add(&tx_time, 0, 4e-3 - time_adv_sec); +} - // Correct CFO before transmission - if (cfo != 0) { - srslte_cfo_correct(&ue_ul.cfo, signal_buffer, signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb)); - } - - // Compute peak - float max = 0; - if (normalize_amp) { - float *t = (float*) signal_buffer; - for (int i=0;i<2*SRSLTE_SF_LEN_PRB(cell.nof_prb);i++) { - if (fabsf(t[i]) > max) { - max = fabsf(t[i]); - } - } - - // Normalize before TX - srslte_vec_sc_prod_cfc(signal_buffer, 0.7/max, signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb)); - } - - Info("TX CFO: %f, len=%d, rx_time= %.6f tx_time = %.6f TA: %.1f PeakAmplitude=%.2f PKT#%d\n", - cfo*15000, SRSLTE_SF_LEN_PRB(cell.nof_prb), - srslte_timestamp_real(&rx_time), - srslte_timestamp_real(&tx_time), time_adv_sec*1000000, max, nof_tx); - - radio_handler->tx(signal_buffer, SRSLTE_SF_LEN_PRB(cell.nof_prb), tx_time); - - /* - char filename[25]; - sprintf(filename, "pusch%d",nof_tx); - srslte_vec_save_file(filename, signal_buffer, sizeof(cf_t)*SRSLTE_SF_LEN_PRB(cell.nof_prb)); - nof_tx++; - */ - - ready(); +void ul_buffer::set_end_of_burst() +{ + Info("Is end of burst\n"); + tti_is_end_of_burst = true; +} + +bool ul_buffer::is_end_of_burst() +{ + return tti_is_end_of_burst; } } // namespace ue diff --git a/srslte/lib/cuhd/src/cuhd_imp.cpp b/srslte/lib/cuhd/src/cuhd_imp.cpp index 553422b1b..f2048f8f1 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"); + handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=30720000, num_recv_frames=512"); // handler->usrp = uhd::usrp::multi_usrp::make(_args + ", master_clock_rate=50000000" + ", num_recv_frames=512"); handler->usrp->set_clock_source("internal");