diff --git a/matlab/tests/prach_detect_test.m b/matlab/tests/prach_detect_test.m index 21b9df284..7a2fc1802 100644 --- a/matlab/tests/prach_detect_test.m +++ b/matlab/tests/prach_detect_test.m @@ -1,22 +1,23 @@ %% PRACH Detection Conformance Test -clear +%clear -d=18;%linspace(4,14,6); +d=50;%linspace(4,14,6); pDetection2 = zeros(2,length(d)); for dd=1:length(d) detect_factor=d(dd); -numSubframes = 75; % Number of subframes frames to simulate at each SNR -SNRdB = linspace(-14,10,8); % SNR points to simulate -foffset = 300.0; % Frequency offset in Hertz -add_fading=true; +numSubframes = 1; % Number of subframes frames to simulate at each SNR +SNRdB = 10;%linspace(-14,10,8); % SNR points to simulate +foffset = 0.0; % Frequency offset in Hertz +delay=0; +add_fading=false; addpath('../../build/srslte/lib/phch/test') %% UE Configuration % User Equipment (UE) settings are specified in the structure |ue|. -ue.NULRB = 100; % 6 Resource Blocks +ue.NULRB = 15; % 6 Resource Blocks ue.DuplexMode = 'FDD'; % Frequency Division Duplexing (FDD) ue.CyclicPrefixUL = 'Normal'; % Normal cyclic prefix length ue.NTxAnts = 1; % Number of transmission antennas @@ -25,8 +26,7 @@ ue.NTxAnts = 1; % Number of transmission antennas prach.Format = 0; % PRACH format: TS36.104, Table 8.4.2.1-1 prach.HighSpeed = 0; % Normal mode: TS36.104, Table 8.4.2.1-1 -prach.FreqOffset = 0; % Default frequency location - +prach.FreqOffset = 4; % Default frequency location info = ltePRACHInfo(ue, prach); % PRACH information %% Propagation Channel Configuration @@ -67,9 +67,9 @@ for nSNR = 1:length(SNRdB) % Loop for each subframe for nsf = 1:numSubframes - prach.SeqIdx = randi(838,1,1)-1; % Logical sequence index: TS36.141, Table A.6-1 - prach.CyclicShiftIdx = randi(16,1,1)-1; % Cyclic shift index: TS36.141, Table A.6-1 - prach.PreambleIdx = randi(64,1,1)-1; % Preamble index: TS36.141, Table A.6-1 + prach.SeqIdx = 0;%randi(838,1,1)-1; % Logical sequence index: TS36.141, Table A.6-1 + prach.CyclicShiftIdx = 11;%randi(16,1,1)-1; % Cyclic shift index: TS36.141, Table A.6-1 + prach.PreambleIdx = 1;%randi(64,1,1)-1; % Preamble index: TS36.141, Table A.6-1 info = ltePRACHInfo(ue, prach); % PRACH information % PRACH transmission @@ -77,8 +77,8 @@ for nSNR = 1:length(SNRdB) ue.NFrame = fix((nsf-1)/10); % Set PRACH timing offset in us as per TS36.141, Figure 8.4.1.4.2-2 - prach.TimingOffset = info.BaseOffset + ue.NSubframe/10.0; - % prach.TimingOffset = 0; + %prach.TimingOffset = info.BaseOffset + ue.NSubframe/10.0; + prach.TimingOffset = 0; % Generate transmit wave [txwave,prachinfo] = ltePRACH(ue, prach); @@ -92,23 +92,30 @@ for nSNR = 1:length(SNRdB) rxwave = txwave; end % Add noise - noise = N*complex(randn(size(rxwave)), randn(size(rxwave))); - rxwave = rxwave + noise; - + %noise = N*complex(randn(size(rxwave)), randn(size(rxwave))); + %rxwave = rxwave + noise; % Remove the implementation delay of the channel modeling if (add_fading) rxwave = rxwave((fadinginfo.ChannelFilterDelay + 1):end, :); end - + + rxwave=x; + % rxwave=[zeros(delay,1); txwave(1:end-delay)]; + % Apply frequency offset t = ((0:size(rxwave, 1)-1)/chcfg.SamplingRate).'; rxwave = rxwave .* repmat(exp(1i*2*pi*foffset*t), ... 1, size(rxwave, 2)); + % PRACH detection for all cell preamble indices [detected, offsets] = ltePRACHDetect(ue, prach, rxwave, (0:63).'); - [detected_srs, offsets_srs] = srslte_prach_detect(ue, prach, rxwave, detect_factor); + [detected_srs, offsets_srs, corrout] = srslte_prach_detect(ue, prach, rxwave, detect_factor); + + disp(detected) + disp(detected_srs) + disp(offsets_srs*1e6) % Test for preamble detection if (length(detected)==1) @@ -144,7 +151,7 @@ for nSNR = 1:length(SNRdB) % Calculate timing estimation error. The true offset is % PRACH offset plus channel delay trueOffset = prach.TimingOffset/1e6 + 310e-9; - measuredOffset = offsets_srs(1)/1e6; + measuredOffset = offsets_srs(1); timingerror = abs(measuredOffset-trueOffset); % Test for acceptable timing error @@ -189,3 +196,4 @@ else fprintf('Pdet=%.4f%%, Pdet_srs=%.4f%%\n',pDetection(1,nSNR),pDetection(2,nSNR)) end +plot(corrout) diff --git a/srslte/examples/pdsch_ue.c b/srslte/examples/pdsch_ue.c index 026cdbbcd..b0a9c5fd6 100644 --- a/srslte/examples/pdsch_ue.c +++ b/srslte/examples/pdsch_ue.c @@ -500,7 +500,6 @@ int main(int argc, char **argv) { decode_pdsch = false; } } - if (decode_pdsch) { INFO("Attempting DL decode SFN=%d\n", sfn); if (prog_args.rnti != SRSLTE_SIRNTI) { @@ -509,7 +508,6 @@ int main(int argc, char **argv) { // RV for SIB1 is predefined uint32_t k = (sfn/2)%4; uint32_t rv = ((uint32_t) ceilf((float)1.5*k))%4; - n = srslte_ue_dl_decode_rnti_rv(&ue_dl, &sf_buffer[prog_args.time_offset], data, srslte_ue_sync_get_sfidx(&ue_sync), SRSLTE_SIRNTI, rv); diff --git a/srslte/include/srslte/enb/enb_dl.h b/srslte/include/srslte/enb/enb_dl.h index 4b6514a43..7f3b034e0 100644 --- a/srslte/include/srslte/enb/enb_dl.h +++ b/srslte/include/srslte/enb/enb_dl.h @@ -86,7 +86,6 @@ typedef struct SRSLTE_API { cf_t pss_signal[SRSLTE_PSS_LEN]; float sss_signal0[SRSLTE_SSS_LEN]; float sss_signal5[SRSLTE_SSS_LEN]; - uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; uint32_t nof_rnti; diff --git a/srslte/include/srslte/enb/enb_ul.h b/srslte/include/srslte/enb/enb_ul.h index f3c320f15..bd1f0c908 100644 --- a/srslte/include/srslte/enb/enb_ul.h +++ b/srslte/include/srslte/enb/enb_ul.h @@ -122,7 +122,8 @@ SRSLTE_API int srslte_enb_ul_detect_prach(srslte_enb_ul_t *q, uint32_t freq_offset, cf_t *signal, uint32_t *indices, - uint32_t *offsets); + float *offsets, + float *peak2avg); #endif diff --git a/srslte/include/srslte/phch/prach.h b/srslte/include/srslte/phch/prach.h index d52b9714d..de2085317 100644 --- a/srslte/include/srslte/phch/prach.h +++ b/srslte/include/srslte/phch/prach.h @@ -64,6 +64,7 @@ typedef struct SRSLTE_API { uint32_t N_zc; // PRACH sequence length uint32_t N_cs; // Cyclic shift size uint32_t N_seq; // Preamble length + float T_seq; // Preamble length in seconds uint32_t N_cp; // Cyclic prefix length // Generated tables @@ -153,7 +154,8 @@ SRSLTE_API int srslte_prach_detect_offset(srslte_prach_t *p, cf_t *signal, uint32_t sig_len, uint32_t *indices, - uint32_t *offsets, + float *t_offsets, + float *peak_to_avg, uint32_t *ind_len); SRSLTE_API void srslte_prach_set_detect_factor(srslte_prach_t *p, diff --git a/srslte/lib/enb/enb_dl.c b/srslte/lib/enb/enb_dl.c index 2958b74f6..db4fbdd9d 100644 --- a/srslte/lib/enb/enb_dl.c +++ b/srslte/lib/enb/enb_dl.c @@ -175,9 +175,11 @@ void srslte_enb_dl_put_refs(srslte_enb_dl_t *q, uint32_t sf_idx) void srslte_enb_dl_put_mib(srslte_enb_dl_t *q, uint32_t tti) { + uint8_t bch_payload[SRSLTE_BCH_PAYLOAD_LEN]; + if ((tti%10) == 0) { - srslte_pbch_mib_pack(&q->cell, tti/10, q->bch_payload); - srslte_pbch_encode(&q->pbch, q->bch_payload, q->slot1_symbols, ((tti/10)%4)); + srslte_pbch_mib_pack(&q->cell, tti/10, bch_payload); + srslte_pbch_encode(&q->pbch, bch_payload, q->slot1_symbols, ((tti/10)%4)); } } @@ -237,13 +239,16 @@ int srslte_enb_dl_put_pdcch_dl(srslte_enb_dl_t *q, srslte_ra_dl_dci_t *grant, if (rnti == SRSLTE_SIRNTI || rnti == SRSLTE_PRNTI || (rnti >= SRSLTE_RARNTI_START && rnti <= SRSLTE_RARNTI_END)) { rnti_is_user = false; } - //srslte_ra_pdsch_fprint(stdout, grant, q->cell.nof_prb); srslte_dci_msg_pack_pdsch(grant, &dci_msg, format, q->cell.nof_prb, rnti_is_user); - //srslte_vec_fprint_hex(stdout, dci_msg.data, dci_msg.nof_bits); if (srslte_pdcch_encode(&q->pdcch, &dci_msg, location, rnti, q->sf_symbols, sf_idx, q->cfi)) { fprintf(stderr, "Error encoding DCI message\n"); return SRSLTE_ERROR; } +/* printf("format: %s, sf_idx=%d, rnti=%d, location=%d,%d, cfi=%d\n", + srslte_dci_format_string(format), sf_idx, rnti, location.L, location.ncce, q->cfi); + srslte_ra_pdsch_fprint(stdout, grant, q->cell.nof_prb); + srslte_vec_fprint_hex(stdout, dci_msg.data, dci_msg.nof_bits); +*/ return SRSLTE_SUCCESS; } diff --git a/srslte/lib/enb/enb_ul.c b/srslte/lib/enb/enb_ul.c index 04de01a63..e3732b8ce 100644 --- a/srslte/lib/enb/enb_ul.c +++ b/srslte/lib/enb/enb_ul.c @@ -83,6 +83,8 @@ int srslte_enb_ul_init(srslte_enb_ul_t *q, srslte_cell_t cell, fprintf(stderr, "Error initiating PRACH\n"); goto clean_exit; } + + srslte_prach_set_detect_factor(&q->prach, 60); if (srslte_chest_ul_init(&q->chest, cell)) { fprintf(stderr, "Error initiating channel estimator\n"); @@ -177,18 +179,20 @@ int srslte_enb_ul_get_pusch(srslte_enb_ul_t *q, srslte_ra_ul_grant_t *grant, srs int srslte_enb_ul_detect_prach(srslte_enb_ul_t *q, uint32_t tti, uint32_t freq_offset, cf_t *signal, - uint32_t *indices, uint32_t *offsets) + uint32_t *indices, float *offsets, float *peak2avg) { uint32_t nof_detected_prach = 0; // consider the number of subframes the transmission must be anticipated if (srslte_prach_tti_opportunity(&q->prach, tti, -1)) { + if (srslte_prach_detect_offset(&q->prach, freq_offset, &signal[q->prach.N_cp], SRSLTE_SF_LEN_PRB(q->cell.nof_prb), indices, offsets, + peak2avg, &nof_detected_prach)) { fprintf(stderr, "Error detecting PRACH\n"); diff --git a/srslte/lib/modem/mod.c b/srslte/lib/modem/mod.c index 9d20bbf40..309a92f43 100644 --- a/srslte/lib/modem/mod.c +++ b/srslte/lib/modem/mod.c @@ -50,7 +50,7 @@ int srslte_mod_modulate(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, u } return j; } - + void mod_bpsk_bytes(srslte_modem_table_t* q, uint8_t *bits, cf_t* symbols, uint32_t nbits) { uint8_t mask_bpsk[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; uint8_t shift_bpsk[8] = {7, 6, 5, 4, 3, 2, 1, 0}; diff --git a/srslte/lib/phch/pbch.c b/srslte/lib/phch/pbch.c index 42d710340..4c5416ab3 100644 --- a/srslte/lib/phch/pbch.c +++ b/srslte/lib/phch/pbch.c @@ -292,8 +292,10 @@ void srslte_pbch_mib_unpack(uint8_t *msg, srslte_cell_t *cell, uint32_t *sfn) { /** Unpacks MIB from PBCH message. * msg buffer must be 24 byte length at least */ -void srslte_pbch_mib_pack(srslte_cell_t *cell, uint32_t sfn, uint8_t *msg) { +void srslte_pbch_mib_pack(srslte_cell_t *cell, uint32_t sfn, uint8_t *payload) { int bw, phich_res = 0; + + uint8_t *msg = payload; bzero(msg, 24); @@ -325,6 +327,7 @@ void srslte_pbch_mib_pack(srslte_cell_t *cell, uint32_t sfn, uint8_t *msg) { } srslte_bit_unpack(phich_res, &msg, 2); srslte_bit_unpack(sfn >> 2, &msg, 8); + } void srslte_pbch_decode_reset(srslte_pbch_t *q) { diff --git a/srslte/lib/phch/prach.c b/srslte/lib/phch/prach.c index 128de1860..cf47babc5 100644 --- a/srslte/lib/phch/prach.c +++ b/srslte/lib/phch/prach.c @@ -32,10 +32,10 @@ #include "srslte/utils/debug.h" #include "srslte/utils/vector.h" +float save_corr[4096]; //PRACH detection threshold is PRACH_DETECT_FACTOR*average #define PRACH_DETECT_FACTOR 18 -#define CFO_REPLICA_FACTOR 0.3 #define N_SEQS 64 // Number of prach sequences available #define N_RB_SC 12 // Number of subcarriers per resource block @@ -440,8 +440,9 @@ int srslte_prach_init(srslte_prach_t *p, srslte_dft_plan_set_norm(p->fft, false); p->N_seq = prach_Tseq[p->f]*p->N_ifft_ul/2048; - p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048; - + p->N_cp = prach_Tcp[p->f]*p->N_ifft_ul/2048; + p->T_seq = prach_Tseq[p->f]*SRSLTE_LTE_TS; + ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid parameters\n"); @@ -506,7 +507,7 @@ int srslte_prach_detect(srslte_prach_t *p, uint32_t *indices, uint32_t *n_indices) { - return srslte_prach_detect_offset(p, freq_offset, signal, sig_len, indices, NULL, n_indices); + return srslte_prach_detect_offset(p, freq_offset, signal, sig_len, indices, NULL, NULL, n_indices); } int srslte_prach_detect_offset(srslte_prach_t *p, @@ -514,7 +515,8 @@ int srslte_prach_detect_offset(srslte_prach_t *p, cf_t *signal, uint32_t sig_len, uint32_t *indices, - uint32_t *offsets, + float *t_offsets, + float *peak_to_avg, uint32_t *n_indices) { int ret = SRSLTE_ERROR; @@ -525,7 +527,7 @@ int srslte_prach_detect_offset(srslte_prach_t *p, { if(sig_len < p->N_ifft_prach){ - fprintf(stderr, "srslte_prach_detect: Signal is not of length %d", p->N_ifft_prach); + fprintf(stderr, "srslte_prach_detect: Signal length is %d and should be %d\n", sig_len, p->N_ifft_prach); return SRSLTE_ERROR_INVALID_INPUTS; } @@ -562,7 +564,6 @@ int srslte_prach_detect_offset(srslte_prach_t *p, uint32_t n_wins = p->N_zc/winsize; float max_peak = 0; - for(int j=0;jN_zc-(j*p->N_cs))%p->N_zc; uint32_t end = start+winsize; @@ -583,12 +584,20 @@ int srslte_prach_detect_offset(srslte_prach_t *p, } if (max_peak > p->detect_factor*corr_ave) { for (int j=0;jpeak_values[j] > p->detect_factor*corr_ave && - p->peak_values[j] >= CFO_REPLICA_FACTOR*max_peak) + if(p->peak_values[j] > p->detect_factor*corr_ave) { - indices[*n_indices] = (i*n_wins)+j; - if (offsets) { - offsets[*n_indices] = p->peak_offsets[j]; + printf("ncs=%d, nzc=%d, nwins=%d, Nroot=%d, i=%d, j=%d, start=%d, peak_value=%f, peak_offset=%d, tseq=%f\n", + p->N_cs, p->N_zc, n_wins, p->N_roots, i, j, (p->N_zc-(j*p->N_cs))%p->N_zc, p->peak_values[j], + p->peak_offsets[j], p->T_seq*1e6); + memcpy(save_corr, p->corr, p->N_zc*sizeof(float)); + if (indices) { + indices[*n_indices] = (i*n_wins)+j; + } + if (peak_to_avg) { + peak_to_avg[*n_indices] = p->peak_values[j]/corr_ave; + } + if (t_offsets) { + t_offsets[*n_indices] = (float) p->peak_offsets[j]*p->T_seq/p->N_zc; } (*n_indices)++; } diff --git a/srslte/lib/phch/test/prach_detect_test_mex.c b/srslte/lib/phch/test/prach_detect_test_mex.c index 0ab7e45fe..bfec8c23a 100644 --- a/srslte/lib/phch/test/prach_detect_test_mex.c +++ b/srslte/lib/phch/test/prach_detect_test_mex.c @@ -29,6 +29,8 @@ #include "srslte/srslte.h" #include "srslte/mex/mexutils.h" +extern float save_corr[4096]; + /** MEX function to be called from MATLAB to test the channel estimator */ @@ -85,7 +87,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexutils_read_uint32_struct(PRACHCFG, "FreqOffset", &frequency_offset); srslte_prach_t prach; - if (srslte_prach_init(&prach, N_ifft_ul, preamble_format, root_seq_idx, high_speed_flag, zero_corr_zone)) { + if (srslte_prach_init(&prach, N_ifft_ul, preamble_format*16, root_seq_idx, high_speed_flag, zero_corr_zone)) { mexErrMsgTxt("Error initiating PRACH\n"); return; } @@ -94,7 +96,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) int nof_samples = mexutils_read_cf(INPUT, &input_signal); uint32_t preambles[64]; - uint32_t offsets[64]; + float offsets[64]; uint32_t nof_detected = 0; if (nrhs > NOF_INPUTS) { @@ -102,7 +104,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) srslte_prach_set_detect_factor(&prach, factor); } - if (srslte_prach_detect_offset(&prach, frequency_offset, &input_signal[prach.N_cp], nof_samples, preambles, offsets, &nof_detected)) { + if (srslte_prach_detect_offset(&prach, frequency_offset, &input_signal[prach.N_cp], nof_samples, preambles, offsets, NULL, &nof_detected)) { mexErrMsgTxt("Error detecting PRACH\n"); return; } @@ -111,7 +113,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexutils_write_int((int*) preambles, &plhs[0], nof_detected, 1); } if (nlhs >= 2) { - mexutils_write_int((int*) offsets, &plhs[1], nof_detected, 1); + mexutils_write_f(offsets, &plhs[1], nof_detected, 1); + } + if (nlhs >= 3) { + mexutils_write_f(save_corr, &plhs[2], prach.N_zc, 1); } free(input_signal); diff --git a/srslte/lib/phch/test/prach_test_mex.c b/srslte/lib/phch/test/prach_test_mex.c index 0d0ac0e9c..54af0ab60 100644 --- a/srslte/lib/phch/test/prach_test_mex.c +++ b/srslte/lib/phch/test/prach_test_mex.c @@ -82,7 +82,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexutils_read_uint32_struct(PRACHCFG, "FreqOffset", &frequency_offset); srslte_prach_t prach; - if (srslte_prach_init(&prach, N_ifft_ul, preamble_format, root_seq_idx, high_speed_flag, zero_corr_zone)) { + if (srslte_prach_init(&prach, N_ifft_ul, preamble_format*16, root_seq_idx, high_speed_flag, zero_corr_zone)) { mexErrMsgTxt("Error initiating PRACH\n"); return; } diff --git a/srslte/lib/phch/test/prach_test_usrp.c b/srslte/lib/phch/test/prach_test_usrp.c index e9f266389..acdaf1947 100644 --- a/srslte/lib/phch/test/prach_test_usrp.c +++ b/srslte/lib/phch/test/prach_test_usrp.c @@ -44,12 +44,13 @@ uint32_t preamble_format = 0; uint32_t root_seq_idx = 0; uint32_t seq_idx = 0; uint32_t frequency_offset = 0; -uint32_t zero_corr_zone = 0; +uint32_t zero_corr_zone = 11; +uint32_t timeadv = 0; uint32_t nof_frames = 20; float uhd_gain=40, uhd_freq=2.4e9; char *uhd_args=""; -char *output_filename = NULL; +char *output_filename = "prach_rx"; void usage(char *prog) { printf("Usage: %s \n", prog); @@ -58,15 +59,17 @@ void usage(char *prog) { printf("\t-g UHD TX/RX gain [Default %.1f dB]\n", uhd_gain); printf("\t-p Number of UL RB [Default %d]\n", nof_prb); printf("\t-F Preamble format [Default %d]\n", preamble_format); + printf("\t-O Frequency offset [Default %d]\n", frequency_offset); printf("\t-s sequence index [Default %d]\n", seq_idx); printf("\t-r Root sequence index [Default %d]\n", root_seq_idx); + printf("\t-t Time advance (us) [Default %d]\n", timeadv); printf("\t-z Zero correlation zone config [Default %d]\n", zero_corr_zone); printf("\t-o Save transmitted PRACH in file [Default no]\n"); } void parse_args(int argc, char **argv) { int opt; - while ((opt = getopt(argc, argv, "apfFgrsoz")) != -1) { + while ((opt = getopt(argc, argv, "apfFgrstoPOz")) != -1) { switch (opt) { case 'a': uhd_args = argv[optind]; @@ -80,6 +83,15 @@ void parse_args(int argc, char **argv) { case 'g': uhd_gain = atof(argv[optind]); break; + case 'P': + preamble_format = atoi(argv[optind]); + break; + case 'O': + frequency_offset = atoi(argv[optind]); + break; + case 't': + timeadv = atoi(argv[optind]); + break; case 'p': nof_prb = atoi(argv[optind]); if (!srslte_nofprb_isvalid(nof_prb)) { @@ -123,7 +135,8 @@ int main(int argc, char **argv) { high_speed_flag, zero_corr_zone); - uint32_t flen = srslte_sampling_freq_hz(nof_prb)/1000; + int srate = srslte_sampling_freq_hz(nof_prb); + uint32_t flen = srate/1000; printf("Generating PRACH\n"); bzero(preamble, flen*sizeof(cf_t)); @@ -133,7 +146,7 @@ int main(int argc, char **argv) { preamble); - uint32_t prach_len = p->N_seq; + uint32_t prach_len = p->N_seq+p->N_cp; srslte_vec_save_file("generated",preamble,prach_len*sizeof(cf_t)); @@ -147,11 +160,27 @@ int main(int argc, char **argv) { exit(-1); } printf("Subframe len: %d samples\n", flen); - printf("Set TX/RX rate: %.2f MHz\n", srslte_rf_set_rx_srate(&uhd, srslte_sampling_freq_hz(nof_prb)) / 1000000); - printf("Set RX gain: %.1f dB\n", srslte_rf_set_rx_gain(&uhd, uhd_gain)); - printf("Set TX gain: %.1f dB\n", srslte_rf_set_tx_gain(&uhd, uhd_gain)); - printf("Set TX/RX freq: %.2f MHz\n", srslte_rf_set_rx_freq(&uhd, uhd_freq) / 1000000); - srslte_rf_set_tx_srate(&uhd, srslte_sampling_freq_hz(nof_prb)); + printf("Set RX gain: %.1f dB\n", uhd_gain); + printf("Set TX gain: %.1f dB\n", 20+uhd_gain); + printf("Set TX/RX freq: %.2f MHz\n", uhd_freq/ 1000000); + + srslte_rf_set_rx_gain(&uhd, uhd_gain); + srslte_rf_set_tx_gain(&uhd, 10+uhd_gain); + srslte_rf_set_rx_freq(&uhd, uhd_freq); + srslte_rf_set_tx_freq(&uhd, uhd_freq); + + if (srate < 10e6) { + srslte_rf_set_master_clock_rate(&uhd, 4*srate); + } else { + srslte_rf_set_master_clock_rate(&uhd, srate); + } + printf("Setting sampling rate %.2f MHz\n", (float) srate/1000000); + float srate_rf = srslte_rf_set_rx_srate(&uhd, (double) srate); + if (srate_rf != srate) { + fprintf(stderr, "Could not set sampling rate\n"); + exit(-1); + } + srslte_rf_set_tx_srate(&uhd, (double) srate); sleep(1); cf_t *zeros = calloc(sizeof(cf_t),flen); @@ -171,7 +200,7 @@ int main(int argc, char **argv) { srslte_rf_recv_with_time(&uhd, &buffer[flen*nframe], flen, true, &tstamp.full_secs, &tstamp.frac_secs); nframe++; if (nframe==9 || nframe==8) { - srslte_timestamp_add(&tstamp, 0, 2e-3); + srslte_timestamp_add(&tstamp, 0, 2e-3-timeadv*1e-6); if (nframe==8) { srslte_rf_send_timed2(&uhd, zeros, flen, tstamp.full_secs, tstamp.frac_secs, true, false); printf("Transmitting zeros\n"); @@ -183,7 +212,7 @@ int main(int argc, char **argv) { } if (f) { - fwrite(&buffer[10*flen], flen*sizeof(cf_t), 1, f); + fwrite(buffer, 11*flen*sizeof(cf_t), 1, f); } if (f) { fclose(f);