SRSUE: Make sure PHY reset is done when SYNC is IDLE

This commit is contained in:
Xavier Arteaga 2021-06-07 18:16:56 +02:00 committed by Xavier Arteaga
parent 49d857cd17
commit 3a011155db
4 changed files with 53 additions and 40 deletions

View File

@ -73,6 +73,13 @@ public:
bool cell_select_start(phy_cell_t cell); bool cell_select_start(phy_cell_t cell);
bool cell_is_camping(); bool cell_is_camping();
/**
* @brief Interface for monitoring UE's synchronization transition to IDLE. In addition to IDLE transitioning, this
* method waits for workers to finish processing and ends the current RF transmission burst.
* @return true if SYNC transitioned to IDLE, false otherwise
*/
bool wait_idle();
// RRC interface for controlling the neighbour cell measurement // RRC interface for controlling the neighbour cell measurement
void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci); void set_cells_to_meas(uint32_t earfcn, const std::set<uint32_t>& pci);
void set_inter_frequency_measurement(uint32_t cc_idx, uint32_t earfcn_, srsran_cell_t cell_); void set_inter_frequency_measurement(uint32_t cc_idx, uint32_t earfcn_, srsran_cell_t cell_);
@ -190,7 +197,7 @@ private:
bool set_cell(float cfo); bool set_cell(float cfo);
std::atomic<bool> running = {false}; std::atomic<bool> running = {false};
bool is_overflow = false; bool is_overflow = false;
srsran::rf_timestamp_t last_rx_time; srsran::rf_timestamp_t last_rx_time;
bool forced_rx_time_init = true; // Rx time sync after first receive from radio bool forced_rx_time_init = true; // Rx time sync after first receive from radio
@ -232,7 +239,7 @@ private:
std::atomic<float> sfo = {}; // SFO estimate updated after each sync-cycle std::atomic<float> sfo = {}; // SFO estimate updated after each sync-cycle
std::atomic<float> cfo = {}; // CFO estimate updated after each sync-cycle std::atomic<float> cfo = {}; // CFO estimate updated after each sync-cycle
std::atomic<float> ref_cfo = {}; // provided adjustment value applied before sync std::atomic<float> ref_cfo = {}; // provided adjustment value applied before sync
sync_metrics_t metrics = {}; sync_metrics_t metrics = {};
// in-sync / out-of-sync counters // in-sync / out-of-sync counters
std::atomic<uint32_t> out_of_sync_cnt = {0}; std::atomic<uint32_t> out_of_sync_cnt = {0};
@ -274,7 +281,7 @@ private:
const static int MIN_TTI_JUMP = 1; ///< Time gap reported to stack after receiving subframe const static int MIN_TTI_JUMP = 1; ///< Time gap reported to stack after receiving subframe
const static int MAX_TTI_JUMP = 1000; ///< Maximum time gap tolerance in RF stream metadata const static int MAX_TTI_JUMP = 1000; ///< Maximum time gap tolerance in RF stream metadata
const uint8_t SYNC_CC_IDX = 0; ///< From the sync POV, the CC idx is always the first const uint8_t SYNC_CC_IDX = 0; ///< From the sync POV, the CC idx is always the first
const uint32_t TIMEOUT_TO_IDLE_MS = 2; ///< Timeout in milliseconds for transitioning to IDLE const uint32_t TIMEOUT_TO_IDLE_MS = 2000; ///< Timeout in milliseconds for transitioning to IDLE
}; };
} // namespace srsue } // namespace srsue

View File

@ -304,10 +304,15 @@ bool phy::cell_select(phy_cell_t cell)
{ {
sfsync.scell_sync_stop(); sfsync.scell_sync_stop();
if (sfsync.cell_select_init(cell)) { if (sfsync.cell_select_init(cell)) {
reset();
// Update PCI before starting the background command to make sure PRACH gets the updated value // Update PCI before starting the background command to make sure PRACH gets the updated value
selected_cell.id = cell.pci; selected_cell.id = cell.pci;
cmd_worker_cell.add_cmd([this, cell]() { cmd_worker_cell.add_cmd([this, cell]() {
// Wait SYNC transitions to IDLE
sfsync.wait_idle();
// Reset worker once SYNC is IDLE to flush any PHY state including measurements, pending ACKs and pending grants
reset();
bool ret = sfsync.cell_select_start(cell); bool ret = sfsync.cell_select_start(cell);
if (ret) { if (ret) {
srsran_cell_t sync_cell; srsran_cell_t sync_cell;
@ -330,8 +335,13 @@ bool phy::cell_search()
{ {
sfsync.scell_sync_stop(); sfsync.scell_sync_stop();
if (sfsync.cell_search_init()) { if (sfsync.cell_search_init()) {
reset();
cmd_worker_cell.add_cmd([this]() { cmd_worker_cell.add_cmd([this]() {
// Wait SYNC transitions to IDLE
sfsync.wait_idle();
// Reset worker once SYNC is IDLE to flush any PHY state including measurements, pending ACKs and pending grants
reset();
phy_cell_t found_cell = {}; phy_cell_t found_cell = {};
rrc_interface_phy_lte::cell_search_ret_t ret = sfsync.cell_search_start(&found_cell); rrc_interface_phy_lte::cell_search_ret_t ret = sfsync.cell_search_start(&found_cell);
stack->cell_search_complete(ret, found_cell); stack->cell_search_complete(ret, found_cell);

View File

@ -873,12 +873,15 @@ void phy_common::reset()
pcell_report_period = 20; pcell_report_period = 20;
last_ri = 0; last_ri = 0;
ZERO_OBJECT(pathloss); {
ZERO_OBJECT(avg_sinr_db); std::unique_lock<std::mutex> lock(meas_mutex);
ZERO_OBJECT(avg_snr_db); ZERO_OBJECT(pathloss);
ZERO_OBJECT(avg_rsrp); ZERO_OBJECT(avg_sinr_db);
ZERO_OBJECT(avg_rsrp_dbm); ZERO_OBJECT(avg_snr_db);
ZERO_OBJECT(avg_rsrq_db); ZERO_OBJECT(avg_rsrp);
ZERO_OBJECT(avg_rsrp_dbm);
ZERO_OBJECT(avg_rsrq_db);
}
cell_state.reset(); cell_state.reset();
reset_neighbour_cells(); reset_neighbour_cells();

View File

@ -219,18 +219,6 @@ rrc_interface_phy_lte::cell_search_ret_t sync::cell_search_start(phy_cell_t* fou
rrc_proc_state = PROC_SEARCH_RUNNING; rrc_proc_state = PROC_SEARCH_RUNNING;
// Wait for SYNC thread to transition to IDLE (max. 2000ms)
if (not phy_state.wait_idle(TIMEOUT_TO_IDLE_MS)) {
Error("SYNC: Error transitioning to IDLE. Cell search cannot start.");
return ret;
}
// Wait for workers to finish PHY processing
worker_com->semaphore.wait_all();
// Reset worker once SYNC is IDLE to flush any worker states such as ACKs and pending grants
worker_com->reset();
if (srate_mode != SRATE_FIND) { if (srate_mode != SRATE_FIND) {
srate_mode = SRATE_FIND; srate_mode = SRATE_FIND;
radio_h->set_rx_srate(1.92e6); radio_h->set_rx_srate(1.92e6);
@ -392,6 +380,26 @@ bool sync::cell_is_camping()
return phy_state.is_camping(); return phy_state.is_camping();
} }
bool sync::wait_idle()
{
// Wait for SYNC thread to transition to IDLE (max. 2000ms)
if (not phy_state.wait_idle(TIMEOUT_TO_IDLE_MS)) {
Error("SYNC: Failed transitioning to IDLE");
return false;
}
// Reset UE sync. Attention: doing this reset when the FSM is NOT IDLE can cause PSS/SSS out-of-sync
srsran_ue_sync_reset(&ue_sync);
// Wait for workers to finish PHY processing
worker_com->semaphore.wait_all();
// As workers have finished, make sure the Tx burst is ended
radio_h->tx_end();
return true;
}
void sync::run_cell_search_state() void sync::run_cell_search_state()
{ {
cell_search_ret = search_p.run(&cell, mib); cell_search_ret = search_p.run(&cell, mib);
@ -802,23 +810,8 @@ void sync::set_ue_sync_opts(srsran_ue_sync_t* q, float cfo)
srsran_sync_set_sss_algorithm(&q->sfind, (sss_alg_t)sss_alg); srsran_sync_set_sss_algorithm(&q->sfind, (sss_alg_t)sss_alg);
} }
bool sync::set_cell(float cfo) bool sync::set_cell(float cfo_in)
{ {
// Wait for SYNC thread to transition to IDLE (max. 2000ms)
if (not phy_state.wait_idle(TIMEOUT_TO_IDLE_MS)) {
Error("SYNC: Can not change Cell while not in IDLE");
return false;
}
// Reset UE sync. Attention: doing this reset when the FSM is NOT IDLE can cause PSS/SSS out-of-sync
srsran_ue_sync_reset(&ue_sync);
// Wait for workers to finish PHY processing
worker_com->semaphore.wait_all();
// Reset worker once SYNC is IDLE to flush any worker states such as ACKs and pending grants
worker_com->reset();
if (!srsran_cell_isvalid(&cell)) { if (!srsran_cell_isvalid(&cell)) {
Error("SYNC: Setting cell: invalid cell (nof_prb=%d, pci=%d, ports=%d)", cell.nof_prb, cell.id, cell.nof_ports); Error("SYNC: Setting cell: invalid cell (nof_prb=%d, pci=%d, ports=%d)", cell.nof_prb, cell.id, cell.nof_ports);
return false; return false;
@ -851,7 +844,7 @@ bool sync::set_cell(float cfo)
} }
// Set options defined in expert section // Set options defined in expert section
set_ue_sync_opts(&ue_sync, cfo); set_ue_sync_opts(&ue_sync, cfo_in);
// Reset ue_sync and set CFO/gain from search procedure // Reset ue_sync and set CFO/gain from search procedure
srsran_ue_sync_reset(&ue_sync); srsran_ue_sync_reset(&ue_sync);