|
| 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 FFT_OFFSET |
| |
| Number of CP samples to use in | FFT (on average) RECIP_PLOT |
| |
| | sched_id (REF_ANT) |
| |
| 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, start_index+1:start_index+N_SYM_SAMP) |
| |
| | recip_tx (REF_ANT, start_index+1:start_index+N_SYM_SAMP) |
| |
| | uplink_pilot_tx (jp, 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 () |
| |
| configure the N_ZPAD_PRE | recip_tx (i, :) zeros(1 |
| |
| node_bs | sdrtx_single (tx_data, i) |
| |
| Burn data to the UE RAM end node_bs | sdr_activate_rx () |
| |
| end | recip_rx (ibs, :) |
| |
| | if (ibs==REF_ANT) rx_fft_ref(sid |
| |
| id | start_index: (id N_SC) |
| |
| else | rx_fft (sid, :) |
| |
| | cal_mat (nid, :) |
| |
| end Uplink Pilot Collection and Channel Estimation node_bs | set_n_frame (10) |
| |
| node_bs | set_tddconfig (1, bs_sched(bs_sched_id)) |
| |
| node_ue | set_tddconfig (WIRED_UE, ue_sched(ue_sched_id)) |
| |
| Burn data to the UE RAM end if ~WIRED_UE node_ue | sdr_setcorr () |
| |
| read data if ~WIRED_UE node_ue | sdr_unsetcorr () |
| |
|
| | Author (s)[version, executable, isloaded] = pyversion |
| |
| if ~isloaded pyversion usr bin python py print() %weird bug where py isn 't loaded in an external script end % Params Enable writing plots to PNG Iris | params |
| |
| | WIRED_UE = 1 |
| |
| | TX_FRQ = 2.5e9 |
| |
| | RX_FRQ = TX_FRQ |
| |
| | TX_GN = 75 |
| |
| | RX_GN = 60 |
| |
| | SMPL_RT = 5e6 |
| |
| | N_FRM = 1 |
| |
| | bs_ids = string.empty() |
| |
| | bs_sched = string.empty() |
| |
| Waveform params | TX_SCALE = 0.5 |
| |
| 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 = 100 |
| |
| 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 |
| |
| Define the preamble LTS for fine CFO and channel estimation | lts_f |
| |
| | lts_t = ifft(lts_f, 64) |
| |
| time domain | lts = [lts_t(49:64) lts_t] |
| |
| Init Iris nodes Set up the Iris experiment Create BS Hub and UE objects | Note |
| |
| else | hub_id = [] |
| |
| | ue_ids = ["RF3E000103", "RF3E000180"] |
| |
| All BS | schedule |
| |
| BS schedule | ue_sched = ["GGPG", "GGRG"] |
| |
| UE schedule | N_BS_NODE = length(bs_ids) |
| |
| | N_UE_NODE = length(ue_ids) |
| |
| | REF_ANT = floor(N_BS_NODE/2) |
| |
| | sched_id = ones(1, N_BS_NODE) |
| |
| Generate a payload of random integers | tx_data = randi(MOD_ORDER, N_UE_NODE, 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, N_UE_NODE, 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 = zeros(N_UE_NODE, length(SC_IND_PILOTS), N_DATA_SYMS) |
| |
| for | i |
| |
| end Construct the precoding input matrix | precoding_in_mat = zeros(N_UE_NODE, N_SC, N_OFDM_SYMS) |
| |
| Insert the data and pilot | values |
| |
| reciprocity calibration tx pilots | N_BS = N_BS_NODE - 1 |
| |
| | DATA_REP = floor(N_OFDM_SYMS / N_BS) |
| |
| | data_len = N_BS * DATA_REP * N_SYM_SAMP |
| |
| | recip_tx = zeros(N_BS_NODE, data_len) |
| |
| for | jp |
| |
| for | rp |
| |
| end end uplink tx piltos | UE_DATA_REP = floor(N_OFDM_SYMS / N_UE_NODE) |
| |
| | ue_pilot_len = UE_DATA_REP * N_SYM_SAMP |
| |
| | ue_pilots_len = N_UE_NODE * ue_pilot_len |
| |
| | uplink_pilot_tx = zeros(N_UE_NODE, ue_pilots_len) |
| |
| 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 = ones(N_BS_NODE, N_SC) |
| |
| 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 |
| |
| | node_bs = iris_py(bs_sdr_params, hub_id) |
| |
| initialize BS | node_ue = iris_py(ue_sdr_params, []) |
| |
| Reciprocity Calibration | recip_postfix_len = N_SAMP - data_len - N_ZPAD_PRE |
| |
| configure the | BS |
| |
| activate reading | stream [rx_vec_iris, ~] = node_bs.sdrrx(N_SAMP) |
| |
| read data | a = 1 |
| |
| | unos = ones(size(conj(lts))) |
| |
| for | ibs |
| |
| | 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)) |
| |
| | rx_data_start |
| |
| | break |
| |
| for | sid |
| |
| | start_index = CP_LEN + ((rid - 1) + (sid - 1) * DATA_REP) * N_SYM_SAMP |
| |
| | __pad5__ |
| |
| | __pad6__ |
| |
| | bs_sched_id = 3 |
| |
| | ue_sched_id = 1 |
| |
| activate correlator | end [rx_vec_pilot, data0_len] = node_bs.sdrrx(N_SAMP) |
| |
| activate correlator end | uplink_pilot_rx = zeros(N_BS_NODE, N_UE_NODE, ue_pilot_len) |
| |
| | uplink_pilot_csi = zeros(N_BS_NODE, N_UE_NODE, N_SC) |
| |
| | m_filt = (abs(v0) .^ 2) ./ v1 |
| |
| normalized | correlation [~, max_idx] = max(abs(m_filt)) |
| |
| In case of bad | correlatons |
| |