⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ofdm_tx_alamouti_init.m

📁 MIMO_OFDM_estimation
💻 M
字号:
warning off;

%Compile-time maximum values; used to set precision of control logic values
max_OFDM_symbols = 2047;
max_num_subcarriers = 64;
max_CP_length = 16;
max_num_baseRateSymbols = 31;
max_num_trainingSymbols = 15;

%Hard-coded OFDM parameters for now; these might be dynamic some day
numSubcarriers = 64;
CPLength = 16;

%Set SISO mode
%tx_SISO_Mode = 1;
tx_alamouti_mode = 1;

%Enable dynamic modulation support
dynamicModulationEn = 0;

%Cyclic Redundancy Check parameters
CRCPolynomial = hex2dec('04c11db7');
CRC_Table = CRC_table_gen(CRCPolynomial);

%Define the preamble which is pre-pended to each packet
%These long and short symbols are borrowed from the 802.11a PHY standard
shortSymbol_freq = [0 0 0 0 0 0 0 0 1+i 0 0 0 -1+i 0 0 0 -1-i 0 0 0 1-i 0 0 0 -1-i 0 0 0 1-i 0 0 0 0 0 0 0 1-i 0 0 0 -1-i 0 0 0 1-i 0 0 0 -1-i 0 0 0 -1+i 0 0 0 1+i 0 0 0 0 0 0 0].';
shortSymbol_time = ifft(fftshift(shortSymbol_freq));
shortSymbol_time = shortSymbol_time(1:16).';

longSymbol_freq_bot = [0 0 0 0 0 0 1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 1]';
longSymbol_freq_top = [1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1 0 0 0 0 0]';
longSymbol_freq = [longSymbol_freq_bot ; 0 ; longSymbol_freq_top];
longSymbol_time = ifft(fftshift(longSymbol_freq)).';

%Concatenate 10 short symbols together
shortsyms_10 = repmat(shortSymbol_time,1,10);

%Concatenate and cyclicly extend two long symbols
%longsyms_2 = [longSymbol_time(33:64) repmat(longSymbol_time,1,2)];
%longSymbol_time = linspace(-1/6, 1/6, 64);
%longsyms_2 = [longSymbol_time(end-31:end) repmat(longSymbol_time,1,2)];
longsyms_2 = [repmat(longSymbol_time,1,2) longSymbol_time(1:32)];

%Scale the resulting time-domain preamble to fit [-1,1]
preamble = 6*[0 shortsyms_10 longsyms_2];

%randseed(1);
%preamble = 6*[0 complex(randn(1,160),randn(1,160)).*0.01 longsyms_2];

preamble_I = real(preamble);%[+1*ones(1,length(preamble)-1) -0.1];
preamble_Q = imag(preamble);%[-1*ones(1,length(preamble)-1) +0.1];

%Configure the pilot tone registers
pilot1_indicies = 7 + ( (64-7) * 2^16);
pilot2_indicies = 21 + ( (64-21) * 2^16);
%pilotValue_pos = hex2dec('7FFF') + (2^16 * hex2dec('7FFF'));%+0.9;
%pilotValue_neg = hex2dec('8000') + (2^16 * hex2dec('8000'));%-0.9;
pilotValue_pos = hex2dec('7FFF') + (2^16 * 0);%+0.9;
pilotValue_neg = hex2dec('8000') + (2^16 * 0);%-0.9;

%Training sequence, borrowed from 802.11a
train = [0 -1 1 -1 1 -1 1 -1 1 -1 -1 -1 -1 1 1 -1 1 1 1 1 1 -1 -1 1 1 -1 -1 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 1 1 -1 -1 -1 -1 1 1 -1 1 -1 1 1 -1 1 1 1 -1 -1 -1 -1 -1 -1];
train = train * -1;
train(22) = -1;
train(58) = 1;

%MIMO training; use the same sequence for both antennas
train = [train train];

%Maximum number of bytes per packet
RAM_init_size = 4096;

%Standard 48-active subcarriers
subcarrier_masks = ones(1,numSubcarriers);
subcarrier_masks(1)=0;  %DC tone at Xk=0
subcarrier_masks(8)=0; %pilot tone at Xk=7
subcarrier_masks(22)=0; %pilot tone at Xk=21
subcarrier_masks(44)=0; %pilot tone at Xk=43
subcarrier_masks(58)=0; %pilot tone at Xk=57
subcarrier_masks([28:32])=0; %zeros at higher frequencies
subcarrier_masks([33:38])=0; %zeros at higher frequencies

%Choose the modulation schemes to use for the base-rate and full-rate symbols
%Replcae the "2" with one of [0,2,4,6,8] to use 0, QPSK, 16/64/256 QAM
modulation_antA = 2*subcarrier_masks;
modulation_antB = 2*subcarrier_masks;
modulation_baseRate = 2*subcarrier_masks;

