diff --git a/executables/nr-ru.c b/executables/nr-ru.c index b098c8998a..a47a4f8ea0 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -604,6 +604,7 @@ void *emulatedRF_thread(void *param) { void rx_rf(RU_t *ru,int *frame,int *slot) { RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; + openair0_config_t *cfg = &ru->openair0_cfg; void *rxp[ru->nb_rx]; unsigned int rxs; int i; @@ -641,8 +642,8 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { if (rxs != samples_per_slot) LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",samples_per_slot,rxs); if (proc->first_rx == 1) { - ru->ts_offset = proc->timestamp_rx; - proc->timestamp_rx = 0; + //ru->ts_offset = proc->timestamp_rx; + //proc->timestamp_rx = 0; } else { samples_per_slot_prev = fp->get_samples_per_slot((*slot-1)%fp->slots_per_frame,fp); @@ -653,13 +654,22 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { } } + //compute system frame number (SFN) according to O-RAN-WG4-CUS.0-v02.00 (using alpha=beta=0) + // this assumes that the USRP has been synchronized to the GPS time + // OAI uses timestamps in sample time stored in int64_t, but it will fit in double precision for many years to come. + double gps_sec = ((double) ts)/cfg->sample_rate; + //proc->frame_rx = ((int64_t) (gps_sec/0.01)) & 1023; + + // in fact the following line is the same as long as the timestamp_rx is synchronized to GPS. proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_subframe*10))&1023; proc->tti_rx = fp->get_slot_from_timestamp(proc->timestamp_rx,fp); // synchronize first reception to frame 0 subframe 0 - LOG_D(PHY,"RU %d/%d TS %llu , frame %d, slot %d.%d / %d\n", + LOG_D(PHY,"RU %d/%d TS %ld, GPS %f, SR %f, frame %d, slot %d.%d / %d\n", ru->idx, 0, - (unsigned long long int)(proc->timestamp_rx+ru->ts_offset), + ts, //(unsigned long long int)(proc->timestamp_rx+ru->ts_offset), + gps_sec, + cfg->sample_rate, proc->frame_rx,proc->tti_rx,proc->tti_tx,fp->slots_per_frame); // dump VCD output for first RU in list diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index 35bc28d9c1..02c366eb03 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -212,12 +212,12 @@ uint32_t get_samples_per_slot(int slot, NR_DL_FRAME_PARMS* fp) uint32_t get_slot_from_timestamp(openair0_timestamp timestamp_rx, NR_DL_FRAME_PARMS* fp) { uint32_t slot_idx = 0; - int samples_till_the_slot = 0; + int samples_till_the_slot = fp->get_samples_per_slot(slot_idx,fp)-1; timestamp_rx = timestamp_rx%fp->samples_per_frame; while (timestamp_rx > samples_till_the_slot) { - samples_till_the_slot += fp->get_samples_per_slot(slot_idx,fp); slot_idx++; + samples_till_the_slot += fp->get_samples_per_slot(slot_idx,fp); } return slot_idx; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 87c1dee1e5..57a7fe7c4d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -69,7 +69,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t ***)gNB->pdcch_pdu_idx[CC_idP]; nfapi_nr_ul_tti_request_t *future_ul_tti_req = - &gNB->UL_tti_req_ahead[CC_idP][(slotP + num_slots - 1) % num_slots]; + &gNB->UL_tti_req_ahead[CC_idP][(slotP+6)]; // + num_slots - 1) % num_slots]; nfapi_nr_ul_dci_request_t *UL_dci_req = &gNB->UL_dci_req[0]; nfapi_nr_tx_data_request_t *TX_req = &gNB->TX_req[0]; @@ -87,7 +87,7 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, UL_dci_req[CC_idP].numPdus = 0; /* advance last round's future UL_tti_req to be ahead of current frame/slot */ - future_ul_tti_req->SFN = (slotP == 0 ? frameP : frameP + 1) % 1024; + future_ul_tti_req->SFN = ((slotP+6SFN, (slotP + num_slots - 1) % num_slots); /* future_ul_tti_req->Slot is fixed! */ future_ul_tti_req->n_pdus = 0; diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 365957cad5..2941b0a5aa 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -203,8 +203,8 @@ static int sync_to_gps(openair0_device *device) { //Set to GPS time uhd::time_spec_t gps_time = uhd::time_spec_t(time_t(s->usrp->get_mboard_sensor("gps_time", mboard).to_int())); - //s->usrp->set_time_next_pps(gps_time+1.0, mboard); - s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + s->usrp->set_time_next_pps(gps_time+1.0, mboard); + //s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); //Wait for it to apply //The wait is 2 seconds because N-Series has a known issue where //the time at the last PPS does not properly update at the PPS edge @@ -215,10 +215,10 @@ static int sync_to_gps(openair0_device *device) { uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(mboard); std::cout << "USRP time: " << (boost::format("%0.9f") % time_last_pps.get_real_secs()) << std::endl; std::cout << "GPSDO time: " << (boost::format("%0.9f") % gps_time.get_real_secs()) << std::endl; - //if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) - // std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; - //else - // std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; + if (gps_time.get_real_secs() == time_last_pps.get_real_secs()) + std::cout << std::endl << "SUCCESS: USRP time synchronized to GPS time" << std::endl << std::endl; + else + std::cerr << std::endl << "ERROR: Failed to synchronize USRP time to GPS time" << std::endl << std::endl; } if (num_gps_locked == num_mboards and num_mboards > 1) { @@ -293,15 +293,11 @@ static int trx_usrp_start(openair0_device *device) { //s->first_rx = 1; s->rx_timestamp = 0; - s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); - // wait for the pps to change uhd::time_spec_t time_last_pps = s->usrp->get_time_last_pps(); - while (time_last_pps == s->usrp->get_time_last_pps()) { - boost::this_thread::sleep(boost::posix_time::milliseconds(1)); - } + LOG_I(HW,"last pps at %f, starting streaming at %f\n",time_last_pps.get_real_secs(),time_last_pps.get_real_secs()+1.0); uhd::stream_cmd_t cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS); - cmd.time_spec = uhd::time_spec_t(1.0); + cmd.time_spec = uhd::time_spec_t(time_last_pps+1.0); cmd.stream_now = false; // start at constant delay s->rx_stream->issue_stream_cmd(cmd); @@ -1103,12 +1099,16 @@ extern "C" { LOG_I(HW,"USRP fails to sync with GPS. Exiting.\n"); exit(EXIT_FAILURE); } - } else if (s->usrp->get_clock_source(0) == "external") { - if (check_ref_locked(s,0)) { - LOG_I(HW,"USRP locked to external reference!\n"); - } else { - LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); - exit(EXIT_FAILURE); + } else { + s->usrp->set_time_next_pps(uhd::time_spec_t(0.0)); + + if (s->usrp->get_clock_source(0) == "external") { + if (check_ref_locked(s,0)) { + LOG_I(HW,"USRP locked to external reference!\n"); + } else { + LOG_I(HW,"Failed to lock to external reference. Exiting.\n"); + exit(EXIT_FAILURE); + } } } @@ -1322,7 +1322,7 @@ extern "C" { LOG_I(HW,"Actual master clock: %fMHz...\n",s->usrp->get_master_clock_rate()/1e6); LOG_I(HW,"Actual clock source %s...\n",s->usrp->get_clock_source(0).c_str()); LOG_I(HW,"Actual time source %s...\n",s->usrp->get_time_source(0).c_str()); - sleep(1); + // create tx & rx streamer uhd::stream_args_t stream_args_rx("sc16", "sc16"); int samples=openair0_cfg[0].sample_rate;