diff --git a/srsue/hdr/phy/scell/scell_sync.h b/srsue/hdr/phy/scell/scell_sync.h index b626c6ced..f5a0ceddd 100644 --- a/srsue/hdr/phy/scell/scell_sync.h +++ b/srsue/hdr/phy/scell/scell_sync.h @@ -45,14 +45,19 @@ private: */ typedef enum { STATE_IDLE = 0, STATE_SEARCH_PSS, STATE_IN_SYNCH } state_t; - state_t state = STATE_IDLE; - sync_callback* callback = nullptr; - uint32_t channel = 0; - srslte_sync_t find_pss = {}; - int32_t sf_len = 0; - int32_t cell_id = -1; - std::array temp = {}; - std::mutex mutex; ///< Used for avoiding reconfiguring (set_cell) while it is searching + /** + * Buffer length in subframes, only 2 subframes are allowed + */ + static const uint32_t BUFFER_LEN = 2; + + state_t state = STATE_IDLE; + sync_callback* callback = nullptr; + uint32_t channel = 0; + srslte_sync_t find_pss = {}; + int32_t sf_len = 0; + int32_t cell_id = -1; + std::array temp = {}; + std::mutex mutex; ///< Used for avoiding reconfiguring (set_cell) while it is searching /** * Executes the PSS search state @@ -103,6 +108,35 @@ private: } } + /** + * Unprotected internal resize method for a given bandwidth + */ + void resize(uint32_t new_nof_prb) + { + uint32_t symbol_sz = srslte_symbol_sz(new_nof_prb); + int32_t new_sf_len = SRSLTE_SF_LEN_PRB(new_nof_prb); + + // Reset Temporal buffer + srslte_vec_cf_zero(temp.data(), BUFFER_LEN * new_sf_len); + + // Skip if no BW is changed + if (new_sf_len == sf_len) { + return; + } + + // Resizes synchronization object. As the secondary serving cell base-band might be unaligned respect the primary + // serving cell, the PSS may be located away from the primary serving cell PSS time. The secondary serving cell PSS + // could be in the boundary between subframes, so more than a subframe is required to ensure PSS is captured. Two + // subframes is a simple and conservative buffer size. + if (srslte_sync_resize(&find_pss, BUFFER_LEN * new_sf_len, BUFFER_LEN * new_sf_len, symbol_sz) != SRSLTE_SUCCESS) { + ERROR("Error setting cell sync find"); + } + + // Update values + sf_len = new_sf_len; + cell_id = -1; // Force next set_cell to set the ID + } + public: /** * Constructor @@ -128,22 +162,8 @@ public: // Protect DSP objects and buffers; As it is called by asynchronous thread, it can wait to finish current processing std::unique_lock lock(mutex); - uint32_t symbol_sz = srslte_symbol_sz(nof_prb); - int32_t new_sf_len = SRSLTE_SF_LEN_PRB(nof_prb); - - // Skip if no BW is changed - if (new_sf_len == sf_len) { - return; - } - - // Resize - if (srslte_sync_resize(&find_pss, 2 * new_sf_len, 2 * new_sf_len, symbol_sz) != SRSLTE_SUCCESS) { - ERROR("Error setting cell sync find"); - } - - // Update values - sf_len = new_sf_len; - cell_id = -1; // Force next set_cell to set the ID + // Resizes the DSP objects for the given bandwidth + resize(nof_prb); // Reset state to idle state = STATE_IDLE; @@ -157,21 +177,11 @@ public: // Protect DSP objects and buffers; As it is called by asynchronous thread, it can wait to finish current processing std::unique_lock lock(mutex); - uint32_t symbol_sz = srslte_symbol_sz(cell.nof_prb); - int32_t new_sf_len = SRSLTE_SF_LEN_PRB(cell.nof_prb); - int32_t new_cell_id = cell.id; - - // Resize Sync object - if (new_sf_len != sf_len) { - if (srslte_sync_resize(&find_pss, 2 * new_sf_len, 2 * new_sf_len, symbol_sz) != SRSLTE_SUCCESS) { - ERROR("Error setting cell sync find"); - } - - // Force cell_id set - cell_id = -1; - } + // Resize DSP for the new cell bandwidth + resize(cell.nof_prb); - // Configure + // Configure only if the cell identifier has changed + int32_t new_cell_id = cell.id; if (cell_id != new_cell_id) { srslte_sync_set_frame_type(&find_pss, cell.frame_type); srslte_sync_set_N_id_2(&find_pss, new_cell_id % SRSLTE_NOF_NID_2); @@ -179,15 +189,9 @@ public: srslte_sync_set_cfo_ema_alpha(&find_pss, 0.1); srslte_sync_set_em_alpha(&find_pss, 1); srslte_sync_set_threshold(&find_pss, 3.0); + cell_id = new_cell_id; } - // Reset Temporal buffer - srslte_vec_cf_zero(temp.data(), 2 * sf_len); - - // Update new values - sf_len = new_sf_len; - cell_id = new_cell_id; - // Go to search PSS state = STATE_SEARCH_PSS; } @@ -198,7 +202,7 @@ public: void stop() { state = STATE_IDLE; } /** - * Runs internal FSM, performing Synchronization operations on the provided buffer. It expects data per sub-frame + * Runs internal FSM, performing Synchronization operations on the provided buffer. It expects data per subframe * basis (1 ms). * @param tti Current primary serving cell time * @param buffer Base-band buffer of the given secondary serving cell @@ -206,7 +210,7 @@ public: void run(uint32_t tti, cf_t* buffer) { // Try to get lock. The lock is unsuccessful if the DSP objects are getting configured. In this case, ignore - // the sub-frame. + // the subframe. if (not mutex.try_lock()) { return; }