mirror of https://github.com/PentHertz/srsLTE.git
SRSUE: Make sure PHY reset is done when SYNC is IDLE
This commit is contained in:
parent
49d857cd17
commit
3a011155db
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue