root/ResearchApps/PHY/MIMO_OFDM/Alamouti/ofdm_tx_alamouti_init.m

Revision 810, 11.7 kB (checked in by murphpo, 11 months ago)

Added full header checksum support to both OFDM PHYs; the receiver can optionally reset when it detects a bad header, before processing the full packet.

Line 
1warning off;
2
3%Compile-time maximum values; used to set precision of control logic values
4max_OFDM_symbols = 2047;
5max_num_subcarriers = 64;
6max_CP_length = 16;
7max_num_baseRateSymbols = 31;
8max_num_trainingSymbols = 15;
9
10%Hard-coded OFDM parameters for now; these might be dynamic some day
11numSubcarriers = 64;
12CPLength = 16;
13
14%Set SISO mode
15%tx_SISO_Mode = 1;
16tx_alamouti_mode = 1;
17
18%Cyclic Redundancy Check parameters
19CRCPolynomial = hex2dec('04c11db7');
20CRC_Table = CRC_table_gen(CRCPolynomial);
21
22%Define the preamble which is pre-pended to each packet
23%These long and short symbols are borrowed from the 802.11a PHY standard
24shortSymbol_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].';
25shortSymbol_time = ifft(fftshift(shortSymbol_freq));
26shortSymbol_time = shortSymbol_time(1:16).';
27
28longSymbol_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]';
29longSymbol_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]';
30longSymbol_freq = [longSymbol_freq_bot ; 0 ; longSymbol_freq_top];
31longSymbol_time = ifft(fftshift(longSymbol_freq)).';
32
33%Concatenate 10 short symbols together
34shortsyms_10 = repmat(shortSymbol_time,1,10);
35
36%Concatenate and cyclicly extend two long symbols
37%longsyms_2 = [longSymbol_time(33:64) repmat(longSymbol_time,1,2)];
38%longSymbol_time = linspace(-1/6, 1/6, 64);
39%longsyms_2 = [longSymbol_time(end-31:end) repmat(longSymbol_time,1,2)];
40longsyms_2 = [repmat(longSymbol_time,1,2) longSymbol_time(1:32)];
41
42%Scale the resulting time-domain preamble to fit [-1,1]
43preamble = 6*[0 shortsyms_10 longsyms_2];
44preamble_ssOnly = 6*[0 shortsyms_10 zeros(1,longsyms_2)];
45
46%randseed(1);
47%preamble = 6*[0 complex(randn(1,160),randn(1,160)).*0.01 longsyms_2];
48
49preamble_I = real(preamble);%[+1*ones(1,length(preamble)-1) -0.1];
50preamble_Q = imag(preamble);%[-1*ones(1,length(preamble)-1) +0.1];
51
52%Configure the pilot tone registers
53pilot1_indicies = 7 + ( (64-7) * 2^16);
54pilot2_indicies = 21 + ( (64-21) * 2^16);
55%pilotValue_pos = hex2dec('7FFF') + (2^16 * hex2dec('7FFF'));%+0.9;
56%pilotValue_neg = hex2dec('8000') + (2^16 * hex2dec('8000'));%-0.9;
57pilotValue_pos = hex2dec('7FFF') + (2^16 * 0);%+0.9;
58pilotValue_neg = hex2dec('8000') + (2^16 * 0);%-0.9;
59
60%Training sequence, borrowed from 802.11a
61train = [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];
62train = train * -1;
63train(22) = -1;
64train(58) = 1;
65
66%MIMO training; use the same sequence for both antennas
67train = [train train];
68
69%Maximum number of bytes per packet
70RAM_init_size = 4096;
71
72%Standard 48-active subcarriers
73subcarrier_masks = ones(1,numSubcarriers);
74subcarrier_masks(1)=0;  %DC tone at Xk=0
75subcarrier_masks(8)=0; %pilot tone at Xk=7
76subcarrier_masks(22)=0; %pilot tone at Xk=21
77subcarrier_masks(44)=0; %pilot tone at Xk=43
78subcarrier_masks(58)=0; %pilot tone at Xk=57
79subcarrier_masks([28:32])=0; %zeros at higher frequencies
80subcarrier_masks([33:38])=0; %zeros at higher frequencies
81
82%Choose the modulation schemes to use for the base-rate and full-rate symbols
83%Replcae the "2" with one of [0,2,4,6,8] to use 0, QPSK, 16/64/256 QAM
84modMask_baseRate = 2;
85modMask_fullRate = 2;
86modulation_baseRate = modMask_baseRate*subcarrier_masks;
87modulation_fullRate = modMask_fullRate*subcarrier_masks;
88
89%Final vector must be: [FullRate BaseRate]
90subcarrier_QAM_Values = [modulation_fullRate modulation_baseRate];
91numBytes_BaseRateOFDMSymbol = sum(modulation_baseRate)/8;
92numBytes_FullRateOFDMSymbol = sum(modulation_fullRate)/8;
93
94%Setup the packet length for simulation
95numTrainingSymbols = 4;
96%numFullRateSymbols = ceil(120/12);%124;
97numBaseRateSymbols = 2;
98
99%Setup the packet contents
100rand('state',1); %Get the same packet each time for BER testing
101
102%Define the packet's header & other meta-information
103pkt_MACAddr_RX = randint(1,6,255); %Radnom MAC addresses
104pkt_MACAddr_TX = randint(1,6,255);
105pkt_version = 1;
106pkt_rate = 2;
107pkt_pktType = 0;
108pkt_reserved = [0 0 0 0 0]; % 6 bytes
109
110%Define the indicies (zero-indexed, like C) of some important bytes in the header
111%Define the indicies (zero-indexed, like C) of some important bytes in the header
112%byteIndex_numPayloadBytes = [22 23];
113%byteIndex_simpleDynModMasks = 8;
114byteIndex_numPayloadBytes = [9 10];
115byteIndex_simpleDynModMasks = 8;
116numHeaderBytes = 24;
117
118
119%Define the some header meta-data that is common to every packet
120% Number of header bytes, used to insert the header checksum in the right spot
121% Indicies of three header bytes - 16-bit packet length and 8-bit modulation masks
122% It is required that the Tx and Rx nodes have matching values ahead of time
123pktByteNums =   numHeaderBytes + ...
124                                byteIndex_numPayloadBytes(1)*2^8 + ...
125                                byteIndex_numPayloadBytes(2)*2^16 + ...
126                                byteIndex_simpleDynModMasks * 2^24;
127
128%Calculate the number of bytes in the packet, based on the number of OFDM symbols specified above
129% In hardware, the user code will provide this value per-packet
130pkt_numPayloadBytes = 24+4+20+20;%1400;%numBytes_BaseRateOFDMSymbol*numBaseRateSymbols + numBytes_FullRateOFDMSymbol*numFullRateSymbols;
131%numFullRateSymbols = ceil( (pkt_numPayloadBytes/numBytes_FullRateOFDMSymbol) - numBaseRateSymbols );%124;
132numFullRateSymbols = ceil((pkt_numPayloadBytes - numBytes_BaseRateOFDMSymbol*numBaseRateSymbols)/numBytes_FullRateOFDMSymbol);
133numFullRateSymbols = numFullRateSymbols + mod(numFullRateSymbols, 2);
134
135%Construct the packet header (base-rate symbol data) byte-by-byte
136packetHeader = [...
137        pkt_MACAddr_RX...       %bytes 0-5
138        pkt_MACAddr_TX...       %bytes 6-11
139        pkt_version...          %byte 12
140        floor((pkt_numPayloadBytes/256))... %byte 13
141        mod(pkt_numPayloadBytes,256)... %byte 14
142        (modMask_fullRate) ... %byte 15
143        pkt_rate...                     %byte 16
144        pkt_pktType...          %byte 17
145        0 ...                           %byte 18
146        pkt_reserved... %bytes 19-23
147        ];
148
149%Construct the packet header (base-rate symbol data) byte-by-byte
150%packetHeader = [...
151%       pkt_MACAddr_RX...       %bytes 0-5
152%       pkt_MACAddr_TX...       %bytes 6-11
153%       pkt_version...          %byte 12
154%       pkt_rate...                     %byte 13
155%       pkt_pktType...          %byte 14
156%       0 ...                           %byte 15
157%       floor((pkt_numPayloadBytes/256))... %byte 16
158%       mod(pkt_numPayloadBytes,256)... %byte 17
159%       pkt_reserved... %bytes 18-23
160%       ];
161
162%Assemble the rest of the packet, using random bytes for the full-rate payload
163%packet = [packetHeader 1:-4+(numBytes_FullRateOFDMSymbol*numFullRateSymbols)];
164%packet = [packetHeader randint(1,(pkt_numPayloadBytes-4-24),255)];%1:(pkt_numPayloadBytes-4-24)];
165packet = [packetHeader 1:(pkt_numPayloadBytes-length(packetHeader)-4)];
166
167%Add the 32-bit checksum to the end of the payload
168% In hardware, the checksum automatically over-writes the last four bytes of the payload
169packet = mod(packet,256);
170packet = [packet calcTxCRC(packet)];
171
172%This value allows the simulated transmitter to start new packets
173% leaving a few hundred cycles of idle time between each packet
174simOnly_numSamples = length(preamble)+( (numSubcarriers+CPLength)*(numTrainingSymbols + numBaseRateSymbols + numFullRateSymbols) );
175
176%Parameters to initialize the packet buffers
177% The default packet is loaded at configuration, allowing real-time BER tests
178% This packet will be overwritten in hardware when user-code loads packets
179packet_length = length(packet)-1;
180RAM_init_values = [packet, zeros(1,RAM_init_size-1-packet_length)];
181
182BER_RAM_init_values = reshape(flipud(reshape(RAM_init_values, 8, RAM_init_size/8)), 1, RAM_init_size);
183
184%LSFR parameters, used for random payload mode
185txLSFR_numBits = 13;
186txLSFR_polynomials = {'21' '35' '0B' '1D' '35' '0B' '3D' '2B'};
187txLSFR_initValues = {'3F' '1B' '03' '35' '17' '0A' '74' '39'};
188
189%Precision for the constants which store the modulation values
190modConstellation_prec = 8;
191modConstellation_bp = 7;
192
193TxRx_FFTScaling = bin2dec('011011') + (bin2dec('000101') * 2^6);
194
195%Defintion of the various constellations
196%Gray coded bit-symbol mappings
197%Borrowed from the IEEE 802.16 specification
198% IEEE Std 802.16-2004 Tables 153-155 (pg. 329)
199
200%QPSK constellation
201%2 bits per symbol, 1 bit per I/Q
202% I = MSB, Q = LSB
203%modConstellation_qpsk = [1 -1];
204modConstellation_qpsk = [1 -1]./sqrt(2);
205%modConstellation_qpsk = (1-2^-modConstellation_bp).*modConstellation_qpsk./(max(abs(modConstellation_qpsk)));
206
207%16-QAM constellation
208%4 bits per symbol, 2 bits per I/Q
209% I = 2MSB, Q = 2LSB
210modConstellation_qam16 = 0.75*[1 3 -1 -3]./3;
211%modConstellation_qam16 = [1 3 -1 -3];
212%modConstellation_qam16 = [1 3 -1 -3]./sqrt(10);
213%modConstellation_qam16 = (1-2^-modConstellation_bp).*modConstellation_qam16./(max(abs(modConstellation_qam16)));
214
215%FIXME: 64/256QAM constellations exceed +/-1, which won't fit in the current data types!
216%64-QAM constellation
217%6 bits per symbol, 3 bits per I/Q
218% I = 3MSB, Q = 3LSB
219modConstellation_qam64 = 0.875*[3 1 5 7 -3 -1 -5 -7]./7;
220%modConstellation_qam64 = [3 1 5 7 -3 -1 -5 -7];
221%modConstellation_qam64 = [3 1 5 7 -3 -1 -5 -7]./(7*3/sqrt(10));%sqrt(42);
222%modConstellation_qam64 = (1-2^-modConstellation_bp).*modConstellation_qam64./(max(abs(modConstellation_qam64)));
223
224%256-QAM constellation
225%8 bits per symbol, 4 bits per I/Q
226% I = 4MSB, Q = 4LSB
227modConstellation_qam256 = 0.9375*[3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15]./15;
228%modConstellation_qam256 = [3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15];
229%1/(modnorm(qammod(0:255,256),'avpow',1))^2
230%modConstellation_qam256 = [3 1 5 7 11 9 13 15 -3 -1 -5 -7 -11 -9 -13 -15]./sqrt(170);
231%modConstellation_qam256 = (1-2^-modConstellation_bp).*modConstellation_qam256./(max(abs(modConstellation_qam256)));
232
233%interpFilter = firpm(40, [0 0.18 0.25 1], [1 1 0 0]);
234[x, interpFilter] = interp(longSymbol_time, 5);
235[x, interpFilter_4] = interp(longSymbol_time, 4);
236%interpFilter_4 = firpm(31,[0 0.22 0.32 1], [1 1 0 0]);
237%interpFilter_4 = firpm(31,[0 (1-52/64)*.25 (1+52/64)*.25 1], [1 1 0 0]);
238%interpFilter_4 = 2*interpFilter_4./norm(interpFilter_4);
239%interpFilter_4 = rcosfir(0.2, 4, 4, 1);
240
241antB_preambleShift = 4;
242
243%Popluate the TxControlBits register
244%0x1:   1: Unused
245%0x2:   2: Unused
246%0x4:   4: Disable antenna B preamble
247%0x8:   8: Enable pilot tone scrambling
248%0xF0:   : Antenna B preamble shift
249%0x100: 256: Enable re-transmission (relay mode)
250%0x200: 512: Swap antenna A/B (sends stream B first in relay mode)
251%0x400: 1024: Enable Tx PreCFO
252%0x800: 2048: Enable relay re-transmission
253%0xFFFF0000: Delay before re-transmission
254
255tx_controlBits = ...
256                   0 * 1 ... %Unused
257                 + 0 * 2 ... %Unused
258                 + 0 * 4 ... %0=enable antenna B preamble
259                 + 1 * 8 ... %1=enable pilot scrambling
260                 + 1 * 16 * (antB_preambleShift) ... %4-bit preamble shift
261                 + 0 * 256 ... %1=relay mode
262                 + 0 * 512 ... %1=antenna swap
263         + 1 * 1024 ... %1=enable Tx preCFO
264         + 1 * 2048 ... %1=Enable relay (DF) re-transmission on goodPkt
265                 + 1 * 2^16 * 1000; %16-bit re-transmit delay
266
267%DataScrambling_Seq = zeros(1,32);
268TxDataScrambling_Seq = [40 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];
269RxDataScrambling_Seq = [40 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];
270
271%Load Chipscope capture data
272AntA_ADC_I = 0;AntA_ADC_Q = 0; csInterp = 2; t_start = 1;
273%xlloadchipScopeData('cfo_v06_capt1_coarseEstOffBy10x.prn'); csInterp = 2; t_start = 1000;
274%xlloadchipScopeData('cfo_v08_coarseCfoTooBig_1.prn'); csInterp = 2; t_start = 2913;
275%xlloadchipScopeData('cfo_v08_coarseCfoGood_0.prn'); csInterp = 2; t_start = 535;
276rxAntI.time = [];
277rxAntQ.time = [];
278rxAntI.signals.values = AntA_ADC_I(t_start:csInterp:end);
279rxAntQ.signals.values = AntA_ADC_Q(t_start:csInterp:end);
Note: See TracBrowser for help on using the browser.