%Final vector must be: [AntennaA AntennaB BaseRate]
%AntA = AntB = BaseRate = 48 non-zero subcarriers -> 12 bytes/OFDM symbol with QPSK
subcarrier_QAM_Values = [modulation_antA modulation_antB modulation_baseRate];
numBytes_BaseRateOFDMSymbol = sum(modulation_baseRate)/8;
numBytes_FullRateOFDMSymbol = sum(modulation_antA)/8;

%Example of how modulation data gets formatted as bytes in the packet's header; useed for simulation
subcarrier_QAM_Values_bytes = reshape([modulation_antA modulation_antB], 2, numSubcarriers);
subcarrier_QAM_Values_bytes = sum(subcarrier_QAM_Values_bytes .* [ones(1,64).*2^4; ones(1,64)]);

%Setup the packet length for simulation
numTrainingSymbols = 2;
%numFullRateSymbols = ceil(120/12);%124;
numBaseRateSymbols = 0;
if(dynamicModulationEn == 1)
	%4 bits per subcarrier, 64 subcarriers on 1 antenna -> 32 bytes for mod data
end

%Setup the packet contents
rand('state',1); %Get the same packet each time for BER testing

%Define the packet's header & other meta-information
pkt_MACAddr_RX = randint(1,6,255); %Radnom MAC addresses
pkt_MACAddr_TX = randint(1,6,255);
pkt_version = 1;
pkt_rate = 2;
pkt_pktType = 0;
pkt_reserved = [0 0 0 0 0 0]; % 6 bytes

%Leave 32 bytes of extra space
pkt_dynModulation = zeros(1,32);

%Zero-padding to make sure only header information ends up in base-rate symbols
pkt_zeroPad = zeros(1,numBytes_BaseRateOFDMSymbol - mod(length(pkt_dynModulation),numBytes_BaseRateOFDMSymbol));

%Calculate the number of bytes in the packet, based on the number of OFDM symbols specified above
% In hardware, the user code will provide this value per-packet
pkt_numPayloadBytes = 1400;%numBytes_BaseRateOFDMSymbol*numBaseRateSymbols + numBytes_FullRateOFDMSymbol*numFullRateSymbols;
numFullRateSymbols = ceil(pkt_numPayloadBytes/numBytes_FullRateOFDMSymbol);%124;
numFullRateSymbols = numFullRateSymbols + mod(numFullRateSymbols, 2);

%Construct the packet header (base-rate symbol data) byte-by-byte
packetHeader = [...
	pkt_MACAddr_RX...	%bytes 0-5
	pkt_MACAddr_TX...	%bytes 6-11
	pkt_version...		%byte 12
	pkt_rate...			%byte 13
	pkt_pktType...		%byte 14
	0 ...				%byte 15
	floor((pkt_numPayloadBytes/256))... %byte 16
	mod(pkt_numPayloadBytes,256)... %byte 17
	pkt_reserved... %bytes 18-23
	];

%If dynamic modulation is enabled, be sure the header has room for the modulation bytes
if(dynamicModulationEn == 1)
	packetHeader = [packetHeader pkt_dynModulation pkt_zeroPad];
end

%Assemble the rest of the packet, using random bytes for the full-rate payload
packet = [packetHeader 1:-4+(numBytes_FullRateOFDMSymbol*numFullRateSymbols)];
%packet = [packetHeader randint(1,(pkt_numPayloadBytes-4-24),255)];%1:(pkt_numPayloadBytes-4-24)];

%Add the 32-bit checksum to the end of the payload
% In hardware, the checksum automatically over-writes the last four bytes of the payload
packet = mod(packet,256);
packet = [packet calcTxCRC(packet)];

%This value allows the simulated transmitter to start new packets
% leaving a few hundred cycles of idle time between each packet
simOnly_numSamples = length(preamble)+( (numSubcarriers+CPLength)*(numTrainingSymbols + numBaseRateSymbols + numFullRateSymbols) );

%Define the indicies (zero-indexed, like C) of some important bytes in the header
byteIndex_rate = 13;
byteIndex_version = 12;

%byteIndex_numPayloadBytes = [16 17];
byteIndex_numPayloadBytes = [22 23];

byteIndex_dynModulationStart = 24;

%Parameters to initialize the packet buffers
% The default packet is loaded at configuration, allowing real-time BER tests
% This packet will be overwritten in hardware when user-code loads packets
packet_length = length(packet)-1;
RAM_init_values = [packet, zeros(1,RAM_init_size-1-packet_length)];

