Commit c6855cb8 authored by Guido Casati's avatar Guido Casati 🇮🇹 Committed by Guido Casati

Maintenance of Uplink Time Alignment. Introduced control on TA transmission...

Maintenance of Uplink Time Alignment. Introduced control on TA transmission and TA update application.

- ta_timer at gNB side to control the transmission of TA to the UE. This is now happening every 20 slots.
- when the timer resets gNB is now transmitting the TA whether it is zero or not.
- introduced struct NR_UL_TIME_ALIGNMENT_t to handle configuration of time alignment related parameters.
- UE PHY RX: is now triggered through a flag when to store the TA command, the frame and slot
  when the application should occur.
- UE PHY TX: when the tx frame and slot match the time alignment configuration, it process the TA command and applies the
  TA update
parent 5ac8b6f3
......@@ -461,6 +461,15 @@ void UE_processing(void *arg) {
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
processSlotRX(UE, proc);
uint8_t gNB_id = 0;
// params for UL time alignment procedure
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id];
uint8_t numerology = UE->frame_parms.numerology_index;
uint16_t bwp_ul_NB_RB = UE->frame_parms.N_RB_UL;
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
//printf(">>> mac ended\n");
// Prepare the future Tx data
/*
......@@ -473,6 +482,21 @@ void UE_processing(void *arg) {
#endif
*/
/* UL time alignment
// If the current tx frame and slot match the TA configuration in ul_time_alignment
// then timing advance is processed and set to be applied in the next UL transmission */
if (UE->mac_enabled == 1) {
if (frame_tx == ul_time_alignment->ta_frame && slot_tx == ul_time_alignment->ta_slot){
LOG_D(PHY,"Applying timing advance -- frame %d -- slot %d\n", frame_tx, slot_tx);
//if (nfapi_mode!=3){
nr_process_timing_advance(UE->Mod_id, UE->CC_id, ul_time_alignment->ta_command, numerology, bwp_ul_NB_RB);
ul_time_alignment->ta_frame = -1;
ul_time_alignment->ta_slot = -1;
//}
}
}
if (proc->nr_tti_tx == NR_UPLINK_SLOT || UE->frame_parms.frame_type == FDD){
......@@ -480,7 +504,7 @@ void UE_processing(void *arg) {
if (UE->mode != loop_through_memory)
phy_procedures_nrUE_TX(UE,proc,0,thread_id);
phy_procedures_nrUE_TX(UE,proc,gNB_id,thread_id);
}
......
......@@ -871,6 +871,16 @@ typedef struct UE_NR_SCAN_INFO_s {
int32_t freq_offset_Hz[3][10];
} UE_NR_SCAN_INFO_t;
typedef struct {
/// flag used by MAC to inform PHY about a TA to be applied
unsigned char apply_ta;
/// frame and slot when to apply the TA as stated in TS 38.213 setion 4.2
int16_t ta_frame;
char ta_slot;
/// TA command and TAGID received from the gNB
uint8_t ta_command;
uint8_t tag_id;
} NR_UL_TIME_ALIGNMENT_t;
#include "NR_IF_Module.h"
......@@ -1066,9 +1076,14 @@ typedef struct {
int rx_offset; /// Timing offset
int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
int time_sync_cell;
int timing_advance; ///timing advance signalled from eNB
int hw_timing_advance;
int N_TA_offset; ///timing offset used in TDD
/// Timing Advance updates variables
/// Timing advance update computed from the TA command signalled from gNB
int timing_advance;
int hw_timing_advance;
int N_TA_offset; ///timing offset used in TDD
NR_UL_TIME_ALIGNMENT_t ul_time_alignment[NUMBER_OF_CONNECTED_gNB_MAX];
/// Flag to tell if UE is secondary user (cognitive mode)
unsigned char is_secondary_ue;
/// Flag to tell if secondary eNB has channel estimates to create NULL-beams from.
......
......@@ -292,10 +292,10 @@ int8_t nr_find_ue(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB);
/*! \brief Compute the timing adjustment at UE side from the old TA offset and the new received TA command
@param Mod_id Local UE index on which to act
@param CC_id Component Carrier Index
@param timing_advance TA command
@param ta_command TA command received from the network
@param mu numerology index (0,1,2..)
*/
void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t timing_advance, uint8_t mu, uint16_t bwp_ul_NB_RB);
void nr_process_timing_advance(module_id_t Mod_id,uint8_t CC_id,uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB);
void nr_process_timing_advance_rar(PHY_VARS_NR_UE *phy_vars_ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance);
unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb);
......
......@@ -1545,7 +1545,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDUR
#endif
void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing_advance, uint8_t mu, uint16_t bwp_ul_NB_RB){
void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
// 3GPP TS 38.213 p4.2
// scale by the scs numerology
......@@ -1561,9 +1561,9 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t timing
default: abort();
}
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (timing_advance - 31) * bw_scaling / factor_mu;
PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu;
LOG_D(PHY,"[UE %d] Got timing advance %u from MAC, new value is %u\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %u\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
}
void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
......@@ -3545,6 +3545,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
uint16_t nb_symb_sch = 9;
nr_downlink_indication_t dl_indication;
fapi_nr_rx_indication_t rx_ind;
// params for UL time alignment procedure
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &ue->ul_time_alignment[eNB_id];
unsigned char *apply_ta = &ul_time_alignment->apply_ta;
uint16_t slots_per_frame = ue->frame_parms.slots_per_frame;
int ul_tx_timing_adjustment = 6; // temporary hardcoded
if (dlsch0==NULL)
AssertFatal(0,"dlsch0 should be defined at this level \n");
......@@ -3850,7 +3855,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
nr_tti_rx,
dlsch0->harq_processes[harq_pid]->b,
dlsch0->harq_processes[harq_pid]->TBS>>3,
eNB_id);
eNB_id,
ul_time_alignment);
break;
case SI_PDSCH:
/*ue_decode_si(ue->Mod_id,
......@@ -3880,6 +3886,20 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
AssertFatal(1==0,"exiting");*/
break;
}
/* Time alignment procedure set the TA to be applied 6 slots
// after the reception of the command */
if (ul_time_alignment->apply_ta == 1){
ul_time_alignment->ta_slot = (nr_tti_rx + ul_tx_timing_adjustment) % slots_per_frame;
if (nr_tti_rx + ul_tx_timing_adjustment > slots_per_frame){
ul_time_alignment->ta_frame = (frame_rx + 1) % 1024;
} else {
ul_time_alignment->ta_frame = frame_rx;
}
// reset TA flag
ul_time_alignment->apply_ta = 0;
LOG_D(PHY,"Frame %d slot %d -- Starting UL time alignment procedures. TA update will be applied at frame %d slot %d\n", frame_rx, nr_tti_rx, ul_time_alignment->ta_frame, ul_time_alignment->ta_slot);
}
}
/*ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS;
......
......@@ -137,14 +137,15 @@ uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t
@returns void
*/
void nr_ue_send_sdu(module_id_t module_idP,uint8_t CC_id, frame_t frameP, uint8_t ttiP,
uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index);
uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
void nr_ue_process_mac_pdu(
module_id_t module_idP,
uint8_t CC_id,
uint8_t *pduP,
uint16_t mac_pdu_len,
uint8_t eNB_index);
uint8_t eNB_index,
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment);
int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len);
......
......@@ -2047,7 +2047,7 @@ void nr_ue_send_sdu(module_id_t module_idP,
uint8_t CC_id,
frame_t frameP,
uint8_t ttiP,
uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index){
uint8_t * pdu, uint16_t pdu_len, uint8_t eNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
printf("nr_ue_send_sdu frame %d\n", frameP);
......@@ -2094,7 +2094,7 @@ void nr_ue_send_sdu(module_id_t module_idP,
// Processing MAC PDU
// it parses MAC CEs subheaders, MAC CEs, SDU subheaderds and SDUs
nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index);
nr_ue_process_mac_pdu(module_idP, CC_id, pduP, pdu_len, eNB_index, ul_time_alignment);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
......@@ -2110,7 +2110,8 @@ void nr_ue_process_mac_pdu(
uint8_t CC_id,
uint8_t *pduP,
uint16_t mac_pdu_len,
uint8_t eNB_index){
uint8_t eNB_index,
NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
// This function is adapting code from the old
// parse_header(...) and ue_send_sdu(...) functions of OAI LTE
......@@ -2123,8 +2124,9 @@ void nr_ue_process_mac_pdu(
uint16_t mac_sdu_len;
NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP);
uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon;
uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB;
//uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon;
//uint16_t bwp_ul_NB_RB = UE_mac_inst->initial_bwp_ul.N_RB;
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
......@@ -2280,9 +2282,12 @@ void nr_ue_process_mac_pdu(
// 38.321 Ch6.1.3.4
mac_ce_len = 1;
uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND;
/*uint8_t ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND;
uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID;*/
uint8_t tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID;
ul_time_alignment->apply_ta = 1;
ul_time_alignment->ta_command = ((NR_MAC_CE_TA *)pdu_ptr)[1].TA_COMMAND;
ul_time_alignment->tag_id = ((NR_MAC_CE_TA *)pdu_ptr)[1].TAGID;
/*
#ifdef DEBUG_HEADER_PARSING
......@@ -2290,11 +2295,8 @@ void nr_ue_process_mac_pdu(
#endif
*/
LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n", ta_command, tag_id, CC_id);
//if (nfapi_mode!=3){ // TODO check nfapi_mode
nr_process_timing_advance(module_idP, CC_id, ta_command, scs, bwp_ul_NB_RB);
//}
LOG_D(MAC, "Received TA_COMMAND %u TAGID %u CC_id %d\n",
ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id);
break;
case DL_SCH_LCID_CON_RES_ID:
......
......@@ -53,6 +53,7 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload,
unsigned char drx_cmd,
unsigned short timing_advance_cmd,
NR_TAG_Id_t tag_id,
int ta_length,
unsigned char *ue_cont_res_id,
unsigned short post_padding){
......@@ -76,25 +77,30 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload,
}
// Timing Advance subheader
if (timing_advance_cmd != 31) {
/* This was done only when timing_advance_cmd != 31
// now TA is always send when ta_timer resets regardless of its value
// this is done to avoid issues with the timeAlignmentTimer which is
// supposed to monitor if the UE received TA or not */
if (ta_length){
mac_pdu_ptr->R = 0;
mac_pdu_ptr->LCID = DL_SCH_LCID_TA_COMMAND;
//last_size = 1;
mac_pdu_ptr++;
// TA MAC CE (1 octet)
// TA MAC CE (1 octet)
AssertFatal(timing_advance_cmd < 64,"timing_advance_cmd %d > 63\n", timing_advance_cmd);
((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND = timing_advance_cmd; //(timing_advance_cmd+31)&0x3f;
((NR_MAC_CE_TA *) ce_ptr)->TAGID = tag_id;
LOG_D(MAC, "NR MAC CE timing advance command =%d (%d) TAG ID =%d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
mac_ce_size = sizeof(NR_MAC_CE_TA);
// Copying bytes for MAC CEs to the mac pdu pointer
memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size);
ce_ptr += mac_ce_size;
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
mac_pdu_ptr += (unsigned char) mac_ce_size;
}
// Contention resolution fixed subheader and MAC CE
if (ue_cont_res_id) {
......@@ -199,35 +205,35 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
int UE_id = 0; // UE_list->head is -1 !
UE_sched_ctrl_t *ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
ta_update = ue_sched_ctl->ta_update;
//ta_update = ue_sched_ctl->ta_update;
for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP] + 1; CC_id++) {
LOG_D(MAC, "doing nr_schedule_ue_spec for CC_id %d\n", CC_id);
for (CC_id = 0; CC_id < RC.nb_nr_mac_CC[module_idP]; CC_id++) {
LOG_D(MAC, "doing nr_schedule_ue_spec for UE_id %d CC_id %d frame %d slot %d\n",
UE_id, CC_id, frameP, slotP);
dl_req = &gNB->DL_req[CC_id].dl_config_request_body;
//for (UE_id = UE_list->head; UE_id >= -1; UE_id = UE_list->next[UE_id]) {
/*
// this was taken from the preprocessor
if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--;
/*
//process retransmission
if (round != 8) {
} else { // This is a potentially new SDU opportunity */
if (gNB->tag->timeAlignmentTimer != NULL) {
printf(" SHOULD NOT ENTER HERE \n");
if (gNB->tag->timeAlignmentTimer == 0) {
ta_update = ue_sched_ctl->ta_update;
/* if we send TA then set timer to not send it for a while */
if (ta_update != 31)
ue_sched_ctl->ta_timer = 20;
/* reset ta_update */
ue_sched_ctl->ta_update = 31;
} else {
ta_update = 31;
}
}
if (ue_sched_ctl->ta_timer == 0) {
ta_update = ue_sched_ctl->ta_update;
/* if time is up, then set the timer to not send it for 20 NR_DOWNLINK_SLOT (20 frames)
// regardless of the TA value */
ue_sched_ctl->ta_timer = 2; //set to 20 when transmission will be in every slot
/* reset ta_update */
ue_sched_ctl->ta_update = 31;
ta_len = 2;
} // else ta_update = 31;
ta_len = (ta_update != 31) ? 2 : 0;
//ta_len = (ta_update != 31) ? 2 : 0;
// retrieve TAG ID
if(gNB->tag->tag_Id != NULL ){
......@@ -307,6 +313,7 @@ nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
255, // no drx
ta_update, // timing advance
tag_id,
ta_len,
NULL, // contention res id
post_padding);
// Padding: fill remainder of DLSCH with 0
......
......@@ -79,6 +79,7 @@ int nr_generate_dlsch_pdu(unsigned char *sdus_payload,
unsigned char drx_cmd,
unsigned short timing_advance_cmd,
NR_TAG_Id_t tag_id,
int ta_length,
unsigned char *ue_cont_res_id,
unsigned short post_padding);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment