|
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 |
|