diff --git a/srsue/hdr/phy/prach.h b/srsue/hdr/phy/prach.h index ac2e306a3..2a6bd526b 100644 --- a/srsue/hdr/phy/prach.h +++ b/srsue/hdr/phy/prach.h @@ -22,6 +22,7 @@ #ifndef SRSUE_PRACH_H #define SRSUE_PRACH_H +#include #include #include "srslte/common/log.h" @@ -57,22 +58,37 @@ public: phy_interface_mac_lte::prach_info_t get_info(); +private: + bool generate_buffer(uint32_t f_idx); + + bool is_buffer_generated(uint32_t f_idx, uint32_t preamble_index) const + { + return buffer_bitmask.test(f_idx * 64 + preamble_index); + } + + void set_buffer_as_generated(uint32_t f_idx, uint32_t preamble_index) + { + buffer_bitmask.set(f_idx * 64 + preamble_index); + } + private: const static int MAX_LEN_SF = 3; - srslte::log* log_h; - int preamble_idx; - int allowed_subframe; - bool mem_initiated; - bool cell_initiated; - uint32_t len; - cf_t* buffer[12][64]; - srslte_prach_t prach_obj; - int transmitted_tti; - srslte_cell_t cell; - cf_t* signal_buffer; - srslte_cfo_t cfo_h; - float target_power_dbm; + srslte::log* log_h; + int preamble_idx; + int allowed_subframe; + bool mem_initiated; + bool cell_initiated; + uint32_t len; + cf_t* buffer[12][64]; + std::bitset<12 * 64> buffer_bitmask; + srslte_prach_t prach_obj; + int transmitted_tti; + srslte_cell_t cell; + cf_t* signal_buffer; + srslte_cfo_t cfo_h; + float target_power_dbm; + srslte_prach_cfg_t cfg = {}; }; } // namespace srsue diff --git a/srsue/src/phy/prach.cc b/srsue/src/phy/prach.cc index d95e66299..fffc6f06b 100644 --- a/srsue/src/phy/prach.cc +++ b/srsue/src/phy/prach.cc @@ -104,6 +104,7 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) // TODO: Check if other PRACH parameters changed if (cell.id != cell_.id || !cell_initiated) { cell = cell_; + cfg = prach_cfg; preamble_idx = -1; if (6 + prach_cfg.freq_offset > cell.nof_prb) { @@ -125,33 +126,7 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) return false; } - uint32_t nof_f_idx = 1; - if (cell.frame_type == SRSLTE_TDD) { - nof_f_idx = srslte_prach_nof_f_idx_tdd(prach_cfg.config_idx, prach_cfg.tdd_config.sf_config); - // For format4, generate prach for even and odd position - if (prach_cfg.config_idx >= 48) { - nof_f_idx *= 2; - } - } - - for (int i = 0; i < 64; i++) { - for (uint32_t f = 0; f < nof_f_idx; f++) { - uint32_t freq_offset = prach_cfg.freq_offset; - if (cell.frame_type == SRSLTE_TDD) { - freq_offset = srslte_prach_f_ra_tdd(prach_cfg.config_idx, - prach_cfg.tdd_config.sf_config, - (f / 6) * 10, - f % 6, - prach_cfg.freq_offset, - cell.nof_prb); - } - if (srslte_prach_gen(&prach_obj, i, freq_offset, buffer[f][i])) { - Error("Generating PRACH preamble %d\n", i); - return false; - } - } - } - + buffer_bitmask.reset(); len = prach_obj.N_seq + prach_obj.N_cp; transmitted_tti = -1; cell_initiated = true; @@ -163,6 +138,28 @@ bool prach::set_cell(srslte_cell_t cell_, srslte_prach_cfg_t prach_cfg) } } +bool prach::generate_buffer(uint32_t f_idx) +{ + if (is_buffer_generated(f_idx, preamble_idx)) { + printf("generation was already done\n"); + return true; + } + + uint32_t freq_offset = cfg.freq_offset; + if (cell.frame_type == SRSLTE_TDD) { + freq_offset = srslte_prach_f_ra_tdd( + cfg.config_idx, cfg.tdd_config.sf_config, (f_idx / 6) * 10, f_idx % 6, cfg.freq_offset, cell.nof_prb); + } + if (srslte_prach_gen(&prach_obj, preamble_idx, freq_offset, buffer[f_idx][preamble_idx])) { + Error("Generating PRACH preamble %d\n", preamble_idx); + return false; + } + + set_buffer_as_generated(f_idx, preamble_idx); + + return true; +} + bool prach::prepare_to_send(uint32_t preamble_idx_, int allowed_subframe_, float target_power_dbm_) { if (cell_initiated && preamble_idx_ < 64) { @@ -237,6 +234,15 @@ cf_t* prach::generate(float cfo, uint32_t* nof_sf, float* target_power) } } + if (!generate_buffer(f_idx)) { + return NULL; + } + + if (!is_buffer_generated(f_idx, preamble_idx)) { + Error("PRACH Buffer not generated: f_idx=%d preamble_idx=%d\n", f_idx, preamble_idx); + return NULL; + } + // Correct CFO before transmission srslte_cfo_correct(&cfo_h, buffer[f_idx][preamble_idx], signal_buffer, cfo / srslte_symbol_sz(cell.nof_prb));