Fix and tidy up time offset in srsue

master
Xavier Arteaga 5 years ago committed by Xavier Arteaga
parent 34bc192f70
commit 11a2d2cc4a

@ -334,7 +334,10 @@ private:
channel_mapping rx_channel_mapping = {}, tx_channel_mapping = {}; channel_mapping rx_channel_mapping = {}, tx_channel_mapping = {};
bool map_channels(channel_mapping& map, const rf_buffer_interface& buffer, void* radio_buffers[SRSLTE_MAX_CHANNELS]); bool map_channels(channel_mapping& map,
uint32_t sample_offset,
const rf_buffer_interface& buffer,
void* radio_buffers[SRSLTE_MAX_CHANNELS]);
bool start_agc(bool tx_gain_same_rx = false); bool start_agc(bool tx_gain_same_rx = false);
void set_tx_adv(int nsamples); void set_tx_adv(int nsamples);
void set_tx_adv_neg(bool tx_adv_is_neg); void set_tx_adv_neg(bool tx_adv_is_neg);

@ -222,7 +222,7 @@ bool radio::rx_now(rf_buffer_interface& buffer, const uint32_t& nof_samples, srs
double* frac_secs = rxd_time ? &rxd_time->frac_secs : NULL; double* frac_secs = rxd_time ? &rxd_time->frac_secs : NULL;
void* radio_buffers[SRSLTE_MAX_CHANNELS] = {}; void* radio_buffers[SRSLTE_MAX_CHANNELS] = {};
if (!map_channels(rx_channel_mapping, buffer, radio_buffers)) { if (!map_channels(rx_channel_mapping, 0, buffer, radio_buffers)) {
log_h->error("Mapping logical channels to physical channels for transmission\n"); log_h->error("Mapping logical channels to physical channels for transmission\n");
return false; return false;
} }
@ -260,8 +260,11 @@ bool radio::has_rssi()
return srslte_rf_has_rssi(&rf_device); return srslte_rf_has_rssi(&rf_device);
} }
bool radio::tx(rf_buffer_interface& buffer, const uint32_t& nof_samples, const srslte_timestamp_t& tx_time_) bool radio::tx(rf_buffer_interface& buffer, const uint32_t& nof_samples_, const srslte_timestamp_t& tx_time_)
{ {
uint32_t nof_samples = nof_samples_;
uint32_t sample_offset = 0;
if (!is_initialized) { if (!is_initialized) {
return false; return false;
} }
@ -272,12 +275,32 @@ bool radio::tx(rf_buffer_interface& buffer, const uint32_t& nof_samples, const s
srslte_timestamp_add(&tx_time, 0, tx_adv_sec); srslte_timestamp_add(&tx_time, 0, tx_adv_sec);
} }
// Calculate Tx gap if it is not start of the burst
if (not is_start_of_burst) {
srslte_timestamp_t tx_gap = end_of_burst_time;
srslte_timestamp_sub(&tx_gap, tx_time.full_secs, tx_time.frac_secs);
int32_t past_nsamples = (int32_t)round(cur_tx_srate * srslte_timestamp_real(&tx_gap));
// Negative gap, trimming first samples by setting a sample offset. Otherwise, ignore
if (past_nsamples > 0) {
// If the gap is larger than the amount of samples to transmit, return without doing anything else
if ((int32_t)nof_samples < past_nsamples) {
return true;
}
// Update transmission parameters
tx_time = end_of_burst_time;
nof_samples -= past_nsamples;
sample_offset = (uint32_t)past_nsamples;
}
}
// Save possible end of burst time // Save possible end of burst time
srslte_timestamp_copy(&end_of_burst_time, &tx_time); srslte_timestamp_copy(&end_of_burst_time, &tx_time);
srslte_timestamp_add(&end_of_burst_time, 0, (double)nof_samples / cur_tx_srate); srslte_timestamp_add(&end_of_burst_time, 0, (double)nof_samples / cur_tx_srate);
void* radio_buffers[SRSLTE_MAX_CHANNELS] = {}; void* radio_buffers[SRSLTE_MAX_CHANNELS] = {};
if (!map_channels(rx_channel_mapping, buffer, radio_buffers)) { if (!map_channels(rx_channel_mapping, sample_offset, buffer, radio_buffers)) {
log_h->error("Mapping logical channels to physical channels for transmission\n"); log_h->error("Mapping logical channels to physical channels for transmission\n");
return false; return false;
} }
@ -285,11 +308,7 @@ bool radio::tx(rf_buffer_interface& buffer, const uint32_t& nof_samples, const s
int ret = srslte_rf_send_timed_multi( int ret = srslte_rf_send_timed_multi(
&rf_device, radio_buffers, nof_samples, tx_time.full_secs, tx_time.frac_secs, true, is_start_of_burst, false); &rf_device, radio_buffers, nof_samples, tx_time.full_secs, tx_time.frac_secs, true, is_start_of_burst, false);
is_start_of_burst = false; is_start_of_burst = false;
if (ret > 0) { return ret > SRSLTE_SUCCESS;
return true;
} else {
return false;
}
} }
void radio::tx_end() void radio::tx_end()
@ -616,6 +635,7 @@ void radio::rf_msg_callback(void* arg, srslte_rf_error_t error)
} }
bool radio::map_channels(channel_mapping& map, bool radio::map_channels(channel_mapping& map,
uint32_t sample_offset,
const rf_buffer_interface& buffer, const rf_buffer_interface& buffer,
void* radio_buffers[SRSLTE_MAX_CHANNELS]) void* radio_buffers[SRSLTE_MAX_CHANNELS])
{ {
@ -630,7 +650,7 @@ bool radio::map_channels(channel_mapping& map,
uint32_t physical_idx = map.get_carrier_idx(i); uint32_t physical_idx = map.get_carrier_idx(i);
for (uint32_t j = 0; j < nof_antennas; j++) { for (uint32_t j = 0; j < nof_antennas; j++) {
if (physical_idx * nof_antennas + j < SRSLTE_MAX_CHANNELS) { if (physical_idx * nof_antennas + j < SRSLTE_MAX_CHANNELS) {
radio_buffers[physical_idx * nof_antennas + j] = buffer.get(i, j, nof_antennas); radio_buffers[physical_idx * nof_antennas + j] = buffer.get(i, j, nof_antennas) + sample_offset;
} else { } else {
return false; return false;
} }

@ -35,9 +35,6 @@ private:
mutable std::mutex mutex; mutable std::mutex mutex;
uint32_t next_base_nta = 0; uint32_t next_base_nta = 0;
float next_base_sec = 0.0f; float next_base_sec = 0.0f;
float current_base_sec = 0.0f;
float prev_base_sec = 0.0f;
int32_t pending_nsamples = 0;
public: public:
/** /**
@ -62,9 +59,6 @@ public:
// Update base in nta // Update base in nta
next_base_nta = static_cast<uint32_t>(roundf(next_base_sec / SRSLTE_LTE_TS)); next_base_nta = static_cast<uint32_t>(roundf(next_base_sec / SRSLTE_LTE_TS));
// Resets pending samples
pending_nsamples = 0;
// Log information information if available // Log information information if available
if (log_h) { if (log_h) {
log_h->info("PHY: Set TA base: n_ta: %d, ta_usec: %.1f\n", next_base_nta, next_base_sec * 1e6f); log_h->info("PHY: Set TA base: n_ta: %d, ta_usec: %.1f\n", next_base_nta, next_base_sec * 1e6f);
@ -138,43 +132,17 @@ public:
} }
} }
/**
* Increments/Decrements the number pending samples for next transmission
*
* @param nsamples is the number of samples
*/
void set_pending_nsamples(int32_t nsamples)
{
std::lock_guard<std::mutex> lock(mutex);
// Increment number of pending samples
pending_nsamples += nsamples;
}
/**
* Get the previous time alignment in seconds
*
* @return Time alignment in seconds
*/
float get_previous_sec() const
{
std::lock_guard<std::mutex> lock(mutex);
// Returns the previous base
return prev_base_sec;
}
/** /**
* Get the current time alignment in seconds * Get the current time alignment in seconds
* *
* @return Time alignment in seconds * @return Time alignment in seconds
*/ */
float get_current_sec() const float get_sec() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
// Returns the current base // Returns the current base
return current_base_sec; return next_base_sec;
} }
/** /**
@ -182,12 +150,12 @@ public:
* *
* @return Time alignment in microseconds * @return Time alignment in microseconds
*/ */
float get_current_usec() const float get_usec() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
// Returns the current base // Returns the current base
return current_base_sec * 1e6f; return next_base_sec * 1e6f;
} }
/** /**
@ -195,41 +163,12 @@ public:
* *
* @return Distance based on the current time base * @return Distance based on the current time base
*/ */
float get_current_km() const float get_km() const
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
// Returns the current base, one direction distance // Returns the current base, one direction distance
return current_base_sec * (3.6f * 3e8f / 2.0f); return next_base_sec * (3.6f * 3e8f / 2.0f);
}
/**
* Get the total number of pending samples to transmit, considering the time difference between the next base and the
* current base.
*
* Attention: this method changes the internal state of the class.
*
* @return the total number of pending samples considering the sampling rate
*/
int32_t get_pending_nsamples(uint32_t sampling_rate_hz)
{
std::lock_guard<std::mutex> lock(mutex);
// Convert sampling rate to float
float srate = static_cast<float>(sampling_rate_hz);
// Calculate number of samples
int32_t nsamples = static_cast<int32_t>(roundf(srate * (current_base_sec - next_base_sec)));
// Update current base
prev_base_sec = current_base_sec;
current_base_sec = next_base_sec;
// Reset pending samples
pending_nsamples = 0;
// Return number of samples
return nsamples;
} }
}; };