BER_RAM_init_values = reshape(flipud(reshape(RAM_init_values, 8, RAM_init_size/8)), 1, RAM_init_size);

%LSFR parameters, used for random payload mode
txLSFR_numBits = 13;
txLSFR_polynomials = {'21' '35' '0B' '1D' '35' '0B' '3D' '2B'};
txLSFR_initValues = {'3F' '1B' '03' '35' '17' '0A' '74' '39'};

%Precision for the constants which store the modulation values
modConstellation_prec = 8;
modConstellation_bp = 7;

TxRx_FFTScaling = bin2dec('011010') + (bin2dec('000101') * 2^6);

%Defintion of the various constellations
%Gray coded bit-symbol mappings
%Borrowed from the IEEE 802.16 specification
% IEEE Std 802.16-2004 Tables 153-155 (pg. 329)

%QPSK constellation
%2 bits per symbol, 1 bit per I/Q
% I = MSB, Q = LSB
%modConstellation_qpsk = [1 -1];
modConstellation_qpsk = [1 -1]./sqrt(2);
%modConstellation_qpsk = (1-2^-modConstellation_bp).*modConstellation_qpsk./(max(abs(modConstellation_qpsk)));

%16-QAM constellation
%4 bits per symbol, 2 bits per I/Q
% I = 2MSB, Q = 2LSB
modConstellation_qam16 = .75*[1 3 -1 -3]./3;
%modConstellation_qam16 = [1 3 -1 -3];
%modConstellation_qam16 = [1 3 -1 -3]./sqrt(10);
%modConstellation_qam16 = (1-2^-modConstellation_bp).*modConstellation_qam16./(max(abs(modConstellation_qam16)));

%FIXME: 64/256QAM constellations exceed +/-1, which won't fit in the current data types!
%64-QAM constellation
%6 bits per symbol, 3 bits per I/Q
% I = 3MSB, Q = 3LSB
modConstellation_qam64 = 0.875*[3 1 5 7 -3 -1 -5 -7]./7;
%modConstellation_qam64 = [3 1 5 7 -3 -1 -5 -7];
%modConstellation_qam64 = [3 1 5 7 -3 -1 -5 -7]./(7*3/sqrt(10));%sqrt(42);
%modConstellation_qam64 = (1-2^-modConstellation_bp).*modConstellation_qam64./(max(abs(modConstellation_qam64)));

%256-QAM constellation
%8 bits per symbol, 4 bits per I/Q
% I = 4MSB, Q = 4LSB
modConstellation_qam256 = 0.9375*[3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15]./15;
%modConstellation_qam256 = [3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15];
%1/(modnorm(qammod(0:255,256),'avpow',1))^2
%modConstellation_qam256 = [3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15]./sqrt(170);
%modConstellation_qam256 = (1-2^-modConstellation_bp).*modConstellation_qam256./(max(abs(modConstellation_qam256)));

%interpFilter = firpm(40, [0 0.18 0.25 1], [1 1 0 0]);
[x, interpFilter] = interp(longSymbol_time, 5);
[x, interpFilter_4] = interp(longSymbol_time, 4);
%interpFilter_4 = firpm(31,[0 0.22 0.32 1], [1 1 0 0]);
%interpFilter_4 = firpm(31,[0 (1-52/64)*.25 (1+52/64)*.25 1], [1 1 0 0]);
%interpFilter_4 = 2*interpFilter_4./norm(interpFilter_4);
%interpFilter_4 = rcosfir(0.2, 4, 4, 1);

antB_preambleShift = 4;

%Fill in the TxControlBits register; each bit has a different purpose
%0x2: 2 Random payload
%0x4: 4 Disable AntB preamble
%0x8: 8 Enable Pilot Scrambling (2^3)
tx_controlBits = (antB_preambleShift * 2^4) + 4*0 + 8*1;

%DataScrambling_Seq = zeros(1,32);
DataScrambling_Seq = [41 198 78 63 82 173 102 245 48 111 172 115 147 230 216 93 72 65 62 2 205 242 122 90 128 83 105 97 73 10 5 252];
DataScrambling_Length = length(DataScrambling_Seq);

%Load Chipscope capture data
%xlloadchipScopeData('fullPktCapt_v11_badBehavior_0.prn'); t_start = 148;
AntA_ADC_I = 0;AntA_ADC_Q = 0; t_start = 1;
%rxAntI.time = [];rxAntQ.time = [];rxAntI.signals.values = real(AntA_ADC_I(1:4:end));rxAntQ.signals.values = real(AntA_ADC_Q(1:4:end));
rxAntI.time = [];
rxAntQ.time = [];
rxAntI.signals.values = AntA_ADC_I(t_start:end);
rxAntQ.signals.values = AntA_ADC_Q(t_start:end);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -