diff --git a/lib/include/srslte/phy/common/timestamp.h b/lib/include/srslte/phy/common/timestamp.h index 7a75add12..cd0cb1883 100644 --- a/lib/include/srslte/phy/common/timestamp.h +++ b/lib/include/srslte/phy/common/timestamp.h @@ -52,7 +52,7 @@ SRSLTE_API void srslte_timestamp_init_uint64(srslte_timestamp_t* ts_time, uint64 SRSLTE_API int srslte_timestamp_copy(srslte_timestamp_t* dest, srslte_timestamp_t* src); -SRSLTE_API int srslte_timestamp_compare(srslte_timestamp_t* a, srslte_timestamp_t* b); +SRSLTE_API int srslte_timestamp_compare(const srslte_timestamp_t* a, const srslte_timestamp_t* b); SRSLTE_API int srslte_timestamp_add(srslte_timestamp_t* t, time_t full_secs, double frac_secs); diff --git a/lib/src/phy/common/timestamp.c b/lib/src/phy/common/timestamp.c index d36dc35a0..ea3e6cf4a 100644 --- a/lib/src/phy/common/timestamp.c +++ b/lib/src/phy/common/timestamp.c @@ -53,7 +53,7 @@ int srslte_timestamp_copy(srslte_timestamp_t *dest, srslte_timestamp_t *src){ return ret; } -int srslte_timestamp_compare(srslte_timestamp_t* a, srslte_timestamp_t* b) +int srslte_timestamp_compare(const srslte_timestamp_t* a, const srslte_timestamp_t* b) { int ret = 0; diff --git a/srsue/hdr/phy/sync.h b/srsue/hdr/phy/sync.h index 8e69416b8..e47a110ab 100644 --- a/srsue/hdr/phy/sync.h +++ b/srsue/hdr/phy/sync.h @@ -343,11 +343,13 @@ private: float current_srate = 0; // This is the primary cell - srslte_cell_t cell = {}; - bool started = false; - float time_adv_sec = 0; - float next_time_adv_sec = 0; - uint32_t tti = 0; + srslte_cell_t cell = {}; + bool started = false; + float time_adv_sec = 0; + float next_time_adv_sec = 0; + uint32_t tti = 0; + srslte_timestamp_t tti_ts = {}; + srslte_timestamp_t radio_ts = {}; std::array mib; uint32_t tx_worker_cnt = 0; diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index c09413893..57e671a0b 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -34,7 +34,8 @@ namespace srsue { -int radio_recv_callback(void *obj, cf_t *data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t *rx_time) { +static int radio_recv_callback(void* obj, cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time) +{ return ((sync*)obj)->radio_recv_fnc(data, nsamples, rx_time); } @@ -587,8 +588,8 @@ void sync::run_thread() nsamples = current_srate/1000; } Debug("Discarting %d samples\n", nsamples); - srslte_timestamp_t rx_time; - if (!radio_h->rx_now(0, dummy_buffer, nsamples, &rx_time)) { + srslte_timestamp_t rx_time = {}; + if (!radio_recv_fnc(dummy_buffer, nsamples, &rx_time)) { log_h->console("SYNC: Receiving from radio while in IDLE_RX\n"); } // If radio is in locked state returns inmidiatetly. In that case, do a 1 ms sleep @@ -641,8 +642,6 @@ void sync::run_thread() // Increase TTI counter tti = (tti+1) % 10240; - - stack->run_tti(tti); } for (uint32_t p = 0; p < nof_rf_channels; p++) { @@ -912,9 +911,32 @@ void sync::get_current_cell(srslte_cell_t* cell, uint32_t* earfcn) int sync::radio_recv_fnc(cf_t* data[SRSLTE_MAX_PORTS], uint32_t nsamples, srslte_timestamp_t* rx_time) { + srslte_timestamp_t ts = {}; + + // Use local timestamp if timestamp is not provided + if (!rx_time) { + rx_time = &ts; + } + + // Receive if (radio_h->rx_now(0, data, nsamples, rx_time)) { + // Detect Radio Timestamp reset + if (srslte_timestamp_compare(rx_time, &radio_ts) < 0) { + srslte_timestamp_init(&radio_ts, 0, 0.0); + } + srslte_timestamp_copy(&radio_ts, rx_time); + + // Advance stack in time + while (srslte_timestamp_compare(rx_time, &tti_ts) > 0) { + // Run stack + stack->run_tti(tti); + + // Increase one millisecond + srslte_timestamp_add(&tti_ts, 0, 1.0e-3f); + } + if (channel_emulator && rx_time) { - channel_emulator->set_srate(current_srate); + channel_emulator->set_srate((uint32_t)current_srate); channel_emulator->run(data, data, nsamples, *rx_time); }