mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-14 05:00:31 +00:00
Compare commits
8 Commits
multi_cc_s
...
config_api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72834a2f64 | ||
|
|
16496673ff | ||
|
|
5de05d3bca | ||
|
|
1fd9d6224e | ||
|
|
46f3e36525 | ||
|
|
c79af1fbe1 | ||
|
|
308287e646 | ||
|
|
0cc6547bd0 |
@@ -68,7 +68,7 @@ gNBs =
|
||||
initialULBWPsubcarrierSpacing = 3;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 52;
|
||||
prach_ConfigurationIndex = 70;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
@@ -110,7 +110,7 @@ gNBs =
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
ssb_PositionsInBurst_Bitmap = 85;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
@@ -178,7 +178,7 @@ MACRLCs = ({
|
||||
set_analog_beamforming = "lophy";
|
||||
beam_duration = 1;
|
||||
beams_per_period = 1;
|
||||
beam_weights = [0]; // single SSB -> one analog beam
|
||||
beam_weights = [0, 1, 2, 3]; // 4 SSBs -> 4 analog beams
|
||||
});
|
||||
|
||||
L1s = (
|
||||
|
||||
@@ -97,6 +97,7 @@ services:
|
||||
- ALL
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: --rfsim --log_config.global_log_options level,nocolor,time
|
||||
--rfsimulator.[0].enable_beams --rfsimulator.[0].beam_gains 0,-20,-30,-40
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
networks:
|
||||
public_net:
|
||||
@@ -123,6 +124,7 @@ services:
|
||||
USE_ADDITIONAL_OPTIONS: --rfsim
|
||||
--rfsimulator.[0].serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
|
||||
-C 27975360000 -r 66 --numerology 3 --ssb 48 --band 257
|
||||
--rfsimulator.[0].enable_beams --rfsimulator.[0].beam_gains 0,-20,-30,-40 --rfsimulator.[0].beam_ids 2
|
||||
ASAN_OPTIONS: detect_leaks=0
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
|
||||
@@ -116,9 +116,7 @@ static void tx_func(processingData_L1tx_t *info)
|
||||
pushNotifiedFIFO(&gNB->resp_L1, res);
|
||||
|
||||
int tx_slot_type = nr_slot_select(cfg, frame_tx, slot_tx);
|
||||
// TODO check for analog_bf_vendor_ext set to 1 is a workaround while no beam API for beam selection is implemented
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx
|
||||
|| IS_SOFTMODEM_RFSIM || cfg->analog_beamforming_ve.analog_bf_vendor_ext.value) {
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM) {
|
||||
start_meas(&info->gNB->phy_proc_tx);
|
||||
phy_procedures_gNB_TX(info->gNB,
|
||||
&sched_response.DL_req,
|
||||
@@ -127,13 +125,14 @@ static void tx_func(processingData_L1tx_t *info)
|
||||
frame_tx,
|
||||
slot_tx,
|
||||
1);
|
||||
|
||||
PHY_VARS_gNB *gNB = info->gNB;
|
||||
processingData_RU_t syncMsgRU;
|
||||
syncMsgRU.frame_tx = frame_tx;
|
||||
syncMsgRU.slot_tx = slot_tx;
|
||||
syncMsgRU.ru = gNB->RU_list[0];
|
||||
syncMsgRU.timestamp_tx = info->timestamp_tx;
|
||||
}
|
||||
processingData_RU_t syncMsgRU;
|
||||
syncMsgRU.frame_tx = frame_tx;
|
||||
syncMsgRU.slot_tx = slot_tx;
|
||||
syncMsgRU.ru = gNB->RU_list[0];
|
||||
syncMsgRU.timestamp_tx = info->timestamp_tx;
|
||||
ru_ctrl_func((void *)&syncMsgRU);
|
||||
if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT || get_softmodem_params()->continuous_tx || IS_SOFTMODEM_RFSIM) {
|
||||
LOG_D(PHY, "gNB: %d.%d : calling RU TX function\n", syncMsgRU.frame_tx, syncMsgRU.slot_tx);
|
||||
ru_tx_func((void *)&syncMsgRU);
|
||||
stop_meas(&info->gNB->phy_proc_tx);
|
||||
|
||||
@@ -364,17 +364,27 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
AssertFatal(*slot < fp->slots_per_frame && *slot >= 0, "slot %d is illegal (%d)\n", *slot, fp->slots_per_frame);
|
||||
|
||||
start_meas(&ru->rx_fhaul);
|
||||
int nb = ru->nb_rx * ru->num_beams_period;
|
||||
void *rxp[nb];
|
||||
for (int i = 0; i < nb; i++)
|
||||
rxp[i] = (void *)&ru->common.rxdata[i][get_samples_slot_timestamp(fp, *slot)];
|
||||
|
||||
openair0_timestamp_t old_ts = proc->timestamp_rx;
|
||||
LOG_D(PHY,"Reading %d samples for slot %d (%p)\n", samples_per_slot, *slot, rxp[0]);
|
||||
|
||||
openair0_timestamp_t ts;
|
||||
unsigned int rxs;
|
||||
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, samples_per_slot, nb);
|
||||
metadata mt = {.slot = *slot, .frame = *frame};
|
||||
if (ru->num_beams_period > 1) {
|
||||
void *rxp[ru->num_beams_period][ru->nb_rx];
|
||||
for (int j = 0; j < ru->num_beams_period; j++) {
|
||||
for (int i = 0; i < ru->nb_rx; i++) {
|
||||
rxp[j][i] = (void *)&ru->common.rxdata[i + j * ru->nb_rx][get_samples_slot_timestamp(fp, *slot)];
|
||||
}
|
||||
}
|
||||
rxs = ru->rfdevice.trx_read_beams_func(&ru->rfdevice, &ts, (void ***)rxp, samples_per_slot, ru->nb_rx, ru->num_beams_period);
|
||||
gNBscopeCopyWithMetadata(ru, gNbTimeDomainSamples, rxp[0][0], sizeof(c16_t), 1, samples_per_slot, 0, &mt);
|
||||
} else {
|
||||
void *rxp[ru->nb_rx];
|
||||
for (int i = 0; i < ru->nb_rx; i++)
|
||||
rxp[i] = (void *)&ru->common.rxdata[i][get_samples_slot_timestamp(fp, *slot)];
|
||||
rxs = ru->rfdevice.trx_read_func(&ru->rfdevice, &ts, rxp, samples_per_slot, ru->nb_rx);
|
||||
gNBscopeCopyWithMetadata(ru, gNbTimeDomainSamples, rxp[0], sizeof(c16_t), 1, samples_per_slot, 0, &mt);
|
||||
}
|
||||
|
||||
proc->timestamp_rx = ts-ru->ts_offset;
|
||||
|
||||
if (rxs != samples_per_slot)
|
||||
@@ -460,9 +470,6 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
}
|
||||
}
|
||||
|
||||
metadata mt = {.slot = *slot, .frame = *frame};
|
||||
gNBscopeCopyWithMetadata(ru, gNbTimeDomainSamples, rxp[0], sizeof(c16_t), 1, samples_per_slot, 0, &mt);
|
||||
|
||||
if (rxs != samples_per_slot) {
|
||||
//exit_fun( "problem receiving samples" );
|
||||
LOG_E(PHY, "problem receiving samples\n");
|
||||
@@ -471,52 +478,45 @@ static void rx_rf(RU_t *ru, int *frame, int *slot)
|
||||
stop_meas(&ru->rx_fhaul);
|
||||
}
|
||||
|
||||
static radio_tx_gpio_flag_t get_gpio_flags(RU_t *ru, int slot)
|
||||
static void ctrl_rf(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
{
|
||||
radio_tx_gpio_flag_t flags_gpio = 0;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
openair0_config_t *cfg0 = &ru->openair0_cfg;
|
||||
|
||||
switch (cfg0->gpio_controller) {
|
||||
case RU_GPIO_CONTROL_GENERIC:
|
||||
// currently we switch beams at the beginning of a slot and we take the beam index of the first symbol of this slot
|
||||
// we only send the beam to the gpio if the beam is different from the previous slot
|
||||
|
||||
if (ru->common.beam_id) {
|
||||
int prev_slot = (slot - 1 + fp->slots_per_frame) % fp->slots_per_frame;
|
||||
const int *beam_ids = ru->common.beam_id[0];
|
||||
int prev_beam = beam_ids[prev_slot * fp->symbols_per_slot];
|
||||
int beam = beam_ids[slot * fp->symbols_per_slot];
|
||||
if (prev_beam != beam) {
|
||||
flags_gpio = beam | TX_GPIO_CHANGE; // enable change of gpio
|
||||
LOG_I(HW, "slot %d, beam %d\n", slot, ru->common.beam_id[0][slot * fp->symbols_per_slot]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case RU_GPIO_CONTROL_INTERDIGITAL: {
|
||||
// the beam index is written in bits 8-10 of the flags
|
||||
// bit 11 enables the gpio programming
|
||||
int beam = 0;
|
||||
if ((slot % 10 == 0) && ru->common.beam_id && (ru->common.beam_id[0][slot * fp->symbols_per_slot] < 64)) {
|
||||
// beam = ru->common.beam_id[0][slot*fp->symbols_per_slot] | 64;
|
||||
beam = 1024; // hardcoded now for beam32 boresight
|
||||
// beam = 127; //for the sake of trying beam63
|
||||
LOG_D(HW, "slot %d, beam %d\n", slot, beam);
|
||||
}
|
||||
flags_gpio = beam | TX_GPIO_CHANGE;
|
||||
// flags_gpio |= beam << 8; // MSB 8 bits are used for beam
|
||||
LOG_I(HW, "slot %d, beam %d, flags_gpio %d\n", slot, beam, flags_gpio);
|
||||
break;
|
||||
int num_beams = 0;
|
||||
int beams[64] = {0};
|
||||
for (int i = 0; i < ru->num_beams_period; i++) {
|
||||
int beam = -1;
|
||||
for (int j = 0; j < fp->symbols_per_slot; j++) {
|
||||
if (ru->common.beam_id[i][slot * fp->symbols_per_slot + j] == -1)
|
||||
continue;
|
||||
AssertFatal(beam == -1 || beam == ru->common.beam_id[i][slot * fp->symbols_per_slot + j],
|
||||
"Cannot handle more than 1 beam per slot");
|
||||
beam = ru->common.beam_id[i][slot * fp->symbols_per_slot + j];
|
||||
}
|
||||
if (beam != -1) {
|
||||
beams[num_beams] = beam;
|
||||
num_beams++;
|
||||
}
|
||||
default:
|
||||
AssertFatal(false, "illegal GPIO controller %d\n", cfg0->gpio_controller);
|
||||
}
|
||||
|
||||
return flags_gpio;
|
||||
uint64_t ts = timestamp + ru->ts_offset;
|
||||
nfapi_nr_config_request_scf_t *cfg = &ru->config;
|
||||
int slot_type = nr_slot_select(cfg, frame, slot % fp->slots_per_frame);
|
||||
int prevslot_type = nr_slot_select(cfg, frame, (slot + (fp->slots_per_frame- 1)) % fp->slots_per_frame);
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD
|
||||
&& slot_type == NR_DOWNLINK_SLOT
|
||||
&& prevslot_type == NR_UPLINK_SLOT
|
||||
&& !get_softmodem_params()->continuous_tx
|
||||
&& !IS_SOFTMODEM_RFSIM)
|
||||
ts -= ru->sf_extension;
|
||||
|
||||
if (num_beams != 0) {
|
||||
for (int i = 0; i < num_beams; i++)
|
||||
LOG_D(NR_PHY, "Frame %d Slot %d Beam %d\n", frame, slot, beams[i]);
|
||||
ru->rfdevice.trx_set_beams2(&ru->rfdevice, beams, num_beams, ts);
|
||||
}
|
||||
}
|
||||
|
||||
void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
static void tx_rf(RU_t *ru, int frame, int slot, uint64_t timestamp)
|
||||
{
|
||||
RU_proc_t *proc = &ru->proc;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
@@ -531,7 +531,6 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
int sf_extension = 0;
|
||||
int siglen = get_samples_per_slot(slot, fp);
|
||||
radio_tx_burst_flag_t flags_burst = TX_BURST_INVALID;
|
||||
radio_tx_gpio_flag_t flags_gpio = 0;
|
||||
|
||||
if (cfg->cell_config.frame_duplex_type.value == TDD && !get_softmodem_params()->continuous_tx && !IS_SOFTMODEM_RFSIM) {
|
||||
int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame);
|
||||
@@ -575,24 +574,40 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
flags_burst = proc->first_tx == 1 ? TX_BURST_START : TX_BURST_MIDDLE;
|
||||
}
|
||||
|
||||
if (ru->openair0_cfg.gpio_controller != RU_GPIO_CONTROL_NONE)
|
||||
flags_gpio = get_gpio_flags(ru, slot);
|
||||
|
||||
const int flags = flags_burst | (flags_gpio << 4);
|
||||
proc->first_tx = 0;
|
||||
|
||||
int nt = ru->nb_tx * ru->num_beams_period;
|
||||
void *txp[nt];
|
||||
for (int i = 0; i < nt; i++)
|
||||
txp[i] = (void *)&ru->common.txdata[i][get_samples_slot_timestamp(fp, slot)] - sf_extension * sizeof(int32_t);
|
||||
double sig_en = 0;
|
||||
uint32_t txs;
|
||||
if (ru->num_beams_period > 1) {
|
||||
void *txp[ru->num_beams_period][ru->nb_tx];
|
||||
for (int b = 0; b < ru->num_beams_period; b++) {
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
txp[b][i] = (void *)&ru->common.txdata[i + b * ru->nb_tx][get_samples_slot_timestamp(fp, slot)] - sf_extension * sizeof(int32_t);
|
||||
}
|
||||
sig_en = (double)signal_energy(txp[0][0], siglen + sf_extension);
|
||||
txs = ru->rfdevice.trx_write_beams_func(&ru->rfdevice,
|
||||
timestamp + ru->ts_offset - sf_extension,
|
||||
(void ***)txp,
|
||||
siglen + sf_extension,
|
||||
ru->nb_tx,
|
||||
ru->num_beams_period,
|
||||
flags_burst);
|
||||
|
||||
} else {
|
||||
void *txp[ru->nb_tx];
|
||||
for (int i = 0; i < ru->nb_tx; i++)
|
||||
txp[i] = (void *)&ru->common.txdata[i][get_samples_slot_timestamp(fp, slot)] - sf_extension * sizeof(int32_t);
|
||||
|
||||
sig_en = (double)signal_energy(txp[0], siglen + sf_extension);
|
||||
// prepare tx buffer pointers
|
||||
txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
timestamp + ru->ts_offset - sf_extension,
|
||||
txp,
|
||||
siglen + sf_extension,
|
||||
ru->nb_tx,
|
||||
flags_burst);
|
||||
}
|
||||
|
||||
// prepare tx buffer pointers
|
||||
uint32_t txs = ru->rfdevice.trx_write_func(&ru->rfdevice,
|
||||
timestamp + ru->ts_offset - sf_extension,
|
||||
txp,
|
||||
siglen + sf_extension,
|
||||
nt,
|
||||
flags);
|
||||
LOG_D(PHY,
|
||||
"[TXPATH] RU %d tx_rf, writing to TS %lu, %d.%d, unwrapped_frame %d, slot %d, flags %d, siglen+sf_extension %d, "
|
||||
"returned %d, E %f\n",
|
||||
@@ -602,10 +617,10 @@ void tx_rf(RU_t *ru, int frame,int slot, uint64_t timestamp)
|
||||
slot,
|
||||
proc->frame_tx_unwrap,
|
||||
slot,
|
||||
flags,
|
||||
flags_burst,
|
||||
siglen + sf_extension,
|
||||
txs,
|
||||
10 * log10((double)signal_energy(txp[0], siglen + sf_extension)));
|
||||
10 * log10(sig_en));
|
||||
}
|
||||
|
||||
static void fill_rf_config(RU_t *ru, char *rf_config_file)
|
||||
@@ -759,6 +774,25 @@ int setup_RU_buffers(RU_t *ru)
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ru_ctrl_func(void *param)
|
||||
{
|
||||
processingData_RU_t *info = (processingData_RU_t *) param;
|
||||
int frame = info->frame_tx;
|
||||
int slot = info->slot_tx;
|
||||
LOG_D(PHY,"ru_ctrl_func: frame = %d, slot = %d\n", frame, slot);
|
||||
RU_t *ru = info->ru;
|
||||
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
|
||||
if (ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
for (int i = 0; i < ru->num_beams_period; i++) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot * fp->symbols_per_slot],
|
||||
(void*) &ru->gNB_list[0]->common_vars.beam_id[i][slot * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
}
|
||||
if (ru->fh_south_ctrl)
|
||||
ru->fh_south_ctrl(ru, frame, slot, info->timestamp_tx);
|
||||
}
|
||||
|
||||
void ru_tx_func(void *param)
|
||||
{
|
||||
processingData_RU_t *info = (processingData_RU_t *) param;
|
||||
@@ -1146,6 +1180,7 @@ void set_function_spec_param(RU_t *ru)
|
||||
ru->rfdevice.host_type = RAU_HOST;
|
||||
ru->fh_south_in = rx_rf; // local synchronous RF RX
|
||||
ru->fh_south_out = tx_rf; // local synchronous RF TX
|
||||
ru->fh_south_ctrl = ctrl_rf; // local sunchronous RF control
|
||||
ru->start_rf = start_rf; // need to start the local RF interface
|
||||
ru->stop_rf = stop_rf;
|
||||
ru->start_write_thread = start_write_thread; // starting RF TX in different thread
|
||||
|
||||
@@ -334,7 +334,7 @@ extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
||||
extern int usrp_tx_thread;
|
||||
extern int sf_ahead;
|
||||
extern int oai_exit;
|
||||
|
||||
void ru_ctrl_func(void *param);
|
||||
void ru_tx_func(void *param);
|
||||
void configure_ru(void *, void *arg);
|
||||
void configure_rru(void *, void *arg);
|
||||
|
||||
@@ -971,7 +971,7 @@ void nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue,
|
||||
|
||||
switch (csirs_config_pdu->measurement_bitmap) {
|
||||
case 1 :
|
||||
LOG_I(NR_PHY, "[UE %d] RSRP = %i dBm\n", ue->Mod_id, rsrp_dBm);
|
||||
LOG_I(NR_PHY, "[UE %d] CSI-RS RSRP = %i dBm\n", ue->Mod_id, rsrp_dBm);
|
||||
break;
|
||||
case 26 :
|
||||
LOG_I(NR_PHY, "RI = %i i1 = %i.%i.%i, i2 = %i, SINR = %i dB, CQI = %i\n",
|
||||
|
||||
@@ -521,6 +521,8 @@ typedef struct RU_t_s {
|
||||
void (*fh_south_in)(struct RU_t_s *ru, int *frame, int *subframe);
|
||||
/// function pointer to synchronous TX fronthaul function
|
||||
void (*fh_south_out)(struct RU_t_s *ru, int frame_tx, int tti_tx, uint64_t timestamp_tx);
|
||||
/// function pointer to synchronous control fronthaul function
|
||||
void (*fh_south_ctrl)(struct RU_t_s *ru, int frame, int slot, uint64_t timestamp);
|
||||
/// function pointer to synchronous RX fronthaul function (RRU)
|
||||
void (*fh_north_in)(struct RU_t_s *ru, int *frame, int *subframe);
|
||||
/// function pointer to synchronous RX fronthaul function (RRU)
|
||||
|
||||
@@ -178,14 +178,6 @@ void nr_feptx_prec(RU_t *ru, int frame_tx, int slot_tx)
|
||||
int txdataF_offset = slot_tx * fp->samples_per_slot_wCP;
|
||||
start_meas(&ru->precoding_stats);
|
||||
|
||||
if (gNB->common_vars.analog_bf) {
|
||||
for (int i = 0; i < ru->num_beams_period; i++) {
|
||||
memcpy((void*) &ru->common.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(void*) &gNB->common_vars.beam_id[i][slot_tx * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
if (nr_slot_select(cfg,frame_tx,slot_tx) == NR_UPLINK_SLOT)
|
||||
return;
|
||||
|
||||
@@ -227,12 +219,6 @@ void nr_feptx(void *arg)
|
||||
if (tx_idx == 0)
|
||||
start_meas(&ru->precoding_stats);
|
||||
|
||||
if (ru->gNB_list[0]->common_vars.analog_bf) {
|
||||
memcpy(&ru->common.beam_id[bb][slot * fp->symbols_per_slot],
|
||||
&ru->gNB_list[0]->common_vars.beam_id[bb][slot * fp->symbols_per_slot],
|
||||
(fp->symbols_per_slot) * sizeof(int));
|
||||
}
|
||||
|
||||
// If there is no digital beamforming we just need to copy the data to RU
|
||||
if (ru->config.dbt_config.num_dig_beams == 0 || ru->gNB_list[0]->common_vars.analog_bf)
|
||||
memcpy((void*)&ru->common.txdataF_BF[tx_idx][txdataF_BF_offset],
|
||||
|
||||
@@ -819,7 +819,8 @@ int main(int argc, char **argv)
|
||||
rnti_t rnti = 0x1234;
|
||||
int uid = 0;
|
||||
int ssb_index = 0;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index);
|
||||
int beam_idx = 0;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index, beam_idx);
|
||||
secondaryCellGroup->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(rnti, uid, scc, frame);
|
||||
|
||||
/* -U option modify DMRS */
|
||||
|
||||
@@ -843,7 +843,8 @@ int main(int argc, char *argv[])
|
||||
rnti_t rnti = 0x1234;
|
||||
int uid = 0;
|
||||
int ssb_index = 0;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index);
|
||||
int beam_idx = 0;
|
||||
NR_CellGroupConfig_t *secondaryCellGroup = get_default_secondaryCellGroup(scc, UE_Capability_nr, 0, 1, &conf, uid, ssb_index, beam_idx);
|
||||
secondaryCellGroup->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(rnti, uid, scc, frame);
|
||||
|
||||
NR_BCCH_BCH_Message_t *mib = get_new_MIB_NR(scc);
|
||||
|
||||
@@ -1653,9 +1653,9 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg)
|
||||
// each beam is described by a set of weights (one for each antenna)
|
||||
// in case of analog beamforming an index to the RU beam identifier is provided
|
||||
// (one for each beam regardless of the number of antennas per beam)
|
||||
config.nb_bfw[0] = num_tx; // number of tx antennas
|
||||
config.nb_bfw[1] = num_beam; // number of beams weights/indices
|
||||
config.bw_list = calloc_or_fail(n, sizeof(*config.bw_list));
|
||||
RC.nrmac[j]->radio_config.nb_bfw[0] = config.nb_bfw[0] = num_tx; // number of tx antennas
|
||||
RC.nrmac[j]->radio_config.nb_bfw[1] = config.nb_bfw[1] = num_beam; // number of beams weights/indices
|
||||
RC.nrmac[j]->radio_config.bw_list = config.bw_list = calloc_or_fail(n, sizeof(*config.bw_list));
|
||||
for (int b = 0; b < n; b++)
|
||||
config.bw_list[b] = MacRLC_ParamList.paramarray[j][MACRLC_BEAMWEIGHTS_IDX].iptr[b];
|
||||
}
|
||||
|
||||
@@ -59,6 +59,96 @@
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "utils.h"
|
||||
|
||||
bool is_prach_slot_set = false;
|
||||
bool is_prach_slot[160] = {false};
|
||||
|
||||
int get_beamloc_from_beam(int beam_index)
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[0];
|
||||
if (mac->beam_info.beam_mode == LOPHY_BEAM_IDX) {
|
||||
for (int i = 0; i < mac->radio_config.nb_bfw[1]; i++) {
|
||||
if (mac->radio_config.bw_list[i] == beam_index)
|
||||
return i;
|
||||
}
|
||||
AssertFatal(false, "beam_index %d not found\n", beam_index);
|
||||
return 0;
|
||||
}
|
||||
return beam_index;
|
||||
}
|
||||
|
||||
bool get_nr_prach_sched_from_info_beam(nr_prach_info_t info,
|
||||
int config_index,
|
||||
int slot,
|
||||
int mu,
|
||||
frequency_range_t freq_range,
|
||||
uint8_t unpaired)
|
||||
{
|
||||
if (freq_range == FR2) {
|
||||
//Not checking n_sfn mod x = y
|
||||
int slot_60khz = slot >> (mu - 2); // in table slots are numbered wrt 60kHz
|
||||
if (((info.s_map >> slot_60khz) & 0x01)) {
|
||||
if (mu == 3) {
|
||||
if ((info.N_RA_slot == 1) && (slot % 2 == 0))
|
||||
return false; // no prach in even slots @ 120kHz for 1 prach per 60khz slot
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return false; // no prach in current slot
|
||||
} else {
|
||||
if (unpaired) { // TDD
|
||||
//Not checking n_sfn mod x = y
|
||||
int subframe = slot >> mu;
|
||||
if ((info.s_map >> subframe) & 0x01) {
|
||||
if (config_index >= 67) {
|
||||
if ((mu == 1) && (info.N_RA_slot <= 1) && (slot % 2 == 0))
|
||||
return false; // no prach in even slots @ 30kHz for 1 prach per subframe
|
||||
} else {
|
||||
if ((slot % 2) && (mu > 0))
|
||||
return false; // slot does not contain start symbol of this prach time resource
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return false; // no prach in current slot
|
||||
} else { // FDD
|
||||
//Not checking n_sfn mod x = y
|
||||
int subframe = slot >> mu;
|
||||
if ((info.s_map >> subframe) & 0x01) {
|
||||
if (config_index >= 87) {
|
||||
if ((mu == 1) && (info.N_RA_slot <= 1) && (slot % 2 == 0)) {
|
||||
return false; // no prach in even slots @ 30kHz for 1 prach per subframe
|
||||
}
|
||||
} else {
|
||||
if ((slot % 2) && (mu > 0))
|
||||
return 0; // slot does not contain start symbol of this prach time resource
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return false; // no prach in current slot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_prach_slot()
|
||||
{
|
||||
gNB_MAC_INST *gNB = RC.nrmac[0];
|
||||
NR_COMMON_channels_t *cc = gNB->common_channels;
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
NR_BWP_UplinkCommon_t *initialUplinkBWP = scc->uplinkConfigCommon->initialUplinkBWP;
|
||||
NR_RACH_ConfigCommon_t *rach_ConfigCommon = initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
||||
NR_MsgA_ConfigCommon_r16_t *msgacc = NULL;
|
||||
if (initialUplinkBWP->ext1 && initialUplinkBWP->ext1->msgA_ConfigCommon_r16)
|
||||
msgacc = initialUplinkBWP->ext1->msgA_ConfigCommon_r16->choice.setup;
|
||||
const NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &rach_ConfigCommon->rach_ConfigGeneric;
|
||||
uint8_t config_index = rach_ConfigGeneric->prach_ConfigurationIndex;
|
||||
const int ul_mu = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
const int mu = nr_get_prach_or_ul_mu(msgacc, rach_ConfigCommon, ul_mu);
|
||||
frequency_range_t freq_range = get_freq_range_from_arfcn(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
|
||||
frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||
for (int j = 0; j < fs->numb_slots_frame; j++) {
|
||||
is_prach_slot[j] = get_nr_prach_sched_from_info_beam(cc->prach_info, config_index, j, mu, freq_range, cc->frame_type);
|
||||
}
|
||||
}
|
||||
|
||||
c16_t convert_precoder_weight(double complex c_in)
|
||||
{
|
||||
return (c16_t) {.r = round(SHRT_MAX*creal(c_in)), .i = round(SHRT_MAX*cimag(c_in))};
|
||||
@@ -289,6 +379,58 @@ int get_first_ul_slot(const frame_structure_t *fs, bool mixed)
|
||||
return 0; // FDD
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the first UL slot index in period
|
||||
* @param fs frame structure
|
||||
* @param beam_idx beam index
|
||||
* @param beams_per_period no of concurrent beams
|
||||
* @param num_beam no of beams
|
||||
* @return slot index
|
||||
*
|
||||
*/
|
||||
int get_first_ul_slot_beam(const frame_structure_t *fs, int beam_idx, int beams_per_period, int num_beam)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
// FDD
|
||||
if (fs->frame_type == FDD)
|
||||
return 1;
|
||||
|
||||
if (!is_prach_slot_set)
|
||||
set_prach_slot();
|
||||
|
||||
// UL slots indexes in period
|
||||
int ul_slot_idxs[fs->numb_slots_frame];
|
||||
int ul_slot_count = 0;
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_frame; i++) {
|
||||
ul_slot_idxs[i] = 0;
|
||||
}
|
||||
int idx = get_beamloc_from_beam(beam_idx) / beams_per_period;
|
||||
LOG_D(NR_MAC, "get_first_ul_slot_beam 0 idx %d beam_idx %d num_beam %d\n", idx, beam_idx, num_beam);
|
||||
|
||||
/* Populate the indices of UL slots in the TDD period from the bitmap
|
||||
* mixed slot is not used in multiple beams config file to avoid collision with SSB
|
||||
*/
|
||||
for (int j = 0; j < fs->numb_slots_frame; j++) {
|
||||
int i = j % fs->numb_slots_period;
|
||||
if ((fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) && !is_prach_slot[j]) {
|
||||
ul_slot_idxs[ul_slot_count++] = j;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_frame; i++)
|
||||
LOG_D(NR_MAC, "ul_slot_idxs[%d] %d\n", i, ul_slot_idxs[i]);
|
||||
|
||||
// Compute slot index offset
|
||||
int period_idx = idx / ul_slot_count; // wrap up the count of complete TDD periods spanned by the index
|
||||
int ul_slot_idx_in_period = idx % ul_slot_count; // wrap up the UL slot index within the current TDD period
|
||||
int ret = ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_frame;
|
||||
LOG_D(NR_MAC, "get_first_ul_slot_beam ret %d idx %d beam_idx %d ul_slot_count %d %d %d\n",
|
||||
ret, idx, beam_idx, ul_slot_idx_in_period, period_idx, fs->numb_slots_period);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get number of DL slots per period (full DL slots + mixed slots with DL symbols)
|
||||
*/
|
||||
@@ -391,6 +533,100 @@ int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed)
|
||||
return ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_period;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the nth UL slot offset for UE index idx in a TDD period using the frame structure bitmap
|
||||
* @param fs frame structure
|
||||
* @param idx UE index
|
||||
* @param is_csi indicates whether it is csi or not
|
||||
* @param beam_idx beam index
|
||||
* @param beams_per_period no of concurrent beams
|
||||
* @param num_beam no of beams
|
||||
* @return slot index offset
|
||||
*/
|
||||
int get_ul_slot_offset_beam(const frame_structure_t *fs, int idx, bool is_csi, int beam_idx, int beams_per_period, int num_beam)
|
||||
{
|
||||
DevAssert(fs);
|
||||
|
||||
// FDD
|
||||
if (fs->frame_type == FDD)
|
||||
return idx;
|
||||
|
||||
if (!is_prach_slot_set)
|
||||
set_prach_slot();
|
||||
|
||||
// UL slots indexes in period
|
||||
int ul_slot_idxs[fs->numb_slots_frame];
|
||||
int ul_slot_count = 0;
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_frame; i++) {
|
||||
ul_slot_idxs[i] = 0;
|
||||
}
|
||||
|
||||
LOG_D(NR_MAC, "get_ul_slot_offset_beam 0 idx %d is_csi %d beam_idx %d num_beam %d\n", idx, is_csi, beam_idx, num_beam);
|
||||
int id = (is_csi) ? idx/2 : idx;
|
||||
id /= beams_per_period;
|
||||
|
||||
// For NO_BEAM_MODE
|
||||
// Assuming num_pucch2 = 2 and ignoring mixed slotset_csi_meas_periodicity() and configure_periodic_srs() will give this assignment
|
||||
// UL slot
|
||||
// 0123456789
|
||||
// uid0 S
|
||||
// CR
|
||||
// uid1 -S
|
||||
// CR
|
||||
// uid2 --S
|
||||
// CR
|
||||
// uid3 ---S
|
||||
// CR
|
||||
// With beamforming, the slot assignment is
|
||||
// UL slot
|
||||
// 0123456789
|
||||
// uid0 SCR
|
||||
// uid1 ---SCR
|
||||
// uid2 ------SCR
|
||||
|
||||
// SRS
|
||||
if (!is_csi) {
|
||||
idx = 3 * id;
|
||||
}
|
||||
else {
|
||||
// odd => RSRP report
|
||||
if (idx % 2) {
|
||||
idx = 3 * id + 2;
|
||||
}
|
||||
// even => CSI report
|
||||
else {
|
||||
idx = 3 * id + 1;
|
||||
}
|
||||
}
|
||||
LOG_D(NR_MAC, "get_ul_slot_offset_beam 2 id %d idx %d is_csi %d beam_idx %d num_beam %d\n", id, idx, is_csi, beam_idx, num_beam);
|
||||
|
||||
// Allow the first NUM_SSB_period slot for SR. See get_first_ul_slot_beam()
|
||||
int NUM_SSB_period = (num_beam % beams_per_period > 0) ? num_beam / beams_per_period + 1 : num_beam / beams_per_period;
|
||||
idx += NUM_SSB_period;
|
||||
|
||||
/* Populate the indices of UL slots in the TDD period from the bitmap
|
||||
* mixed slot is not used in multiple beams config file to avoid collision with SSB
|
||||
*/
|
||||
for (int j = 0; j < fs->numb_slots_frame; j++) {
|
||||
int i = j % fs->numb_slots_period;
|
||||
if ((fs->period_cfg.tdd_slot_bitmap[i].slot_type == TDD_NR_UPLINK_SLOT) && !is_prach_slot[j]) {
|
||||
ul_slot_idxs[ul_slot_count++] = j;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < fs->numb_slots_frame; i++)
|
||||
LOG_D(NR_MAC, "ul_slot_idxs[%d] %d, is_prach_slot[%d] %d\n", i, ul_slot_idxs[i], i, is_prach_slot[i]);
|
||||
|
||||
// Compute slot index offset
|
||||
int period_idx = idx / ul_slot_count; // wrap up the count of complete TDD periods spanned by the index
|
||||
int ul_slot_idx_in_period = idx % ul_slot_count; // wrap up the UL slot index within the current TDD period
|
||||
int ret = ul_slot_idxs[ul_slot_idx_in_period] + period_idx * fs->numb_slots_frame;
|
||||
LOG_D(NR_MAC, "get_ul_slot_offset_beam ret %d idx %d beam_idx %d beams_period %d ul_slot_count %d %d %d\n", ret, idx, beam_idx, beams_per_period, ul_slot_idx_in_period, period_idx, fs->numb_slots_period);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void config_common(gNB_MAC_INST *nrmac, const nr_mac_config_t *config, NR_ServingCellConfigCommon_t *scc)
|
||||
{
|
||||
nfapi_nr_config_request_scf_t *cfg = &nrmac->config[0];
|
||||
|
||||
@@ -3838,7 +3838,7 @@ bool prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
|
||||
int srb_id = 1;
|
||||
const NR_ServingCellConfigCommon_t *scc = mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
int ssb_index = get_ssbidx_from_beam(mac, UE->UE_beam_index);
|
||||
NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index);
|
||||
NR_CellGroupConfig_t *cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index, UE->UE_beam_index);
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, UE->CellGroup);
|
||||
UE->CellGroup = cellGroupConfig;
|
||||
UE->local_bwp_id = mac->radio_config.first_active_bwp;
|
||||
@@ -3979,7 +3979,8 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE,
|
||||
nrmac->common_channels[0].ServingCellConfigCommon,
|
||||
UE->uid,
|
||||
UE->current_DL_BWP.bwp_id,
|
||||
ssb_index);
|
||||
ssb_index,
|
||||
UE->UE_beam_index);
|
||||
} else {
|
||||
if (new_bwp_id >= 0) {
|
||||
AssertFatal(UE->current_DL_BWP.bwp_id == UE->current_UL_BWP.bwp_id, "We only support same BWP for UL and DL\n");
|
||||
@@ -3996,7 +3997,8 @@ void nr_mac_trigger_reconfiguration(const gNB_MAC_INST *nrmac, NR_UE_info_t *UE,
|
||||
UE->uid,
|
||||
UE->current_DL_BWP.bwp_id,
|
||||
new_bwp_id,
|
||||
ssb_index);
|
||||
ssb_index,
|
||||
UE->UE_beam_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,14 @@ int get_NTN_Koffset(const NR_ServingCellConfigCommon_t *scc);
|
||||
bool is_ssb_configured(const NR_ServingCellConfigCommon_t *scc, int ssb_index);
|
||||
int get_max_ssbs(const NR_ServingCellConfigCommon_t *scc);
|
||||
int get_first_ul_slot(const frame_structure_t *fs, bool mixed);
|
||||
int get_first_ul_slot_beam(const frame_structure_t *fs, int beam_idx, int beams_per_period, int num_beam);
|
||||
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);
|
||||
int get_ul_slot_offset(const frame_structure_t *fs, int idx, bool count_mixed);
|
||||
int get_ul_slot_offset_beam(const frame_structure_t *fs, int idx, bool is_csi, int beam_idx, int beams_per_period, int num_beam);
|
||||
void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia);
|
||||
|
||||
void mac_top_init_gNB(ngran_node_t node_type,
|
||||
|
||||
@@ -569,11 +569,11 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C
|
||||
const nr_mac_config_t *configuration = &mac->radio_config;
|
||||
int ssb_index = get_ssbidx_from_beam(mac, UE->UE_beam_index);
|
||||
if (is_SA) {
|
||||
cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index);
|
||||
cellGroupConfig = get_initial_cellGroupConfig(UE->uid, scc, &mac->radio_config, &mac->rlc_config, ssb_index, UE->UE_beam_index);
|
||||
cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame);
|
||||
} else {
|
||||
NR_UE_NR_Capability_t *cap = get_ue_nr_cap_from_cg_config_info(cgci);
|
||||
cellGroupConfig = get_default_secondaryCellGroup(scc, cap, 1, 1, configuration, UE->uid, ssb_index);
|
||||
cellGroupConfig = get_default_secondaryCellGroup(scc, cap, 1, 1, configuration, UE->uid, ssb_index, UE->UE_beam_index);
|
||||
cellGroupConfig->spCellConfig->reconfigurationWithSync = get_reconfiguration_with_sync(UE->rnti, UE->uid, scc, mac->frame);
|
||||
// TODO: in NSA we assign capabilities here, otherwise outside => not logic
|
||||
UE->capability = cap;
|
||||
@@ -760,7 +760,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req)
|
||||
if (ue_cap != NULL && cg_configinfo == NULL) {
|
||||
// store the new UE capabilities, and update the cellGroupConfig
|
||||
// only to be done if we did not already update through the cg_configinfo
|
||||
update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc);
|
||||
update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc, UE->UE_beam_index);
|
||||
}
|
||||
|
||||
/* During re-establishment, prepare CellGroupConfig for UE Context Setup response.
|
||||
@@ -887,7 +887,7 @@ void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req)
|
||||
ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, UE->capability);
|
||||
UE->capability = ue_cap;
|
||||
LOG_I(NR_MAC, "UE %04x: received capabilities, updating CellGroupConfig\n", UE->rnti);
|
||||
update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc);
|
||||
update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc, UE->UE_beam_index);
|
||||
}
|
||||
|
||||
/* 3GPP TS 38.473 Clause 8.3.4: If gNB-DU Configuration Query is present, include CellGroupConfig
|
||||
|
||||
@@ -380,6 +380,14 @@ static int set_ideal_period(bool is_csi)
|
||||
return is_csi ? MAX_MOBILES_PER_GNB * 2 * nb_slots_per_period / n_ul_slots_per_period : nb_slots_per_period * MAX_MOBILES_PER_GNB;
|
||||
}
|
||||
|
||||
static int set_ideal_period_beam(bool is_csi, int NUM_SSB_period)
|
||||
{
|
||||
const frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||
const int nb_slots_per_period = fs->numb_slots_period;
|
||||
// 2 reports per UE (RSRP and RI-PMI-CQI)
|
||||
return 3 * nb_slots_per_period * MAX_MOBILES_PER_GNB + NUM_SSB_period;
|
||||
}
|
||||
|
||||
static void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0,
|
||||
int id,
|
||||
int ideal_period,
|
||||
@@ -520,7 +528,16 @@ static void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigco
|
||||
*nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
|
||||
nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
|
||||
|
||||
const int ideal_period = set_ideal_period(true); // same periodicity as CSI measurement report
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[0]->beam_info;
|
||||
int ideal_period;
|
||||
if (beam_info->beam_mode != NO_BEAM_MODE) {
|
||||
int num_beam = (RC.nrmac[0]->radio_config.nb_bfw[1] > 0) ? RC.nrmac[0]->radio_config.nb_bfw[1] : 1;
|
||||
int beams_per_period = (beam_info->beams_per_period > 0) ? beam_info->beams_per_period : 1;
|
||||
int NUM_SSB_period = (num_beam % beams_per_period > 0) ? num_beam / beams_per_period + 1 : num_beam / beams_per_period;
|
||||
ideal_period = set_ideal_period_beam(true, NUM_SSB_period); // same periodicity as CSI measurement report
|
||||
} else {
|
||||
ideal_period = set_ideal_period(true); // same periodicity as CSI measurement report
|
||||
}
|
||||
const frame_structure_t *fs = &(RC.nrmac[0]->frame_structure);
|
||||
set_csirs_periodicity(nzpcsi0, id, ideal_period, fs);
|
||||
|
||||
@@ -680,13 +697,28 @@ static void set_dl_maxmimolayers(NR_PDSCH_ServingCellConfig_t *pdsch_servingcell
|
||||
}
|
||||
|
||||
static struct NR_SRS_Resource__resourceType__periodic *configure_periodic_srs(const NR_ServingCellConfigCommon_t *scc,
|
||||
const int uid)
|
||||
const int uid,
|
||||
int beam_idx)
|
||||
{
|
||||
frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||
int offset = get_ul_slot_offset(fs, uid, false); // only full UL slots for SRS
|
||||
int offset;
|
||||
int ideal_period;
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[0]->beam_info;
|
||||
if (beam_info->beam_mode != NO_BEAM_MODE) {
|
||||
int num_beam = (RC.nrmac[0]->radio_config.nb_bfw[1] > 0) ? RC.nrmac[0]->radio_config.nb_bfw[1] : 1;
|
||||
int beams_per_period = (beam_info->beams_per_period > 0) ? beam_info->beams_per_period : 1 ;
|
||||
int NUM_SSB_period = (num_beam % beams_per_period > 0) ? num_beam / beams_per_period + 1 : num_beam / beams_per_period;
|
||||
ideal_period = set_ideal_period_beam(false, NUM_SSB_period);
|
||||
offset = get_ul_slot_offset_beam(fs, uid, false, beam_idx, beams_per_period, num_beam); // only full UL slots for SRS
|
||||
LOG_I(NR_MAC, "configure_periodic_srs 0 idx %d count_mixed %d beam_idx %d num_beam %d ideal_period %d srs_offset %d\n",
|
||||
uid, false, beam_idx, num_beam, ideal_period, offset);
|
||||
} else {
|
||||
offset = get_ul_slot_offset(fs, uid, false); // only full UL slots for SRS
|
||||
ideal_period = set_ideal_period(false);
|
||||
}
|
||||
|
||||
// checked for validity in verify_radio_configuration
|
||||
AssertFatal(offset < 2560, "Cannot allocate SRS configuration for uid %d, not enough resources\n", uid);
|
||||
const int ideal_period = set_ideal_period(false);
|
||||
|
||||
struct NR_SRS_Resource__resourceType__periodic *periodic_srs = calloc(1,sizeof(*periodic_srs));
|
||||
if (check_periodicity(4, ideal_period, fs)) {
|
||||
@@ -795,7 +827,8 @@ static NR_SRS_Resource_t *get_srs_resource(const NR_ServingCellConfigCommon_t *s
|
||||
const int res_id,
|
||||
const long maxMIMO_Layers,
|
||||
const NR_SRS_Resource__transmissionComb_PR tx_comb,
|
||||
int do_srs)
|
||||
int do_srs,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_SRS_Resource_t *srs_res = calloc_or_fail(1, sizeof(*srs_res));
|
||||
srs_res->srs_ResourceId = res_id;
|
||||
@@ -866,7 +899,7 @@ static NR_SRS_Resource_t *get_srs_resource(const NR_ServingCellConfigCommon_t *s
|
||||
srs_res->groupOrSequenceHopping = NR_SRS_Resource__groupOrSequenceHopping_neither;
|
||||
if (do_srs) {
|
||||
srs_res->resourceType.present = NR_SRS_Resource__resourceType_PR_periodic;
|
||||
srs_res->resourceType.choice.periodic = configure_periodic_srs(scc, uid);
|
||||
srs_res->resourceType.choice.periodic = configure_periodic_srs(scc, uid, beam_idx);
|
||||
} else {
|
||||
srs_res->resourceType.present = NR_SRS_Resource__resourceType_PR_aperiodic;
|
||||
srs_res->resourceType.choice.aperiodic = calloc_or_fail(1, sizeof(*srs_res->resourceType.choice.aperiodic));
|
||||
@@ -887,7 +920,8 @@ static NR_SetupRelease_SRS_Config_t *get_config_srs(const NR_ServingCellConfigCo
|
||||
const int res_id,
|
||||
const long maxMIMO_Layers,
|
||||
const int minRXTXTIME,
|
||||
int do_srs)
|
||||
int do_srs,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_SetupRelease_SRS_Config_t *setup_release_srs_Config = calloc_or_fail(1, sizeof(*setup_release_srs_Config));
|
||||
setup_release_srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup;
|
||||
@@ -896,7 +930,7 @@ static NR_SetupRelease_SRS_Config_t *get_config_srs(const NR_ServingCellConfigCo
|
||||
|
||||
srs_Config->srs_ResourceToAddModList = calloc_or_fail(1, sizeof(*srs_Config->srs_ResourceToAddModList));
|
||||
NR_SRS_Resource_t *srs_res0 =
|
||||
get_srs_resource(scc, uecap, curr_bwp, uid, res_id, maxMIMO_Layers, NR_SRS_Resource__transmissionComb_PR_n2, do_srs);
|
||||
get_srs_resource(scc, uecap, curr_bwp, uid, res_id, maxMIMO_Layers, NR_SRS_Resource__transmissionComb_PR_n2, do_srs, beam_idx);
|
||||
asn1cSeqAdd(&srs_Config->srs_ResourceToAddModList->list, srs_res0);
|
||||
|
||||
srs_Config->srs_ResourceSetToAddModList = calloc_or_fail(1, sizeof(*srs_Config->srs_ResourceSetToAddModList));
|
||||
@@ -1387,7 +1421,75 @@ static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedul
|
||||
}
|
||||
}
|
||||
|
||||
static void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, NR_PUCCH_Config_t *pucch_Config, int scs)
|
||||
static void set_SR_periodandoffset_beam(NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig, const NR_ServingCellConfigCommon_t *scc, int scs, int beam_idx)
|
||||
{
|
||||
const frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[0]->beam_info;
|
||||
int num_beam = (RC.nrmac[0]->radio_config.nb_bfw[1] > 0) ? RC.nrmac[0]->radio_config.nb_bfw[1] : 1;
|
||||
int beams_per_period = (beam_info->beams_per_period > 0) ? beam_info->beams_per_period : 1;
|
||||
int NUM_SSB_period = (num_beam % beams_per_period > 0) ? num_beam / beams_per_period + 1 : num_beam / beams_per_period;
|
||||
|
||||
int sr_slot = 1; // in FDD SR in slot 1
|
||||
const int ideal_period = set_ideal_period_beam(false, NUM_SSB_period);
|
||||
sr_slot = get_first_ul_slot_beam(fs, beam_idx, beams_per_period, num_beam);
|
||||
|
||||
schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset));
|
||||
|
||||
LOG_I(NR_MAC, "set_SR_periodandoffset_beam beam_idx %d num_beam %d ideal_period %d sr_slot %d\n",
|
||||
beam_idx, num_beam, ideal_period, sr_slot);
|
||||
|
||||
if (check_periodicity(5, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl5;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl5 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if(check_periodicity(8, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl8;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl8 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if(check_periodicity(10, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if(check_periodicity(16, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl16;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl16 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if(check_periodicity(20, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl20 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if (check_periodicity(40, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if (check_periodicity(80, ideal_period, fs)) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl80 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if ((check_periodicity(160, ideal_period, fs))) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl160 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else if ((check_periodicity(320, ideal_period, fs))) {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl320 = sr_slot;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640;
|
||||
schedulingRequestResourceConfig->periodicityAndOffset->choice.sl640 = sr_slot;
|
||||
}
|
||||
}
|
||||
|
||||
static void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, NR_PUCCH_Config_t *pucch_Config, int scs, int beam_idx)
|
||||
{
|
||||
// format with <=2 bits in pucch resource set 0
|
||||
NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0];
|
||||
@@ -1399,7 +1501,11 @@ static void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, N
|
||||
schedulingRequestResourceConfig->schedulingRequestResourceId = 1;
|
||||
schedulingRequestResourceConfig->schedulingRequestID = 0;
|
||||
|
||||
set_SR_periodandoffset(schedulingRequestResourceConfig, scc, scs);
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[0]->beam_info;
|
||||
if (beam_info->beam_mode == NO_BEAM_MODE)
|
||||
set_SR_periodandoffset(schedulingRequestResourceConfig, scc, scs);
|
||||
else
|
||||
set_SR_periodandoffset_beam(schedulingRequestResourceConfig, scc, scs, beam_idx);
|
||||
|
||||
schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
|
||||
*schedulingRequestResourceConfig->resource = *pucchressetid;
|
||||
@@ -1873,7 +1979,8 @@ static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA,
|
||||
int maxMIMO_Layers,
|
||||
const nr_mac_config_t *configuration,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const NR_UE_NR_Capability_t *uecap)
|
||||
const NR_UE_NR_Capability_t *uecap,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_BWP_Uplink_t *ubwp = calloc_or_fail(1, sizeof(*ubwp));
|
||||
ubwp->bwp_Id = 1;
|
||||
@@ -1916,7 +2023,7 @@ static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA,
|
||||
config_pucch_resset0(scc, pucch_Config, uid, curr_bwp, uecap, &configuration->pdsch_AntennaPorts);
|
||||
config_pucch_resset1(scc, pucch_Config, uid, curr_bwp, uecap, &configuration->pdsch_AntennaPorts);
|
||||
set_pucch_power_config(pucch_Config, configuration->do_CSIRS);
|
||||
scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
|
||||
scheduling_request_config(scc, pucch_Config, ubwp->bwp_Common->genericParameters.subcarrierSpacing, beam_idx);
|
||||
set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, ubwp->bwp_Common->genericParameters.subcarrierSpacing);
|
||||
|
||||
ubwp->bwp_Dedicated->pusch_Config = config_pusch(configuration, scc, uecap);
|
||||
@@ -1928,7 +2035,8 @@ static NR_BWP_Uplink_t *config_uplinkBWP(bool is_SA,
|
||||
ubwp->bwp_Id,
|
||||
maxMIMO_Layers,
|
||||
configuration->minRXTXTIME,
|
||||
configuration->do_SRS);
|
||||
configuration->do_SRS,
|
||||
beam_idx);
|
||||
|
||||
ubwp->bwp_Dedicated->configuredGrantConfig = NULL;
|
||||
ubwp->bwp_Dedicated->beamFailureRecoveryConfig = NULL;
|
||||
@@ -1950,14 +2058,38 @@ static void set_csi_meas_periodicity(const NR_ServingCellConfigCommon_t *scc,
|
||||
int uid,
|
||||
int curr_bwp,
|
||||
const nr_pdsch_AntennaPorts_t *antennaports,
|
||||
bool is_rsrp)
|
||||
bool is_rsrp,
|
||||
int beam_idx)
|
||||
{
|
||||
const int ideal_period = set_ideal_period(true);
|
||||
int ideal_period;
|
||||
const int num_pucch2 = get_nb_pucch2_per_slot(scc, curr_bwp, antennaports);
|
||||
const int idx = (uid * 2 / num_pucch2) + is_rsrp;
|
||||
int idx;
|
||||
frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||
int offset = get_ul_slot_offset(fs, idx, true);
|
||||
LOG_D(NR_MAC, "set_csi_meas_periodicity: uid = %d, offset = %d, ideal_period = %d", uid, offset, ideal_period);
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[0]->beam_info;
|
||||
int offset;
|
||||
if (beam_info->beam_mode != NO_BEAM_MODE) {
|
||||
// For NO_BEAM_MODE
|
||||
// C - CSI meas
|
||||
// R - RSRP
|
||||
// UL slot
|
||||
// 0123456789
|
||||
// uid0 CR
|
||||
// uid1 -CR
|
||||
// uid2 --CR
|
||||
// With beamforming, uid0, uid1 and uid could be of different beams. CSI meas and Report of different uid could not be shared
|
||||
idx = uid * 2 + is_rsrp;
|
||||
int num_beam = (RC.nrmac[0]->radio_config.nb_bfw[1] > 0) ? RC.nrmac[0]->radio_config.nb_bfw[1]: 1;
|
||||
int beams_per_period = (beam_info->beams_per_period > 0) ? beam_info->beams_per_period: 1;
|
||||
int NUM_SSB_period = (num_beam % beams_per_period > 0) ? num_beam / beams_per_period + 1 : num_beam / beams_per_period;
|
||||
ideal_period = set_ideal_period_beam(true, NUM_SSB_period);
|
||||
LOG_I(NR_MAC, "set_csi_meas_periodicity 0 idx %d count_mixed %d beam_idx %d num_beam %d ideal_period %d\n", idx, true, beam_idx, num_beam, ideal_period);
|
||||
offset = get_ul_slot_offset_beam(fs, idx, true, beam_idx, beams_per_period, num_beam);
|
||||
} else {
|
||||
ideal_period = set_ideal_period(true);
|
||||
idx = (uid * 2 / num_pucch2) + is_rsrp;
|
||||
offset = get_ul_slot_offset(fs, idx, true);
|
||||
}
|
||||
LOG_I(NR_MAC, "set_csi_meas_periodicity: uid = %d, offset = %d, ideal_period = %d\n", uid, offset, ideal_period);
|
||||
// checked for validity in verify_radio_configuration
|
||||
AssertFatal(offset < 320, "Not enough UL slots to accomodate all possible UEs. Need to rework the implementation\n");
|
||||
if (check_periodicity(4, ideal_period, fs)) {
|
||||
@@ -2107,7 +2239,8 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
const int max_layers,
|
||||
int rep_id,
|
||||
int uid,
|
||||
int curr_bwp)
|
||||
int curr_bwp,
|
||||
int beam_idx)
|
||||
{
|
||||
int resource_id = -1;
|
||||
int im_id = -1;
|
||||
@@ -2136,7 +2269,7 @@ static void config_csi_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
csirep->nzp_CSI_RS_ResourcesForInterference = NULL;
|
||||
csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
|
||||
csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
|
||||
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, antennaports, false);
|
||||
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, antennaports, false, beam_idx);
|
||||
asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
|
||||
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI;
|
||||
csirep->reportQuantity.choice.cri_RI_PMI_CQI = (NULL_t)0;
|
||||
@@ -2203,7 +2336,8 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
int rep_id,
|
||||
int uid,
|
||||
int curr_bwp,
|
||||
uint64_t ssb_bitmap)
|
||||
uint64_t ssb_bitmap,
|
||||
int beam_idx)
|
||||
{
|
||||
int resource_id = -1;
|
||||
const nr_pdsch_AntennaPorts_t *pdschap = &configuration->pdsch_AntennaPorts;
|
||||
@@ -2231,7 +2365,7 @@ static void config_rsrp_meas_report(NR_CSI_MeasConfig_t *csi_MeasConfig,
|
||||
csirep->nzp_CSI_RS_ResourcesForInterference = NULL;
|
||||
csirep->reportConfigType.present = NR_CSI_ReportConfig__reportConfigType_PR_periodic;
|
||||
csirep->reportConfigType.choice.periodic = calloc(1, sizeof(*csirep->reportConfigType.choice.periodic));
|
||||
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, pdschap, true);
|
||||
set_csi_meas_periodicity(servingcellconfigcommon, csirep, uid, curr_bwp, pdschap, true, beam_idx);
|
||||
asn1cSeqAdd(&csirep->reportConfigType.choice.periodic->pucch_CSI_ResourceList.list, pucchcsires);
|
||||
if (configuration->report_type == SSB_SINR) {
|
||||
csirep->reportQuantity.present = NR_CSI_ReportConfig__reportQuantity_PR_none;
|
||||
@@ -3347,7 +3481,8 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo
|
||||
const nr_mac_config_t *configuration,
|
||||
int maxMIMO_Layers,
|
||||
const NR_UE_NR_Capability_t *uecap,
|
||||
int id)
|
||||
int id,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_BWP_UplinkDedicated_t *initialUplinkBWP = calloc(1, sizeof(*initialUplinkBWP));
|
||||
NR_BWP_t *genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
@@ -3367,9 +3502,9 @@ static NR_BWP_UplinkDedicated_t *configure_initial_ul_bwp(const NR_ServingCellCo
|
||||
initialUplinkBWP->pusch_Config = config_pusch(configuration, scc, uecap);
|
||||
|
||||
// We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1
|
||||
initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0);
|
||||
initialUplinkBWP->srs_Config = get_config_srs(scc, uecap, curr_bwp, id, 0, maxMIMO_Layers, configuration->minRXTXTIME, 0, beam_idx);
|
||||
|
||||
scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing);
|
||||
scheduling_request_config(scc, pucch_Config, scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing, beam_idx);
|
||||
set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME, genericParameters->subcarrierSpacing);
|
||||
return initialUplinkBWP;
|
||||
}
|
||||
@@ -3425,7 +3560,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf
|
||||
int uid,
|
||||
int bwp_id,
|
||||
uint64_t bitmap,
|
||||
int ssb_index)
|
||||
int ssb_index,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_CSI_MeasConfig_t *csi_MeasConfig = calloc(1, sizeof(*csi_MeasConfig));
|
||||
csi_MeasConfig->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*csi_MeasConfig->csi_SSB_ResourceSetToAddModList));
|
||||
@@ -3523,7 +3659,8 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf
|
||||
*configDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers,
|
||||
bwp_id,
|
||||
uid,
|
||||
curr_bwp);
|
||||
curr_bwp,
|
||||
beam_idx);
|
||||
}
|
||||
NR_PUCCH_CSI_Resource_t *pucchrsrp = calloc(1, sizeof(*pucchrsrp));
|
||||
pucchrsrp->uplinkBandwidthPartId = bwp_id;
|
||||
@@ -3536,14 +3673,16 @@ static NR_CSI_MeasConfig_t *get_csiMeasConfig(const NR_ServingCellConfig_t *conf
|
||||
bwp_id + 10,
|
||||
uid,
|
||||
curr_bwp,
|
||||
bitmap);
|
||||
bitmap,
|
||||
beam_idx);
|
||||
return csi_MeasConfig;
|
||||
}
|
||||
|
||||
static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const nr_mac_config_t *configuration,
|
||||
int ssb_index)
|
||||
int ssb_index,
|
||||
int beam_idx)
|
||||
{
|
||||
const int pdsch_AntennaPorts =
|
||||
configuration->pdsch_AntennaPorts.N1 * configuration->pdsch_AntennaPorts.N2 * configuration->pdsch_AntennaPorts.XP;
|
||||
@@ -3583,7 +3722,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
|
||||
asn1cCallocOne(configDedicated->firstActiveDownlinkBWP_Id, first_active_bwp);
|
||||
asn1cCallocOne(uplinkConfig->firstActiveUplinkBWP_Id, first_active_bwp);
|
||||
if (first_active_bwp == 0) {
|
||||
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, NULL, uid);
|
||||
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, configuration, maxMIMO_Layers, NULL, uid, beam_idx);
|
||||
configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, NULL, configuration);
|
||||
} else {
|
||||
configDedicated->downlinkBWP_ToAddModList = calloc(1, sizeof(*configDedicated->downlinkBWP_ToAddModList));
|
||||
@@ -3595,7 +3734,7 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
|
||||
configuration);
|
||||
asn1cSeqAdd(&configDedicated->downlinkBWP_ToAddModList->list, bwp);
|
||||
uplinkConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList));
|
||||
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(true, uid, maxMIMO_Layers, configuration, scc, NULL);
|
||||
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(true, uid, maxMIMO_Layers, configuration, scc, NULL, beam_idx);
|
||||
asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ubwp);
|
||||
}
|
||||
|
||||
@@ -3608,7 +3747,8 @@ static NR_SpCellConfig_t *get_initial_SpCellConfig(int uid,
|
||||
uid,
|
||||
first_active_bwp,
|
||||
bitmap,
|
||||
ssb_index);
|
||||
ssb_index,
|
||||
beam_idx);
|
||||
|
||||
fill_harq_IEs(configDedicated, configuration->num_dlharq, configuration->num_ulharq, first_active_bwp);
|
||||
SpCellConfig->spCellConfigDedicated = configDedicated;
|
||||
@@ -3741,10 +3881,21 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId,
|
||||
return rlc_BearerConfig;
|
||||
}
|
||||
|
||||
static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration)
|
||||
static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon_t *scc, const nr_mac_config_t *configuration, int beam_idx)
|
||||
{
|
||||
frame_structure_t *fs = &RC.nrmac[0]->frame_structure;
|
||||
int srs_offset = get_ul_slot_offset(fs, uid, false);
|
||||
NR_beam_info_t *beam_info = &RC.nrmac[0]->beam_info;
|
||||
int srs_offset;
|
||||
if (beam_info->beam_mode != NO_BEAM_MODE) {
|
||||
int num_beam = (RC.nrmac[0]->radio_config.nb_bfw[1] > 0) ? RC.nrmac[0]->radio_config.nb_bfw[1] : 1;
|
||||
int beams_per_period = (beam_info->beams_per_period > 0) ? beam_info->beams_per_period : 1;
|
||||
srs_offset = get_ul_slot_offset_beam(fs, uid, false, beam_idx, beams_per_period, num_beam);
|
||||
LOG_I(NR_MAC, "verify_radio_configuration 0 idx %d count_mixed %d beam_idx %d num_beam %d srs_offset %d\n",
|
||||
uid, false, beam_idx, num_beam, srs_offset);
|
||||
} else {
|
||||
srs_offset = get_ul_slot_offset(fs, uid, false);
|
||||
}
|
||||
|
||||
// see configure_periodic_srs
|
||||
if (srs_offset >= 2560) {
|
||||
LOG_E(NR_RRC, "UID %d, cannot allocate resources for SRS, rejecting UE\n", uid);
|
||||
@@ -3774,8 +3925,29 @@ static bool verify_radio_configuration(int uid, const NR_ServingCellConfigCommon
|
||||
LOG_E(NR_RRC, "UID %d, cannot allocate resources for PUCCH2, rejecting UE\n", uid);
|
||||
return false; // cannot allocate resources for PUCCH2
|
||||
}
|
||||
const int idx = (uid * 2 / num_pucch2) + 1;
|
||||
int offset = get_ul_slot_offset(fs, idx, true);
|
||||
|
||||
int offset;
|
||||
if (beam_info->beam_mode != NO_BEAM_MODE) {
|
||||
int num_beam = (RC.nrmac[0]->radio_config.nb_bfw[1] > 0) ? RC.nrmac[0]->radio_config.nb_bfw[1] : 1;
|
||||
int beams_per_period = (beam_info->beams_per_period > 0) ? beam_info->beams_per_period : 1;
|
||||
// For NO_BEAM_MODE
|
||||
// C - CSI meas
|
||||
// R - RSRP
|
||||
// UL slot
|
||||
// 0123456789
|
||||
// uid0 CR
|
||||
// uid1 -CR
|
||||
// uid2 --CR
|
||||
// With beamforming, uid0, uid1 and uid could be of different beams. CSI meas and Report of different uid could not be shared
|
||||
const int idx = (uid * 2) + 1;
|
||||
offset = get_ul_slot_offset_beam(fs, idx, true, beam_idx, beams_per_period, num_beam);
|
||||
LOG_I(NR_MAC, "verify_radio_configuration 1 idx %d count_mixed %d beam_idx %d num_beam %d offset %d\n",
|
||||
idx, true, beam_idx, num_beam, offset);
|
||||
} else {
|
||||
const int idx = (uid * 2 / num_pucch2) + 1;
|
||||
offset = get_ul_slot_offset(fs, idx, true);;
|
||||
}
|
||||
|
||||
// see set_csi_meas_periodicity
|
||||
if (offset >= 320) {
|
||||
LOG_E(NR_RRC, "UID %d, cannot allocate resources for CSI reporting, rejecting UE\n", uid);
|
||||
@@ -3789,12 +3961,13 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const nr_mac_config_t *configuration,
|
||||
const nr_rlc_configuration_t *default_rlc_config,
|
||||
int ssb_index)
|
||||
int ssb_index,
|
||||
int beam_idx)
|
||||
{
|
||||
if (!verify_radio_configuration(uid, scc, configuration))
|
||||
if (!verify_radio_configuration(uid, scc, configuration, beam_idx))
|
||||
return NULL;
|
||||
|
||||
NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, configuration, ssb_index);
|
||||
NR_SpCellConfig_t *spCellConfig = get_initial_SpCellConfig(uid, scc, configuration, ssb_index, beam_idx);
|
||||
NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(*cellGroupConfig));
|
||||
cellGroupConfig->cellGroupId = 0;
|
||||
|
||||
@@ -3826,7 +3999,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t
|
||||
int uid,
|
||||
int old_bwp,
|
||||
int new_bwp,
|
||||
int ssb_index)
|
||||
int ssb_index,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig;
|
||||
NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated;
|
||||
@@ -3845,7 +4019,7 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t
|
||||
configDedicated->initialDownlinkBWP = calloc_or_fail(1, sizeof(*configDedicated->initialDownlinkBWP));
|
||||
if (!uplinkConfig->initialUplinkBWP)
|
||||
uplinkConfig->initialUplinkBWP = calloc_or_fail(1, sizeof(*uplinkConfig->initialUplinkBWP));
|
||||
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, &local_config, ul_maxMIMO_Layers, uecap, uid);
|
||||
uplinkConfig->initialUplinkBWP = configure_initial_ul_bwp(scc, &local_config, ul_maxMIMO_Layers, uecap, uid, beam_idx);
|
||||
configDedicated->initialDownlinkBWP = configure_initial_dl_bwp(scc, pdsch_AntennaPorts, bitmap, uecap, &local_config);
|
||||
} else {
|
||||
if (!configDedicated->downlinkBWP_ToAddModList)
|
||||
@@ -3860,7 +4034,7 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t
|
||||
|
||||
if (!uplinkConfig->uplinkBWP_ToAddModList)
|
||||
uplinkConfig->uplinkBWP_ToAddModList = calloc_or_fail(1, sizeof(*uplinkConfig->uplinkBWP_ToAddModList));
|
||||
NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(true, uid, ul_maxMIMO_Layers, &local_config, scc, uecap);
|
||||
NR_BWP_Uplink_t *ul_bwp = config_uplinkBWP(true, uid, ul_maxMIMO_Layers, &local_config, scc, uecap, beam_idx);
|
||||
asn1cSeqAdd(&uplinkConfig->uplinkBWP_ToAddModList->list, ul_bwp);
|
||||
}
|
||||
|
||||
@@ -3872,7 +4046,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t
|
||||
uid,
|
||||
*uplinkConfig->firstActiveUplinkBWP_Id,
|
||||
bitmap,
|
||||
ssb_index);
|
||||
ssb_index,
|
||||
beam_idx);
|
||||
|
||||
// we temporarily need to keep both the old and the new BWP in the CG used by the gNB
|
||||
// while removing the old from the CG sent to the UE
|
||||
@@ -3890,7 +4065,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
int uid,
|
||||
int bwp,
|
||||
int ssb_index)
|
||||
int ssb_index,
|
||||
int beam_idx)
|
||||
{
|
||||
NR_SpCellConfig_t *spCellConfig = cellGroupConfig->spCellConfig;
|
||||
NR_ServingCellConfig_t *configDedicated = spCellConfig->spCellConfigDedicated;
|
||||
@@ -3904,7 +4080,8 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_
|
||||
uid,
|
||||
bwp,
|
||||
bitmap,
|
||||
ssb_index);
|
||||
ssb_index,
|
||||
beam_idx);
|
||||
|
||||
NR_CellGroupConfig_t *clone_cg = NULL;
|
||||
const int copy_result = asn_copy(&asn_DEF_NR_CellGroupConfig, (void **)&clone_cg, cellGroupConfig);
|
||||
@@ -3916,7 +4093,8 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
const int uid,
|
||||
const NR_UE_NR_Capability_t *uecap,
|
||||
const nr_mac_config_t *configuration,
|
||||
const NR_ServingCellConfigCommon_t *scc)
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
int beam_idx)
|
||||
{
|
||||
DevAssert(cellGroupConfig != NULL);
|
||||
DevAssert(cellGroupConfig->spCellConfig != NULL);
|
||||
@@ -3998,7 +4176,8 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
bwp_id,
|
||||
maxMIMO_Layers,
|
||||
configuration->minRXTXTIME,
|
||||
configuration->do_SRS);
|
||||
configuration->do_SRS,
|
||||
beam_idx);
|
||||
}
|
||||
set_ul_mcs_table(configuration->force_UL256qam_off ? NULL : uecap, scc, pusch_Config);
|
||||
}
|
||||
@@ -4052,7 +4231,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
int servCellIndex,
|
||||
const nr_mac_config_t *configuration,
|
||||
int uid,
|
||||
int ssb_index)
|
||||
int ssb_index,
|
||||
int beam_idx)
|
||||
{
|
||||
const nr_pdsch_AntennaPorts_t *pdschap = &configuration->pdsch_AntennaPorts;
|
||||
const int dl_antenna_ports = pdschap->N1 * pdschap->N2 * pdschap->XP;
|
||||
@@ -4123,7 +4303,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
0,
|
||||
maxMIMO_Layers,
|
||||
configuration->minRXTXTIME,
|
||||
configuration->do_SRS);
|
||||
configuration->do_SRS,
|
||||
beam_idx);
|
||||
|
||||
// Downlink BWPs
|
||||
int firstActiveDownlinkBWP_Id = 1;
|
||||
@@ -4143,7 +4324,7 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
// Uplink BWPs
|
||||
int firstActiveUplinkBWP_Id = 1;
|
||||
ulConfig->uplinkBWP_ToAddModList = calloc(1, sizeof(*ulConfig->uplinkBWP_ToAddModList));
|
||||
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap);
|
||||
NR_BWP_Uplink_t *ubwp = config_uplinkBWP(false, uid, maxMIMO_Layers, configuration, servingcellconfigcommon, uecap, beam_idx);
|
||||
asn1cSeqAdd(&ulConfig->uplinkBWP_ToAddModList->list, ubwp);
|
||||
ulConfig->firstActiveUplinkBWP_Id = calloc(1, sizeof(*ulConfig->firstActiveUplinkBWP_Id));
|
||||
*ulConfig->firstActiveUplinkBWP_Id = firstActiveUplinkBWP_Id;
|
||||
@@ -4204,7 +4385,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
uid,
|
||||
firstActiveUplinkBWP_Id,
|
||||
bitmap,
|
||||
ssb_index);
|
||||
ssb_index,
|
||||
beam_idx);
|
||||
|
||||
configDedicated->sCellDeactivationTimer = NULL;
|
||||
configDedicated->crossCarrierSchedulingConfig = NULL;
|
||||
|
||||
@@ -96,12 +96,14 @@ NR_CellGroupConfig_t *get_initial_cellGroupConfig(int uid,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
const nr_mac_config_t *configuration,
|
||||
const nr_rlc_configuration_t *default_rlc_config,
|
||||
int ssb_index);
|
||||
int ssb_index,
|
||||
int beam_idx);
|
||||
void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
const int uid,
|
||||
const NR_UE_NR_Capability_t *uecap,
|
||||
const nr_mac_config_t *configuration,
|
||||
const NR_ServingCellConfigCommon_t *scc);
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
int beam_idx);
|
||||
int encode_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, uint8_t *buffer, int max_buffer_size);
|
||||
|
||||
/* Note: this function returns a new CellGroupConfig for a user with given
|
||||
@@ -113,7 +115,8 @@ NR_CellGroupConfig_t *get_default_secondaryCellGroup(const NR_ServingCellConfigC
|
||||
int servCellIndex,
|
||||
const nr_mac_config_t *configuration,
|
||||
int uid,
|
||||
int ssb_index);
|
||||
int ssb_index,
|
||||
int beam_idx);
|
||||
|
||||
NR_ReconfigurationWithSync_t *get_reconfiguration_with_sync(rnti_t rnti, uid_t uid, const NR_ServingCellConfigCommon_t *scc, int frame);
|
||||
|
||||
@@ -136,14 +139,16 @@ NR_CellGroupConfig_t *update_cellGroupConfig_for_BWP_switch(NR_CellGroupConfig_t
|
||||
int uid,
|
||||
int old_bwp,
|
||||
int new_bwp,
|
||||
int ssb_index);
|
||||
int ssb_index,
|
||||
int beam_idx);
|
||||
NR_CellGroupConfig_t *update_cellGroupConfig_for_beam_switch(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
const nr_mac_config_t *configuration,
|
||||
const NR_UE_NR_Capability_t *uecap,
|
||||
const NR_ServingCellConfigCommon_t *scc,
|
||||
int uid,
|
||||
int bwp,
|
||||
int ssb_index);
|
||||
int ssb_index,
|
||||
int beam_idx);
|
||||
NR_MeasurementTimingConfiguration_t *get_nr_mtc(uint8_t *buf, uint32_t len);
|
||||
measgap_config_t create_measgap_config(const NR_MeasurementTimingConfiguration_t *mtc, int scs, int min_rxtxtime);
|
||||
int encode_measgap_config(const measgap_config_t *c, uint8_t *buf);
|
||||
|
||||
@@ -101,6 +101,7 @@ typedef struct {
|
||||
int64_t rx_count;
|
||||
int wait_for_first_pps;
|
||||
int use_gps;
|
||||
int prev_beam;
|
||||
//int first_tx;
|
||||
//int first_rx;
|
||||
//! timestamp of RX packet
|
||||
@@ -334,6 +335,7 @@ static int trx_usrp_start(openair0_device_t *device)
|
||||
//s->first_tx = 1;
|
||||
//s->first_rx = 1;
|
||||
s->rx_timestamp = 0;
|
||||
s->prev_beam = -1;
|
||||
|
||||
//wait for next pps
|
||||
uhd::time_spec_t last_pps = s->usrp->get_time_last_pps();
|
||||
@@ -380,6 +382,41 @@ static void trx_usrp_finish_rx(usrp_state_t *s)
|
||||
} while (samples > 0);
|
||||
}
|
||||
|
||||
static int trx_set_beam(openair0_device_t *device, int *beams, int num_beams, openair0_timestamp_t timestamp)
|
||||
{
|
||||
AssertFatal(beams, "Invalid input for beams %p, vector not present\n", beams);
|
||||
AssertFatal(num_beams == 1, "Cannot handle more than 1 concurrent beam in USRP\n");
|
||||
usrp_state_t *s = (usrp_state_t *)device->priv;
|
||||
if (beams[0] == s->prev_beam)
|
||||
return 0;
|
||||
else
|
||||
s->prev_beam = beams[0];
|
||||
int gpio = 0;
|
||||
switch (device->openair0_cfg->gpio_controller) {
|
||||
case RU_GPIO_CONTROL_GENERIC:
|
||||
AssertFatal(beams[0] < 8, "Only 3 bits available for setting beams\n");
|
||||
gpio = s->prev_beam | TX_GPIO_CHANGE;
|
||||
break;
|
||||
case RU_GPIO_CONTROL_INTERDIGITAL:
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
AssertFatal(false, "illegal GPIO controller for beam handling %d\n", device->openair0_cfg->gpio_controller);
|
||||
}
|
||||
radio_tx_gpio_flag_t flags_gpio = (radio_tx_gpio_flag_t) gpio;
|
||||
// bit 13 enables gpio
|
||||
timestamp -= device->openair0_cfg->command_line_sample_advance + device->openair0_cfg->tx_sample_advance;
|
||||
s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO, 1);
|
||||
// push GPIO bits
|
||||
s->usrp->set_command_time(s->tx_md.time_spec);
|
||||
s->usrp->set_gpio_attr(s->gpio_bank, "OUT", flags_gpio, MAN_MASK);
|
||||
s->usrp->clear_command_time();
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void trx_usrp_write_reset(openair0_thread_t *wt);
|
||||
|
||||
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
|
||||
@@ -439,7 +476,6 @@ static int trx_usrp_write(openair0_device_t *device,
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
|
||||
radio_tx_burst_flag_t flags_burst = (radio_tx_burst_flag_t) (flags & 0xf);
|
||||
radio_tx_gpio_flag_t flags_gpio = (radio_tx_gpio_flag_t) ((flags >> 4) & 0x1fff);
|
||||
|
||||
int end;
|
||||
openair0_thread_t *write_thread = &device->write_thread;
|
||||
@@ -501,16 +537,6 @@ static int trx_usrp_write(openair0_device_t *device,
|
||||
s->tx_md.time_spec = uhd::time_spec_t::from_ticks(timestamp, s->sample_rate);
|
||||
s->tx_count++;
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO, 1);
|
||||
// bit 13 enables gpio
|
||||
if ((flags_gpio & TX_GPIO_CHANGE) != 0) {
|
||||
// push GPIO bits
|
||||
s->usrp->set_command_time(s->tx_md.time_spec);
|
||||
s->usrp->set_gpio_attr(s->gpio_bank, "OUT", flags_gpio, MAN_MASK);
|
||||
s->usrp->clear_command_time();
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHING_GPIO, 0);
|
||||
|
||||
if (cc > 1) {
|
||||
std::vector<void *> buff_ptrs;
|
||||
|
||||
@@ -545,7 +571,7 @@ static int trx_usrp_write(openair0_device_t *device,
|
||||
write_package[end].cc = cc;
|
||||
write_package[end].first_packet = first_packet_state;
|
||||
write_package[end].last_packet = last_packet_state;
|
||||
write_package[end].flags_gpio = flags_gpio;
|
||||
//write_package[end].flags_gpio = flags_gpio;
|
||||
for (int i = 0; i < cc; i++)
|
||||
write_package[end].buff[i] = buff[i];
|
||||
write_thread->count_write++;
|
||||
@@ -1537,6 +1563,7 @@ extern "C" {
|
||||
LOG_I(HW,"Device timestamp: %f...\n", s->usrp->get_time_now().get_real_secs());
|
||||
device->trx_write_func = trx_usrp_write;
|
||||
device->trx_read_func = trx_usrp_read;
|
||||
device->trx_set_beams2 = trx_set_beam;
|
||||
s->sample_rate = openair0_cfg[0].sample_rate;
|
||||
|
||||
// TODO:
|
||||
|
||||
Reference in New Issue
Block a user