Implement MAC/RRC setter/getter functions to support multiple TDD patterns
* set_tdd_bmap_period, config_tdd_patterns: to configure TDD period, including bitmap, in the frame structure * get_tdd_periodicity: to retrieve the periodicity in milliseconds for the given TDD pattern * get_tdd_period_idx: to get the TDD period index based on pattern periodicities * get_ul_slots_per_period: get the number of UL slots (including mixed with UL symbols) in period * get_full_ul_slots_per_period: get the number of full UL slots in period * get_dl_slots_per_period: get the number of DL slots (including mixed with DL symbols) in period * get_full_dl_slots_per_period: get the number of full DL slots in period Co-authored-by: vijay chadachan <vijay.chadachan@firecell.io>
This commit is contained in:
committed by
Guido Casati
co-authored by
vijay chadachan
parent
9cf1ce7427
commit
c3a6700037
@@ -676,6 +676,14 @@ uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t nrarfcn)
|
||||
return frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the slot index within the period
|
||||
*/
|
||||
int get_slot_idx_in_period(const int slot, const frame_structure_t *fs)
|
||||
{
|
||||
return slot % fs->numb_slots_period;
|
||||
}
|
||||
|
||||
int get_first_ul_slot(int nrofDownlinkSlots, int nrofDownlinkSymbols, int nrofUplinkSymbols)
|
||||
{
|
||||
return (nrofDownlinkSlots + (nrofDownlinkSymbols != 0 && nrofUplinkSymbols == 0));
|
||||
|
||||
@@ -279,6 +279,8 @@ int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_
|
||||
unsigned short get_m_srs(int c_srs, int b_srs);
|
||||
unsigned short get_N_b_srs(int c_srs, int b_srs);
|
||||
|
||||
int get_slot_idx_in_period(const int slot, const frame_structure_t *fs);
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
|
||||
|
||||
|
||||
@@ -283,6 +283,206 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
|
||||
return mat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the TDD period, including bitmap, in the frame structure
|
||||
*
|
||||
* This function sets the TDD period configuration for DL, UL, and mixed slots in
|
||||
* the specified frame structure instance, according to the given pattern, and
|
||||
* updates the bitmap.
|
||||
*
|
||||
* @param pattern NR_TDD_UL_DL_Pattern_t configuration containing TDD slots and symbols configuration
|
||||
* @param fs frame_structure_t pointer
|
||||
* @param curr_total_slot current position in the slot bitmap to start from
|
||||
*
|
||||
* @return Number of slots in the configured TDD period
|
||||
*/
|
||||
static uint8_t set_tdd_bmap_period(NR_TDD_UL_DL_Pattern_t *pattern, tdd_period_config_t *pc, int8_t curr_total_slot)
|
||||
{
|
||||
int8_t n_dl_slot = pattern->nrofDownlinkSlots;
|
||||
int8_t n_ul_slot = pattern->nrofUplinkSlots;
|
||||
int8_t n_dl_symbols = pattern->nrofDownlinkSymbols;
|
||||
int8_t n_ul_symbols = pattern->nrofUplinkSymbols;
|
||||
|
||||
// Total slots in the period: if DL/UL symbols are present, is mixed slot
|
||||
const bool has_mixed_slot = (n_ul_symbols + n_dl_symbols) > 0;
|
||||
int8_t total_slot = has_mixed_slot ? n_dl_slot + n_ul_slot + 1 : n_dl_slot + n_ul_slot;
|
||||
|
||||
/** Update TDD period configuration:
|
||||
* mixed slots with DL symbols are counted as DL slots
|
||||
* mixed slots with UL symbols are counted as UL slots */
|
||||
pc->num_dl_slots += (n_dl_slot + (n_dl_symbols > 0));
|
||||
pc->num_ul_slots += (n_ul_slot + (n_ul_symbols > 0));
|
||||
|
||||
// Populate the slot bitmap for each slot in the TDD period
|
||||
for (int i = 0; i < total_slot; i++) {
|
||||
tdd_bitmap_t *bitmap = &pc->tdd_slot_bitmap[i + curr_total_slot];
|
||||
if (i < n_dl_slot)
|
||||
bitmap->slot_type = TDD_NR_DOWNLINK_SLOT;
|
||||
else if ((i == n_dl_slot) && has_mixed_slot) {
|
||||
bitmap->slot_type = TDD_NR_MIXED_SLOT;
|
||||
bitmap->num_dl_symbols = n_dl_symbols;
|
||||
bitmap->num_ul_symbols = n_ul_symbols;
|
||||
} else if (n_ul_slot)
|
||||
bitmap->slot_type = TDD_NR_UPLINK_SLOT;
|
||||
}
|
||||
|
||||
LOG_I(NR_MAC,
|
||||
"Set TDD configuration period to: %d DL slots, %d UL slots, %d slots per period (NR_TDD_UL_DL_Pattern is %d DL slots, %d "
|
||||
"UL slots, %d DL symbols, %d UL symbols)\n",
|
||||
pc->num_dl_slots,
|
||||
pc->num_ul_slots,
|
||||
total_slot,
|
||||
n_dl_slot,
|
||||
n_ul_slot,
|
||||
n_dl_symbols,
|
||||
n_ul_symbols);
|
||||
|
||||
return total_slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures TDD patterns (1 or 2) in the frame structure
|
||||
*
|
||||
* This function sets up the TDD configuration in the frame structure by applying
|
||||
* DL and UL patterns as defined in NR_TDD_UL_DL_ConfigCommon.
|
||||
* It handles both TDD pattern1 and pattern2.
|
||||
*
|
||||
* @param tdd NR_TDD_UL_DL_ConfigCommon_t pointer containing pattern1 and pattern2
|
||||
* @param fs Pointer to the frame structure to update with the configured TDD patterns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
static void config_tdd_patterns(NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_structure_t *fs)
|
||||
{
|
||||
int num_of_patterns = 1;
|
||||
uint8_t nb_slots_p2 = 0;
|
||||
// Reset num dl/ul slots
|
||||
tdd_period_config_t *pc = &fs->period_cfg;
|
||||
pc->num_dl_slots = 0;
|
||||
pc->num_ul_slots = 0;
|
||||
// Pattern1
|
||||
uint8_t nb_slots_p1 = set_tdd_bmap_period(&tdd->pattern1, pc, 0);
|
||||
// Pattern2
|
||||
if (tdd->pattern2) {
|
||||
num_of_patterns++;
|
||||
nb_slots_p2 = set_tdd_bmap_period(tdd->pattern2, pc, nb_slots_p1);
|
||||
}
|
||||
LOG_I(NR_MAC,
|
||||
"Configured %d TDD patterns (total slots: pattern1 = %d, pattern2 = %d)\n",
|
||||
num_of_patterns,
|
||||
nb_slots_p1,
|
||||
nb_slots_p2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of DL slots per period (full DL slots + mixed slots with DL symbols)
|
||||
*/
|
||||
int get_dl_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
return fs->is_tdd ? fs->period_cfg.num_dl_slots : fs->numb_slots_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of UL slots per period (full UL slots + mixed slots with UL symbols)
|
||||
*/
|
||||
int get_ul_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
return fs->is_tdd ? fs->period_cfg.num_ul_slots : fs->numb_slots_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of full UL slots per period
|
||||
* @param fs Pointer to the frame structure
|
||||
* @return Number of full UL slots
|
||||
*/
|
||||
int get_full_ul_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
if (!fs->is_tdd)
|
||||
return fs->numb_slots_frame;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_period; i++)
|
||||
if (fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT)
|
||||
count++;
|
||||
|
||||
LOG_D(NR_MAC, "Full UL slots in TDD period: %d\n", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of full DL slots per period
|
||||
* @param fs Pointer to the frame structure
|
||||
* @return Number of full DL slots
|
||||
*/
|
||||
int get_full_dl_slots_per_period(const frame_structure_t *fs)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
if (!fs->is_tdd)
|
||||
return fs->numb_slots_frame;
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_period; i++)
|
||||
if (fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_DOWNLINK_SLOT)
|
||||
count++;
|
||||
|
||||
LOG_D(NR_MAC, "Full DL slots in TDD period: %d\n", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of UL slots per frame
|
||||
*/
|
||||
int get_ul_slots_per_frame(const frame_structure_t *fs)
|
||||
{
|
||||
return fs->is_tdd ? fs->numb_period_frame * get_ul_slots_per_period(fs) : fs->numb_slots_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the frame structure and the NFAPI config request
|
||||
* depending on the duplex mode. If TDD, does the TDD patterns
|
||||
* and TDD periods configuration.
|
||||
*
|
||||
* @param mu numerology
|
||||
* @param scc pointer to scc
|
||||
* @param cfg pointer to NFAPI config request
|
||||
* @param fs pointer to the frame structure to update
|
||||
*
|
||||
* @return Number of periods in frame
|
||||
*/
|
||||
static int config_frame_structure(int mu,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
nfapi_nr_config_request_scf_t *cfg,
|
||||
frame_structure_t *fs)
|
||||
{
|
||||
fs->numb_slots_frame = nr_slots_per_frame[mu];
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD) {
|
||||
cfg->tdd_table.tdd_period.tl.tag = NFAPI_NR_CONFIG_TDD_PERIOD_TAG;
|
||||
cfg->num_tlv++;
|
||||
cfg->tdd_table.tdd_period.value = get_tdd_period_idx(scc->tdd_UL_DL_ConfigurationCommon);
|
||||
fs->numb_period_frame = get_nb_periods_per_frame(cfg->tdd_table.tdd_period.value);
|
||||
fs->numb_slots_period = fs->numb_slots_frame / fs->numb_period_frame;
|
||||
fs->is_tdd = true;
|
||||
config_tdd_patterns(scc->tdd_UL_DL_ConfigurationCommon, fs);
|
||||
set_tdd_config_nr(cfg,
|
||||
mu,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots,
|
||||
scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols);
|
||||
} else { // FDD
|
||||
fs->is_tdd = false;
|
||||
fs->numb_period_frame = 1;
|
||||
fs->numb_slots_period = nr_slots_per_frame[mu];
|
||||
}
|
||||
AssertFatal(fs->numb_period_frame > 0, "Frame configuration cannot be configured!\n");
|
||||
return fs->numb_period_frame;
|
||||
}
|
||||
|
||||
static void config_common(gNB_MAC_INST *nrmac,
|
||||
const nr_mac_config_t *config,
|
||||
NR_ServingCellConfigCommon_t *scc)
|
||||
|
||||
@@ -39,6 +39,12 @@ void set_cset_offset(uint16_t);
|
||||
void get_K1_K2(int N1, int N2, int *K1, int *K2, int layers);
|
||||
int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
|
||||
|
||||
int get_ul_slots_per_period(const frame_structure_t *fs);
|
||||
int get_ul_slots_per_frame(const frame_structure_t *fs);
|
||||
int get_dl_slots_per_period(const frame_structure_t *fs);
|
||||
int get_full_ul_slots_per_period(const frame_structure_t *fs);
|
||||
int get_full_dl_slots_per_period(const frame_structure_t *fs);
|
||||
|
||||
void mac_top_init_gNB(ngran_node_t node_type,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
NR_ServingCellConfig_t *scd,
|
||||
|
||||
@@ -919,6 +919,59 @@ void nr_rrc_config_dl_tda(struct NR_PDSCH_TimeDomainResourceAllocationList *pdsc
|
||||
}
|
||||
}
|
||||
|
||||
const float tdd_ms_period_pattern[] = {0.5, 0.625, 1.0, 1.25, 2.0, 2.5, 5.0, 10.0};
|
||||
const float tdd_ms_period_ext[] = {3.0, 4.0};
|
||||
|
||||
/**
|
||||
* @brief Retrieves the periodicity in milliseconds for the given TDD pattern
|
||||
* depending on the presence of the extension
|
||||
* @param pattern Pointer to the NR_TDD_UL_DL_Pattern_t pattern structure
|
||||
* @return Periodicity value in milliseconds.
|
||||
*/
|
||||
static float get_tdd_periodicity(NR_TDD_UL_DL_Pattern_t *pattern) {
|
||||
if (!pattern->ext1) {
|
||||
LOG_D(NR_MAC, "Setting TDD configuration period to dl_UL_TransmissionPeriodicity %ld\n", pattern->dl_UL_TransmissionPeriodicity);
|
||||
return tdd_ms_period_pattern[pattern->dl_UL_TransmissionPeriodicity];
|
||||
} else {
|
||||
DevAssert(pattern->ext1->dl_UL_TransmissionPeriodicity_v1530 != NULL);
|
||||
LOG_D(NR_MAC,
|
||||
"Setting TDD configuration period to dl_UL_TransmissionPeriodicity_v1530 %ld\n",
|
||||
*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530);
|
||||
return tdd_ms_period_ext[*pattern->ext1->dl_UL_TransmissionPeriodicity_v1530];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines the TDD period index based on pattern periodicities
|
||||
* @note Not applicabile to pattern extension
|
||||
* @param tdd Pointer to the NR_TDD_UL_DL_ConfigCommon_t containing patterns
|
||||
* @return Index of the TDD period in tdd_ms_period_pattern
|
||||
*/
|
||||
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd)
|
||||
{
|
||||
int tdd_period_idx = 0;
|
||||
float pattern1_ms = get_tdd_periodicity(&tdd->pattern1);
|
||||
float pattern2_ms = tdd->pattern2 ? get_tdd_periodicity(tdd->pattern2) : 0.0;
|
||||
bool found_match = false;
|
||||
// Find matching TDD period in the predefined list of periodicities
|
||||
for (int i = 0; i < NFAPI_MAX_NUM_PERIODS; i++) {
|
||||
if ((pattern1_ms + pattern2_ms) == tdd_ms_period_pattern[i]) {
|
||||
tdd_period_idx = i;
|
||||
LOG_I(NR_MAC,
|
||||
"TDD period index = %d, based on the sum of dl_UL_TransmissionPeriodicity "
|
||||
"from Pattern1 (%f ms) and Pattern2 (%f ms): Total = %f ms\n",
|
||||
tdd_period_idx,
|
||||
pattern1_ms,
|
||||
pattern2_ms,
|
||||
pattern1_ms + pattern2_ms);
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Assert if no match was found
|
||||
AssertFatal(found_match, "The sum of pattern1_ms and pattern2_ms does not match any value in tdd_ms_period_pattern");
|
||||
return tdd_period_idx;
|
||||
}
|
||||
|
||||
static struct NR_PUSCH_TimeDomainResourceAllocation *set_TimeDomainResourceAllocation(const int k2, uint8_t index, int ul_symb)
|
||||
{
|
||||
|
||||
@@ -112,5 +112,6 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
int uid);
|
||||
|
||||
NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc);
|
||||
int get_tdd_period_idx(NR_TDD_UL_DL_ConfigCommon_t *tdd);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user