mirror of https://github.com/PentHertz/srsLTE.git
Minor changes on UE SA PHY
This commit is contained in:
parent
c494a84738
commit
db19941985
|
@ -49,7 +49,11 @@ public:
|
||||||
* @brief Describes a cell select result
|
* @brief Describes a cell select result
|
||||||
*/
|
*/
|
||||||
struct cell_select_result_t {
|
struct cell_select_result_t {
|
||||||
bool successful = false; ///< Cell was found and physical layer is synchronised
|
enum {
|
||||||
|
ERROR = 0, ///< The cell selection procedure failed due a to an invalid configuration
|
||||||
|
UNSUCCESFUL, ///< The cell selection failed to find and synchronise the SSB
|
||||||
|
SUCCESFUL, ///< The cell selection was succesful, resulting in a camping state
|
||||||
|
} status;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -32,15 +32,10 @@
|
||||||
namespace srsran {
|
namespace srsran {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the radio interface for the PHY
|
* Implementation of radio dummy for the PHY testing
|
||||||
*
|
*
|
||||||
* It uses the rf C library object to access the underlying radio. This implementation uses a flat array to
|
* It uses ringbuffers from srsRAN library to emulate baseband transmission and reception. The current implementation
|
||||||
* transmit/receive samples for all RF channels. The N carriers and P antennas are mapped into M=NP RF channels (M <=
|
* does not support dynamic sampling rates, gains and frequencies.
|
||||||
* SRSRAN_MAX_CHANNELS). Note that all carriers must have the same number of antennas.
|
|
||||||
*
|
|
||||||
* The underlying radio receives and transmits M RF channels synchronously from possibly multiple radios using the same
|
|
||||||
* rf driver object. In the current implementation, the mapping between N carriers and P antennas is sequentially, eg:
|
|
||||||
* [carrier_0_port_0, carrier_0_port_1, carrier_1_port_0, carrier_1_port_1, ..., carrier_N_port_N]
|
|
||||||
*/
|
*/
|
||||||
class radio_dummy : public srsran::radio_base, public srsran::radio_interface_phy
|
class radio_dummy : public srsran::radio_base, public srsran::radio_interface_phy
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,6 +111,7 @@ public:
|
||||||
void add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) final {}
|
void add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid) final {}
|
||||||
void remove_eps_bearer(uint8_t eps_bearer_id) final {}
|
void remove_eps_bearer(uint8_t eps_bearer_id) final {}
|
||||||
void reset_eps_bearers() final {}
|
void reset_eps_bearers() final {}
|
||||||
|
void cell_select_completed(const cell_select_result_t& result) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run_thread() final;
|
void run_thread() final;
|
||||||
|
|
|
@ -104,27 +104,32 @@ int slot_sync::recv_callback(srsran::rf_buffer_t& data, srsran_timestamp_t* rx_t
|
||||||
|
|
||||||
bool slot_sync::run_sfn_sync()
|
bool slot_sync::run_sfn_sync()
|
||||||
{
|
{
|
||||||
|
// Run UE SYNC process using the temporal SFN process buffer
|
||||||
srsran_ue_sync_nr_outcome_t outcome = {};
|
srsran_ue_sync_nr_outcome_t outcome = {};
|
||||||
if (srsran_ue_sync_nr_zerocopy(&ue_sync_nr, sfn_sync_buff.to_cf_t(), &outcome) < SRSRAN_SUCCESS) {
|
if (srsran_ue_sync_nr_zerocopy(&ue_sync_nr, sfn_sync_buff.to_cf_t(), &outcome) < SRSRAN_SUCCESS) {
|
||||||
logger.error("SYNC: error in zerocopy");
|
logger.error("SYNC: error in zerocopy");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If in sync, update slot index
|
||||||
if (outcome.in_sync) {
|
if (outcome.in_sync) {
|
||||||
slot_cfg.idx = outcome.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) + outcome.sf_idx;
|
slot_cfg.idx = outcome.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) + outcome.sf_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return true if the PHY in-sync
|
||||||
return outcome.in_sync;
|
return outcome.in_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool slot_sync::run_camping(srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& timestamp)
|
bool slot_sync::run_camping(srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t& timestamp)
|
||||||
{
|
{
|
||||||
|
// Run UE SYNC process using an external baseband buffer
|
||||||
srsran_ue_sync_nr_outcome_t outcome = {};
|
srsran_ue_sync_nr_outcome_t outcome = {};
|
||||||
if (srsran_ue_sync_nr_zerocopy(&ue_sync_nr, buffer.to_cf_t(), &outcome) < SRSRAN_SUCCESS) {
|
if (srsran_ue_sync_nr_zerocopy(&ue_sync_nr, buffer.to_cf_t(), &outcome) < SRSRAN_SUCCESS) {
|
||||||
logger.error("SYNC: error in zerocopy");
|
logger.error("SYNC: error in zerocopy");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If in sync, update slot index
|
||||||
if (outcome.in_sync) {
|
if (outcome.in_sync) {
|
||||||
slot_cfg.idx = outcome.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) + outcome.sf_idx;
|
slot_cfg.idx = outcome.sfn * SRSRAN_NSLOTS_PER_FRAME_NR(srsran_subcarrier_spacing_15kHz) + outcome.sf_idx;
|
||||||
}
|
}
|
||||||
|
@ -132,6 +137,7 @@ bool slot_sync::run_camping(srsran::rf_buffer_t& buffer, srsran::rf_timestamp_t&
|
||||||
// Set RF timestamp
|
// Set RF timestamp
|
||||||
*timestamp.get_ptr(0) = outcome.timestamp;
|
*timestamp.get_ptr(0) = outcome.timestamp;
|
||||||
|
|
||||||
|
// Return true if the PHY in-sync
|
||||||
return outcome.in_sync;
|
return outcome.in_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,10 +149,16 @@ rrc_interface_phy_nr::cell_select_result_t sync_sa::cell_select_run(const phy_in
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> ul(rrc_mutex);
|
std::unique_lock<std::mutex> ul(rrc_mutex);
|
||||||
|
|
||||||
|
// By default, the result is set to error
|
||||||
|
rrc_interface_phy_nr::cell_select_result_t result = {};
|
||||||
|
result.status = rrc_interface_phy_nr::cell_select_result_t::ERROR;
|
||||||
|
|
||||||
// Wait the FSM to transition to IDLE
|
// Wait the FSM to transition to IDLE
|
||||||
if (!wait_idle()) {
|
if (!wait_idle()) {
|
||||||
logger.error("Cell Search: SYNC thread didn't transition to IDLE after 100 ms\n");
|
logger.error("Cell Search: SYNC thread didn't transition to IDLE after 100 ms\n");
|
||||||
return {};
|
|
||||||
|
// Return default result with error status
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
rrc_proc_state = PROC_SELECT_RUNNING;
|
rrc_proc_state = PROC_SELECT_RUNNING;
|
||||||
|
@ -170,19 +176,21 @@ rrc_interface_phy_nr::cell_select_result_t sync_sa::cell_select_run(const phy_in
|
||||||
cfg.ssb.srate_hz = srate_hz;
|
cfg.ssb.srate_hz = srate_hz;
|
||||||
if (slot_synchronizer.set_sync_cfg(cfg)) {
|
if (slot_synchronizer.set_sync_cfg(cfg)) {
|
||||||
logger.error("Cell Search: Failed setting slot synchronizer configuration");
|
logger.error("Cell Search: Failed setting slot synchronizer configuration");
|
||||||
return {};
|
|
||||||
|
// Return default result with error status
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SFN synchronization
|
// SFN synchronization
|
||||||
phy_state.run_sfn_sync();
|
phy_state.run_sfn_sync();
|
||||||
|
|
||||||
// Determine if the procedure was successful if it is camping
|
// Determine if the procedure was successful if the current state is camping, otherwise it is unsuccessful
|
||||||
rrc_interface_phy_nr::cell_select_result_t result = {};
|
if (phy_state.is_camping()) {
|
||||||
result.successful = phy_state.is_camping();
|
|
||||||
if (result.successful) {
|
|
||||||
logger.info("Cell Select: SFN synchronized. CAMPING...");
|
logger.info("Cell Select: SFN synchronized. CAMPING...");
|
||||||
|
result.status = rrc_interface_phy_nr::cell_select_result_t::SUCCESFUL;
|
||||||
} else {
|
} else {
|
||||||
logger.info("Cell Select: Could not synchronize SFN");
|
logger.info("Cell Select: Could not synchronize SFN");
|
||||||
|
result.status = rrc_interface_phy_nr::cell_select_result_t::UNSUCCESFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rrc_proc_state = PROC_IDLE;
|
rrc_proc_state = PROC_IDLE;
|
||||||
|
@ -278,7 +286,7 @@ void sync_sa::run_state_cell_camping()
|
||||||
}
|
}
|
||||||
|
|
||||||
srsran::phy_common_interface::worker_context_t context;
|
srsran::phy_common_interface::worker_context_t context;
|
||||||
context.sf_idx = tti;
|
context.sf_idx = slot_synchronizer.get_slot_cfg().idx;
|
||||||
context.worker_ptr = nr_worker;
|
context.worker_ptr = nr_worker;
|
||||||
context.last = true; // Set last if standalone
|
context.last = true; // Set last if standalone
|
||||||
last_rx_time.add(FDD_HARQ_DELAY_DL_MS * 1e-3);
|
last_rx_time.add(FDD_HARQ_DELAY_DL_MS * 1e-3);
|
||||||
|
|
|
@ -202,4 +202,9 @@ void ue_stack_nr::set_phy_config_complete(bool status)
|
||||||
sync_task_queue.push([this, status]() { rrc->set_phy_config_complete(status); });
|
sync_task_queue.push([this, status]() { rrc->set_phy_config_complete(status); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ue_stack_nr::cell_select_completed(const rrc_interface_phy_nr::cell_select_result_t& result)
|
||||||
|
{
|
||||||
|
sync_task_queue.push([this, result]() { rrc->cell_select_completed(result); });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace srsue
|
} // namespace srsue
|
||||||
|
|
|
@ -230,7 +230,8 @@ int main(int argc, char** argv)
|
||||||
// Start cell selection procedure
|
// Start cell selection procedure
|
||||||
srsue::rrc_interface_phy_nr::cell_select_result_t cs_res =
|
srsue::rrc_interface_phy_nr::cell_select_result_t cs_res =
|
||||||
tb.run_cell_select(args.phy_cfg.carrier, args.phy_cfg.get_ssb_cfg());
|
tb.run_cell_select(args.phy_cfg.carrier, args.phy_cfg.get_ssb_cfg());
|
||||||
srsran_assert(cs_res.successful, "Failed to perform cell selection");
|
srsran_assert(cs_res.status == srsue::rrc_interface_phy_nr::cell_select_result_t::SUCCESFUL,
|
||||||
|
"Failed to perform cell selection");
|
||||||
|
|
||||||
// Run per TTI basis
|
// Run per TTI basis
|
||||||
while (tb.run_tti()) {
|
while (tb.run_tti()) {
|
||||||
|
|
Loading…
Reference in New Issue