From c4c1c62360ccbede6bb85dbfd7575e545d1aa96e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 13 Oct 2017 17:59:12 +0200 Subject: [PATCH] stable connection. Runs out of samples in ringbuffer if clock differences --- lib/include/srslte/phy/utils/ringbuffer.h | 8 +- lib/src/phy/utils/ringbuffer.c | 5 + srsue/hdr/phy/phch_recv.h | 11 +- srsue/hdr/phy/phy.h | 2 + srsue/hdr/ue.h | 1 + srsue/src/main.cc | 6 + srsue/src/phy/phch_recv.cc | 147 +++++++++++++++++----- srsue/src/phy/phy.cc | 5 + srsue/src/ue.cc | 5 + 9 files changed, 152 insertions(+), 38 deletions(-) diff --git a/lib/include/srslte/phy/utils/ringbuffer.h b/lib/include/srslte/phy/utils/ringbuffer.h index c9276d5a9..acd2ae5e6 100644 --- a/lib/include/srslte/phy/utils/ringbuffer.h +++ b/lib/include/srslte/phy/utils/ringbuffer.h @@ -17,17 +17,19 @@ typedef struct { } srslte_ringbuffer_t; -SRSLTE_API int srslte_ringbuffer_init(srslte_ringbuffer_t *q, +SRSLTE_API int srslte_ringbuffer_init(srslte_ringbuffer_t *q, int capacity); SRSLTE_API void srslte_ringbuffer_free(srslte_ringbuffer_t *q, int capacity); -SRSLTE_API int srslte_ringbuffer_write(srslte_ringbuffer_t *q, +SRSLTE_API int srslte_ringbuffer_status(srslte_ringbuffer_t *q); + +SRSLTE_API int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *ptr, int nof_bytes); -SRSLTE_API int srslte_ringbuffer_read(srslte_ringbuffer_t *q, +SRSLTE_API int srslte_ringbuffer_read(srslte_ringbuffer_t *q, void *ptr, int nof_bytes); diff --git a/lib/src/phy/utils/ringbuffer.c b/lib/src/phy/utils/ringbuffer.c index 02faaeb9a..f7a10e2c5 100644 --- a/lib/src/phy/utils/ringbuffer.c +++ b/lib/src/phy/utils/ringbuffer.c @@ -34,6 +34,11 @@ void srslte_ringbuffer_free(srslte_ringbuffer_t *q, int capacity) } } +int srslte_ringbuffer_status(srslte_ringbuffer_t *q) +{ + return q->count; +} + int srslte_ringbuffer_write(srslte_ringbuffer_t *q, void *p, int nof_bytes) { uint8_t *ptr = (uint8_t*) p; diff --git a/srsue/hdr/phy/phch_recv.h b/srsue/hdr/phy/phch_recv.h index 781603be1..bb23bb5b5 100644 --- a/srsue/hdr/phy/phch_recv.h +++ b/srsue/hdr/phy/phch_recv.h @@ -67,7 +67,9 @@ public: void set_time_adv_sec(float time_adv_sec); void get_current_cell(srslte_cell_t *cell); - + + void scell_enable(bool enable); + const static int MUTEX_X_WORKER = 4; int radio_recv_fnc(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time); @@ -155,6 +157,7 @@ private: float rsrp(); float rsrq(); float snr(); + float cfo(); private: srslte::log *log_h; srslte_ue_dl_t ue_dl; @@ -162,7 +165,7 @@ private: cf_t *buffer[SRSLTE_MAX_PORTS]; uint32_t cnt; uint32_t nof_subframes; - float mean_rsrp, mean_rsrq, mean_snr; + float mean_rsrp, mean_rsrq, mean_snr, mean_cfo; const static int RSRP_MEASURE_NOF_FRAMES = 5; }; @@ -172,9 +175,11 @@ private: public: void init(phch_recv *parent, srslte::log *log_h, uint32_t nof_rx_antennas, uint32_t prio, int cpu_affinity = -1); void stop(); + void reset(); int recv(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time); void write(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time); bool is_enabled(); + void set_cell(srslte_cell_t scell); private: void run_thread(); @@ -192,6 +197,8 @@ private: cf_t *sf_buffer[SRSLTE_MAX_PORTS]; srslte_ue_sync_t ue_sync; srslte_cell_t cell; + uint32_t nof_rx_antennas; + uint32_t current_sflen; measure measure_p; sfn_sync sfn_p; diff --git a/srsue/hdr/phy/phy.h b/srsue/hdr/phy/phy.h index 07a2713fa..c75fbb90d 100644 --- a/srsue/hdr/phy/phy.h +++ b/srsue/hdr/phy/phy.h @@ -78,6 +78,8 @@ public: void set_earfcn(std::vector earfcns); void force_freq(float dl_freq, float ul_freq); + void scell_enable(bool enable); + /********** RRC INTERFACE ********************/ void reset(); void sync_reset(); diff --git a/srsue/hdr/ue.h b/srsue/hdr/ue.h index 4e48f6b6d..fa461d1c9 100644 --- a/srsue/hdr/ue.h +++ b/srsue/hdr/ue.h @@ -80,6 +80,7 @@ public: void pregenerate_signals(bool enable); + void test_scell(); private: virtual ~ue(); diff --git a/srsue/src/main.cc b/srsue/src/main.cc index 47d5f807e..0b67cecc1 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -387,14 +387,20 @@ int main(int argc, char *argv[]) pthread_t input; pthread_create(&input, NULL, &input_loop, &args); + bool scell_done = false; bool plot_started = false; bool signals_pregenerated = false; + while (running) { if (ue->is_attached()) { if (!signals_pregenerated && args.expert.pregenerate_signals) { ue->pregenerate_signals(true); signals_pregenerated = true; } + if (!scell_done) { + ((srsue::ue*) ue)->test_scell(); + scell_done = true; + } if (!plot_started && args.gui.enable) { ue->start_plot(); plot_started = true; diff --git a/srsue/src/phy/phch_recv.cc b/srsue/src/phy/phch_recv.cc index 2249a0913..91d2cd482 100644 --- a/srsue/src/phy/phch_recv.cc +++ b/srsue/src/phy/phch_recv.cc @@ -64,7 +64,8 @@ phch_recv::phch_recv() { void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_mac, rrc_interface_phy *_rrc, prach *_prach_buffer, srslte::thread_pool *_workers_pool, phch_common *_worker_com, srslte::log *_log_h, uint32_t nof_rx_antennas_, uint32_t prio, - int sync_cpu_affinity) { + int sync_cpu_affinity) +{ radio_h = _radio_handler; log_h = _log_h; mac = _mac; @@ -96,7 +97,7 @@ void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_ma measure_p.init(&ue_sync, sf_buffer, log_h, nof_rx_antennas); // Start scell - scell.init(this, log_h, nof_rx_antennas_, prio, sync_cpu_affinity); + scell.init(this, log_h, nof_rx_antennas_, prio-1, sync_cpu_affinity); reset(); @@ -106,7 +107,6 @@ void phch_recv::init(srslte::radio_multi *_radio_handler, mac_interface_phy *_ma } else { start_cpu(prio, sync_cpu_affinity); } - } phch_recv::~phch_recv() { @@ -118,13 +118,15 @@ phch_recv::~phch_recv() { srslte_ue_sync_free(&ue_sync); } -void phch_recv::stop() { +void phch_recv::stop() +{ running = false; wait_thread_finish(); } -void phch_recv::reset() { +void phch_recv::reset() +{ tx_mutex_cnt = 0; running = true; phy_state = IDLE; @@ -141,7 +143,8 @@ void phch_recv::reset() { } -void phch_recv::radio_error() { +void phch_recv::radio_error() +{ log_h->error("SYNC: Receiving from radio.\n"); phy_state = IDLE; radio_is_resetting=true; @@ -157,7 +160,8 @@ void phch_recv::radio_error() { radio_is_resetting=false; } -bool phch_recv::wait_radio_reset() { +bool phch_recv::wait_radio_reset() +{ int cnt=0; while(cnt < 20 && radio_is_resetting) { sleep(1); @@ -166,11 +170,13 @@ bool phch_recv::wait_radio_reset() { return radio_is_resetting; } -void phch_recv::set_agc_enable(bool enable) { +void phch_recv::set_agc_enable(bool enable) +{ do_agc = enable; } -void phch_recv::set_time_adv_sec(float _time_adv_sec) { +void phch_recv::set_time_adv_sec(float _time_adv_sec) +{ if (TX_MODE_CONTINUOUS && !radio_h->is_first_of_burst()) { int nsamples = ceil(current_srate*_time_adv_sec); next_offset = -nsamples; @@ -179,7 +185,8 @@ void phch_recv::set_time_adv_sec(float _time_adv_sec) { } } -void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) { +void phch_recv::set_ue_sync_opts(srslte_ue_sync_t *q) +{ if (worker_com->args->cfo_integer_enabled) { srslte_ue_sync_cfo_i_detec_en(q, true); } @@ -473,9 +480,12 @@ int phch_recv::radio_recv_fnc(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, s next_offset = nsamples; } - if (offset == 0) { + if (offset <= 0) { scell.write(data, nsamples, rx_time); } + + log_h->debug("SYNC: received %d samples from radio\n", nsamples); + return nsamples; } else { return -1; @@ -487,7 +497,13 @@ int phch_recv::scell_recv_fnc(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, s return scell.recv(data, nsamples, rx_time); } - +void phch_recv::scell_enable(bool enable) +{ + srslte_cell_t target_cell; + memcpy(&target_cell, &cell, sizeof(srslte_cell_t)); + target_cell.id++; + scell.set_cell(target_cell); +} @@ -512,7 +528,6 @@ void phch_recv::run_thread() Debug("SYNC: state=%d\n", phy_state); } - tti = (tti+1) % 10240; log_h->step(tti); sf_idx = tti%10; @@ -635,7 +650,6 @@ void phch_recv::run_thread() rrc->out_of_sync(); worker->release(); worker_com->reset_ul(); - mac->tti_clock(tti); break; default: radio_error(); @@ -652,11 +666,12 @@ void phch_recv::run_thread() } is_in_idle = true; usleep(1000); - // Keep running MAC timer from system clock - tti = (tti+1) % 10240; - mac->tti_clock(tti); break; } + + // Increase TTI counter and trigger MAC clock (lower priority) + tti = (tti+1) % 10240; + mac->tti_clock(tti); } } @@ -860,6 +875,7 @@ bool phch_recv::sfn_sync::set_cell(srslte_cell_t cell) Error("SYNC: Setting cell: initiating ue_mib\n"); return false; } + reset(); return true; } @@ -952,7 +968,8 @@ void phch_recv::measure::reset() { cnt = 0; mean_rsrp = 0; mean_rsrq = 0; - mean_snr = 0; + mean_snr = 0; + mean_cfo = 0; } void phch_recv::measure::set_cell(srslte_cell_t cell) @@ -960,6 +977,7 @@ void phch_recv::measure::set_cell(srslte_cell_t cell) if (srslte_ue_dl_set_cell(&ue_dl, cell)) { Error("SYNC: Setting cell: initiating ue_dl_measure\n"); } + reset(); } float phch_recv::measure::rsrp() { @@ -974,6 +992,10 @@ float phch_recv::measure::snr() { return 10*log10(mean_snr); } +float phch_recv::measure::cfo() { + return mean_cfo; +} + phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) { int sync_res = srslte_ue_sync_zerocopy_multi(ue_sync, buffer); @@ -988,10 +1010,12 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) float rsrp = srslte_chest_dl_get_rsrp(&ue_dl.chest); float rsrq = srslte_chest_dl_get_rsrq(&ue_dl.chest); float snr = srslte_chest_dl_get_snr(&ue_dl.chest); + float cfo = srslte_ue_sync_get_cfo(ue_sync); mean_rsrp = SRSLTE_VEC_CMA(rsrp, mean_rsrp, cnt); mean_rsrq = SRSLTE_VEC_CMA(rsrq, mean_rsrq, cnt); - mean_snr = SRSLTE_VEC_CMA(rsrq, mean_snr, cnt); + mean_snr = SRSLTE_VEC_CMA(snr, mean_snr, cnt); + mean_cfo = SRSLTE_VEC_CMA(cfo, mean_cfo, cnt); cnt++; log_h->info("SYNC: Measuring RSRP %d/%d, sf_idx=%d, RSRP=%.1f dBm, SNR=%.1f dB\n", @@ -1022,19 +1046,20 @@ phch_recv::measure::ret_code phch_recv::measure::run_subframe(uint32_t sf_idx) void phch_recv::scell_recv::init(phch_recv *parent, srslte::log *log_h, uint32_t nof_rx_antennas, uint32_t prio, int cpu_affinity) { - this->p = parent; - this->log_h = log_h; + this->p = parent; + this->log_h = log_h; + this->nof_rx_antennas = nof_rx_antennas; // Create the ringbuffer for secondary cell reception for (int i=0;i current_sflen) { + read_samples = current_sflen; + } + if (nsamples < 10) { + read_samples = 0; + } + int n = 0; + for (uint32_t i=0;idebug("SCELL: tti=%d, read %d/%d samples from buffer, buffer size=%d\n", + tti, read_samples,nsamples, srslte_ringbuffer_status(&ring_buffer[0])); + return nsamples; } else { - Error("SYNC: SCell reception not enabled\n"); + Error("SCELL: Reception not enabled\n"); return -1; } } @@ -1079,7 +1151,7 @@ int phch_recv::scell_recv::recv(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, void phch_recv::scell_recv::write(cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time) { if (is_enabled()) { - for (int i = 0; i < SRSLTE_MAX_PORTS; i++) { + for (uint32_t i = 0; i < nof_rx_antennas; i++) { srslte_ringbuffer_write(&ring_buffer[i], data[i], sizeof(cf_t) * nsamples); } } @@ -1090,16 +1162,19 @@ void phch_recv::scell_recv::run_thread() while(running) { switch(scell_state) { case IDLE: + usleep(1000); break; case SCELL_SELECT: switch (sfn_p.run_subframe(&cell, &tti)) { case sfn_sync::SFN_FOUND: - log_h->info("SFN Sync OK. Camping on cell PCI=%d...\n", cell.id); + log_h->info("SCELL: SFN Sync OK. Camping on cell PCI=%d...\n", cell.id); + sfn_p.reset(); + scell_state = SCELL_MEASURE; break; case sfn_sync::TIMEOUT: - log_h->info("SFN sync timeout\n"); + log_h->info("SCELL: SFN sync timeout\n"); break; case sfn_sync::IDLE: break; @@ -1107,11 +1182,15 @@ void phch_recv::scell_recv::run_thread() p->radio_error(); break; } + break; case SCELL_MEASURE: switch (measure_p.run_subframe(tti%10)) { case measure::MEASURE_OK: - log_h->info("SYNC: Measured OK\n"); + log_h->info("SCELL: Measured OK TTI=%5d, RSRP=%.1f dBm, RSRQ=%.1f dB, SNR=%3.1f dB, CFO=%.1f KHz, Buff=%d\n", + tti, measure_p.rsrp(), measure_p.rsrq(), measure_p.snr(), measure_p.cfo()/1000, + srslte_ringbuffer_status(&ring_buffer[0])); + measure_p.reset(); break; case measure::IDLE: break; @@ -1121,6 +1200,8 @@ void phch_recv::scell_recv::run_thread() } break; } + // Increase TTI counter + tti = (tti+1) % 10240; } } diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index df29726d5..0e4bcdc5f 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -243,6 +243,11 @@ void phy::cell_search_next() sf_recv.cell_search_next(); } +void phy::scell_enable(bool enable) +{ + sf_recv.scell_enable(enable); +} + void phy::sync_reset() { sf_recv.reset_sync(); } diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 3560a78fe..ee00d8876 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -213,6 +213,11 @@ void ue::pregenerate_signals(bool enable) phy.enable_pregen_signals(enable); } +void ue::test_scell() +{ + phy.scell_enable(true); +}; + void ue::stop() { if(started)