@ -532,6 +532,9 @@ void phy_common::worker_end(void* tx_sem_id,
// Wait for the green light to transmit in the current TTI // Wait for the green light to transmit in the current TTI
semaphore.wait(tx_sem_id); semaphore.wait(tx_sem_id);
// Add Time Alignment
srslte_timestamp_sub(&tx_time, 0, ta.get_sec());
// For each radio, transmit // For each radio, transmit
if (tx_enable && !srslte_timestamp_iszero(&tx_time)) { if (tx_enable && !srslte_timestamp_iszero(&tx_time)) {

@ -206,7 +206,6 @@ void sf_worker::work_imp()
bool rx_signal_ok = false; bool rx_signal_ok = false;
bool tx_signal_ready = false; bool tx_signal_ready = false;
uint32_t nof_samples = SRSLTE_SF_LEN_PRB(cell.nof_prb); uint32_t nof_samples = SRSLTE_SF_LEN_PRB(cell.nof_prb);
int32_t next_offset = 0;
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
@ -231,9 +230,6 @@ void sf_worker::work_imp()
} }
} }
// Load TA
next_offset = phy->ta.get_pending_nsamples(nof_samples * 1000U);
/***** Uplink Generation + Transmission *******/ /***** Uplink Generation + Transmission *******/
/* If TTI+4 is an uplink subframe (TODO: Support short PRACH and SRS in UpPts special subframes) */ /* If TTI+4 is an uplink subframe (TODO: Support short PRACH and SRS in UpPts special subframes) */
@ -250,12 +246,7 @@ void sf_worker::work_imp()
tx_signal_ready |= cc_workers[carrier_idx]->work_ul(&uci_data); tx_signal_ready |= cc_workers[carrier_idx]->work_ul(&uci_data);
// Set signal pointer based on offset // Set signal pointer based on offset
cf_t* b = cc_workers[carrier_idx]->get_tx_buffer(0); tx_signal_ptr.set((uint32_t)carrier_idx, 0, phy->args->nof_rx_ant, cc_workers[carrier_idx]->get_tx_buffer(0));
if (next_offset > 0) {
tx_signal_ptr.set(carrier_idx, 0, phy->args->nof_rx_ant, b);
} else {
tx_signal_ptr.set(carrier_idx, 0, phy->args->nof_rx_ant, &b[-next_offset]);
}
} }
} }
} }
@ -263,13 +254,9 @@ void sf_worker::work_imp()
// Set PRACH buffer signal pointer // Set PRACH buffer signal pointer
if (prach_ptr) { if (prach_ptr) {
srslte_timestamp_sub(&tx_time, 0, phy->ta.get_current_sec());
tx_signal_ready = true; tx_signal_ready = true;
tx_signal_ptr.set(0, prach_ptr); tx_signal_ptr.set(0, prach_ptr);
prach_ptr = nullptr; prach_ptr = nullptr;
} else {
srslte_timestamp_sub(&tx_time, 0, phy->ta.get_previous_sec());
nof_samples += next_offset;
} }
// Call worker_end to transmit the signal // Call worker_end to transmit the signal

@ -473,7 +473,7 @@ void sync::run_thread()
metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync); metrics.sfo = srslte_ue_sync_get_sfo(&ue_sync);
metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync); metrics.cfo = srslte_ue_sync_get_cfo(&ue_sync);
metrics.ta_us = worker_com->ta.get_current_usec(); metrics.ta_us = worker_com->ta.get_usec();
for (uint32_t i = 0; i < worker_com->args->nof_carriers; i++) { for (uint32_t i = 0; i < worker_com->args->nof_carriers; i++) {
worker_com->set_sync_metrics(i, metrics); worker_com->set_sync_metrics(i, metrics);
} }
@ -862,13 +862,6 @@ int sync::radio_recv_fnc(srslte::rf_buffer_t& data, uint32_t nsamples, srslte_ti
} }
} }
int offset = nsamples - current_sflen;
if (abs(offset) < 10 && offset != 0) {
worker_com->ta.set_pending_nsamples(offset);
} else if (nsamples < 10) {
worker_com->ta.set_pending_nsamples(nsamples);
}
log_h->debug("SYNC: received %d samples from radio\n", nsamples); log_h->debug("SYNC: received %d samples from radio\n", nsamples);
return nsamples; return nsamples;

Loading…
Cancel
Save