|
| id | following:sounding:http:LICENSE:http: (id Implicit,[sounding] use beamweights computed in step2 License,[http] c SOURCE,[LICENSE] id,[http] id all) |
| |
| Scale for Tx | waveform ([0:1]) % OFDM params SC_IND_PILOTS |
| |
| id | N_ZPAD_POST () |
| |
| Number of data | symbols (one per data-bearing subcarrier per OFDM symbol) N_DATA_SC |
| |
| Modulation | order (2/4/16/64=BSPK/QPSK/16-QAM/64-QAM) % Rx processing params RECIP_PLOT=0 |
| |
| Number of CP samples to use in | FFT (on average) %% Define the preamble % LTS for fine CFO and channel estimation lts_f |
| |
| | ceil (N_BS_NODE/2) |
| |
| | bs_index (REF_ANT) |
| |
| | rx_cal_data_start (REF_ANT) |
| |
| if WIRED_UE | pilot_data_start (:) |
| |
| | dl_data_start (:) |
| |
| | rx_cal_data_start (:) |
| |
| end | precoding_in_mat (SC_IND_DATA, N_PILOTS_SYMS+1:end) |
| |
| | precoding_in_mat (SC_IND_PILOTS, N_PILOTS_SYMS+1:end) |
| |
| | recip_tx (nid+(nid >=REF_ANT), first:last) |
| |
| | recip_tx (REF_ANT, first:last) |
| |
| | uplink_pilot_tx (start_index+1:start_index+N_SYM_SAMP) |
| |
| initialize UE node_bs | sdrsync () |
| |
| Synchronize delays only for BS node_bs | sdrrxsetup () |
| |
| node_bs | sdr_setupbeacon () |
| |
| Burn beacon to the BS RAM node_ue | sdr_configgainctrl () |
| |
| end node_bs | set_tddconfig_single (1, schedule, i) |
| |
| configure the N_ZPAD_PRE | recip_tx (i, :) zeros(1 |
| |
| node_bs | sdrtx_single (tx_signal, i) |
| |
| Burn data to the UE RAM end node_bs | sdr_activate_rx () |
| |
| | rx_cal_data_start (ibs) |
| |
| | cal_mat (nid, :) |
| |
| end node_bs | set_tddconfig (1, schedule) |
| |
| end node_ue | set_tddconfig (WIRED_UE, ue_ul_sched) |
| |
| configure the N_ZPAD_PRE uplink_pilot_tx | zeros (1, N_ZPAD_POST)] |
| |
| node_ue | sdrtx_single (tx_signal, 1) |
| |
| Burn data to the UE RAM if ~WIRED_UE node_ue | sdr_setcorr () |
| |
| if ~WIRED_UE node_ue | sdr_unsetcorr () |
| |
| | plot (lts_corr) |
| |
| 'UPLINK PILOT COLLECTION:No LTS Correlation Peaks Found!\n' | fprintf () |
| |
| Get sSecond peak | pilot_data_start (ibs) |
| |
| | corr_peak_all (ibs) |
| |
| if curr_offset< 0 rx_mat_calibrated_tmp(ibs, 1+abs(curr_offset):end)=rx_vec_pilot(ibs, 1:end-abs(curr_offset));elseif curr_offset > | rx_mat_calibrated_tmp (ibs, 1:end-curr_offset) |
| |
| else | rx_mat_calibrated_tmp (ibs, :) |
| |
| if pilotEnd | length (rx_vec_pilot) display('Bad Uplink Pilot(RX)') |
| |
| end | uplink_pilot_rx (ibs, :) |
| |
| | rx_fft (irp, :) |
| |
| end | uplink_pilot_csi (ibs, :) |
| |
| | tx_pilot_mat (ibs, :) |
| |
| | tx_payload_mat (ibs, :, isym-N_PILOTS_SYMS) |
| |
| Add preamble to one antenna for | sync (workaround to offset from beamformed preamble) syncSeq |
| |
| | syncSeq (1, :) |
| |
| | plot (abs(tx_vec_iris)) node_bs.sdrtx_single(tx_vec_iris |
| |
| activate reading stream node_bs | sdrtrigger () |
| |
| read data | rx_vec_dl (:, :) |
| |
| | fprintf ('Downlink Beacon Successful at UE %d \n', j) |
| |
| else | fprintf ('WARNING:NO Downlink Beacon Detected at UE %d \n', j) |
| |
| end end | if (all_ue_rx==N_UE_NODE) rx_vec_downlink |
| |
| use size of lts_t Stop if no valid correlation peak was found | if (isempty(lts_second_peak_index)) bad_cnt |
| |
| | fprintf ('DOWNLINK TRAINING:No LTS Correlation Peaks Found! Count:%d \n', bad_cnt) |
| |
| | fprintf ('CORR. PEAK AT:%d, PILOT STARTS AT:%d \n', offset-1, dl_pilot_start) |
| |
| end Another correlation | method (similar performance to code above)... if 0 lts_rep_dl |
| |
| lts | length () |
| |
| | fprintf ('CORR. ALT. PEAK AT:%d \n', max_idx_dl) |
| |
|
| if ~isloaded pyversion usr bin python py print() %weird bug where py isn 't loaded in an external script end py.importlib.import_module( 'iris_py') % Params Enable writing plots to PNG Iris | params = pyversion |
| |
| | WIRED_UE = 0 |
| |
| | TX_FRQ = 3.6e9 |
| |
| | RX_FRQ = TX_FRQ |
| |
| | TX_GN = 80 |
| |
| | RX_GN = 70 |
| |
| | SMPL_RT = 5e6 |
| |
| | N_FRM = 1 |
| |
| | bs_ids = string.empty() |
| |
| | bs_sched = string.empty() |
| |
| | ue_sched = string.empty() |
| |
| Waveform params | TX_SCALE = 1 |
| |
| Pilot subcarrier indices | SC_IND_DATA = [2:7 9:21 23:27 39:43 45:57 59:64] |
| |
| Data subcarrier indices | SC_IND_DATA_PILOT = [2:27 39:64]' |
| |
| | N_SC = 64 |
| |
| Number of subcarriers | CP_LEN = 16 |
| |
| Cyclic prefix length | N_SYM_SAMP = N_SC + CP_LEN |
| |
| Number of samples that will go over the air | N_SAMP = 4096 |
| |
| | N_ZPAD_PRE = 160 |
| |
| Number of OFDM symbols for | burst |
| |
| Number of OFDM symbols for it needs to be less than | N_PILOTS_SYMS = 2 |
| |
| | N_DATA_SYMS = (N_OFDM_SYMS - N_PILOTS_SYMS) |
| |
| | MOD_ORDER = 4 |
| |
| | PILOT_PLOT = 1 |
| |
| | DOWNLINK_PLOT = 1 |
| |
| | AUTO_OFFSET = 1 |
| |
| | FFT_OFFSET = 0 |
| |
| | lts_t = ifft(lts_f, 64) |
| |
| time domain | lts = [lts_t(49:64) lts_t] |
| |
| | lts_lcp = [lts_t(33:64) lts_t lts_t] |
| |
| LTS Init Iris nodes Set up the Iris experiment Create BS Hub and UE objects | Note |
| |
| else | hub_id = [] |
| |
| end Last node in list is calibration node | ! bs_ids = ["RF3E000674", "RF3E000704", "RF3E000676", "RF3E000668", "RF3E000157"] |
| |
| | ue_ids = ["RF3E000119"] |
| |
| | beacon_node = 0 |
| |
| set to make all nodes send beacon | ref_calib_sched = "RGPG" |
| |
| | bs_calib_sched = "PGRG" |
| |
| | bs_ul_sched_beacon = "BGRG" |
| |
| | bs_ul_sched = "GGRG" |
| |
| | ue_ul_sched = "GGPG" |
| |
| | bs_dl_sched_beacon = "BGPG" |
| |
| | bs_dl_sched = "GGPG" |
| |
| | ue_dl_sched = "GGRG" |
| |
| | N_BS_NODE = length(bs_ids) |
| |
| | N_UE_NODE = 1 |
| |
| | REF_ANT = N_BS_NODE |
| |
| | bs_index = 1:N_BS_NODE |
| |
| Manually measured offsets for the start of data | rx_cal_data_start = 168 * ones(1, N_BS_NODE) |
| |
| | pilot_data_start = 150 * ones(1, N_BS_NODE) |
| |
| | dl_data_start = 305 |
| |
| end Generate a payload of random integers | tx_data = randi(MOD_ORDER, 1, N_DATA_SC) - 1 |
| |
| | tx_syms = mod_sym(tx_data, MOD_ORDER) |
| |
| Reshape the symbol vector to a matrix with one column per OFDM symbol | tx_syms_mat = reshape(tx_syms, length(SC_IND_DATA), N_DATA_SYMS) |
| |
| Define the pilot tone values as BPSK symbols | pilots = [1 1 -1 1].' |
| |
| Repeat the pilots across all OFDM symbols | pilots_mat = repmat(pilots, 1, N_DATA_SYMS) |
| |
| Construct the precoding input matrix | precoding_in_mat = zeros(N_SC, N_OFDM_SYMS) |
| |
| Insert the data and pilot | values |
| |
| other subcarriers will remain at for | i |
| |
| reciprocity calibration tx pilots | N_BS = N_BS_NODE - 1 |
| |
| | DATA_REP = floor(N_OFDM_SYMS / N_BS) |
| |
| | lts_rep = repmat(lts, 1, DATA_REP) |
| |
| | lts_rep_len = DATA_REP * N_SYM_SAMP |
| |
| | data_len = N_BS * lts_rep_len |
| |
| | recip_tx = zeros(N_BS_NODE, data_len) |
| |
| for | nid |
| |
| | last = nid * lts_rep_len |
| |
| end uplink tx piltos | UE_DATA_REP = N_OFDM_SYMS |
| |
| | ue_pilot_len = UE_DATA_REP * N_SYM_SAMP |
| |
| | uplink_pilot_tx = zeros(1, ue_pilot_len) |
| |
| for | rp |
| |
| end Iris nodes parameters | bs_sdr_params |
| |
| | ue_sdr_params = bs_sdr_params |
| |
| ue_sdr_params | id = ue_ids |
| |
| ue_sdr_params | n_sdrs = N_UE_NODE |
| |
| ue_sdr_params | tdd_sched = ue_sched |
| |
| ue_sdr_params | is_bs = 0 |
| |
| | node_bs = iris_py(bs_sdr_params, hub_id) |
| |
| initialize BS | node_ue = iris_py(ue_sdr_params, []) |
| |
| Step | __pad4__ |
| |
| | schedule = bs_calib_sched |
| |
| configure the | BS |
| |
| configure the N_ZPAD_PRE | recip_postfix_len |
| |
| activate reading | stream [rx_vec_iris, ~] = node_bs.sdrrx(N_SAMP) |
| |
| read data | a = 1 |
| |
| | unos = ones(size(conj(lts))) |
| |
| default offsets measured with prefix and | postfix |
| |
| | v1 = filter(unos, a, abs(rx_vec_iris(ibs, end - DATA_REP * N_SYM_SAMP: end)) .^ 2) |
| |
| | lts_corr = (abs(v0) .^ 2) ./ v1 |
| |
| normalized correlation position of the last | peak [~, max_idx] = max(abs(lts_corr)) |
| |
| | break |
| |
| end end end | recip_rx = zeros(N_BS_NODE, data_len) |
| |
| | rx_fft = zeros(N_BS, N_SC) |
| |
| | rx_fft_ref = zeros(N_BS, N_SC) |
| |
| | cal_mat = zeros(N_BS_NODE, N_SC) |
| |
| | first = rx_cal_data_start(REF_ANT) |
| |
| | recip_rx_ref = rx_vec_iris(REF_ANT, first:last) |
| |
| | recip_rx_ref_mat = reshape(recip_rx_ref, N_SYM_SAMP, DATA_REP, N_BS) |
| |
| | recip_ref_fft_mat = fft(recip_rx_ref_mat(CP_LEN+1:N_SYM_SAMP, :, :), N_SC, 1) |
| |
| | recip_rx_bs = rx_vec_iris(bs_index, 1:lts_rep_len) |
| |
| | recip_rx_bs_mat = reshape(recip_rx_bs, N_BS, N_SYM_SAMP, DATA_REP) |
| |
| | recip_bs_fft_mat = fft(recip_rx_bs_mat(:, CP_LEN+1:N_SYM_SAMP, :), N_SC, 2) |
| |
| end for | sid |
| |
| end | Step |
| |
| activate correlator | end [rx_vec_pilot_all, data_len_all] = node_bs.sdrrx(N_SAMP, 0) |
| |
| read data | pilot_rep = 1 |
| |
| | rx_vec_pilot = node_bs.get_best_frame(rx_vec_pilot_all, N_SAMP) |
| |
| | data0_len = length(rx_vec_pilot) |
| |
| activate correlator end | corr_peak_all = zeros(1, N_BS_NODE) |
| |
| if AUTO_OFFSET for | ibs |
| |
| | figure |
| |
| | lts_peaks = find(lts_corr > 0.8*max(lts_corr)) |
| |
| | return |
| |
| end | offset = lts_peaks(lts_second_peak_index(1)) - (2*length(lts)) |
| |
| | v0 = filter(fliplr(conj(uplink_pilot_tx)), a, rx_vec_pilot(ibs, :)) |
| |
| | m_filt = (abs(v0) .^ 2) ./ v1 |
| |
| normalized | correlation [~, max_idx] = max(abs(m_filt)) |
| |
| In case of bad | correlatons |
| |
| end end end Sample offset calibration | samp_offset_array = corr_peak_all - corr_peak_all(1) |
| |
| | rx_mat_calibrated_tmp = zeros(size(rx_vec_pilot)) |
| |
| end end | uplink_pilot_rx = zeros(N_BS_NODE, ue_pilot_len) |
| |
| | uplink_pilot_csi = zeros(N_BS_NODE, N_SC) |
| |
| for | irp |
| |
| | ifft_in_mat = zeros(N_BS_NODE, N_SC, N_OFDM_SYMS) |
| |
| for | isc |
| |
| try | downlink_beam_weights = pinv(squeeze(downlink_pilot_csi(:, isc))) |
| |
| catch | stop = 1 |
| |
| end for | isym |
| |
| end end IFFT | tx_payload_mat = zeros(N_BS_NODE, N_SYM_SAMP, N_DATA_SYMS) |
| |
| | tx_pilot_mat = zeros(N_BS_NODE, length(lts_t)*2.5) |
| |
| | pilot2 = squeeze(ifft(ifft_in_mat(ibs, :, 2))) |
| |
| end end Reshape to a vector | tx_payload_vec = reshape(tx_payload_mat, N_BS_NODE, numel(tx_payload_mat(1, :, :))) |
| |
| end configure the | UE |
| |
| Write beamformed signal to all antennas | donwlink_postfix_len = N_SAMP - N_ZPAD_PRE - N_OFDM_SYMS * N_SYM_SAMP |
| |
| | tx_vec_iris = TX_SCALE .* tx_signal ./ max(abs(tx_signal)) |
| |
| activate correlator end Transmit beamformed signal from all antennas and receive at UEs | bad_pilot = true |
| |
| | bad_cnt = 0 |
| |
| | bad_cnt_max = 1000 |
| |
| while bad_pilot | rx_vec_dl = zeros(N_UE_NODE, N_SAMP) |
| |
| | rx_vec_downlink = zeros(N_UE_NODE, N_SAMP) |
| |
| | all_ue_rx = 0 |
| |
| for | j |
| |
| end Process downlink receive signal if AUTO_OFFSET Correlation | lts_rep_dl = repmat(lts_t, 1, N_PILOTS_SYMS) |
| |
| | dl_pilot_start = offset-(2.5*length(lts_t)) |
| |