Commit c6855cb8 authored by Guido Casati's avatar Guido Casati Committed by cig

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