fixing "making SFN dependent on GPS time"

in fact it syncs the USRP time to GPS time when available and then derives the SFN from the USRP time.
a side effect is that now SFN does not necessarily start at 0 and this also required other changes
 - initialization of the future_ul_tti_request.
 - fixing a bug in get_samples_per_slot
This commit is contained in:
Florian Kaltenberger
2022-04-06 17:40:14 +02:00
parent 5b22d94d37
commit 367ad780a4
4 changed files with 37 additions and 27 deletions
+14 -4
View File
@@ -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
+2 -2
View File
@@ -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;
}
+2 -2
View File
@@ -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+6<num_slots) ? frameP : frameP + 1) % 1024;
LOG_D(MAC,"Future_ul_tti SFN = %d for slot %d \n", future_ul_tti_req->SFN, (slotP + num_slots - 1) % num_slots);
/* future_ul_tti_req->Slot is fixed! */
future_ul_tti_req->n_pdus = 0;
+19 -19
View File
@@ -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;