%%%%%%%% OFDM transceiver with 802.11n %%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%% Mohammad Hosseinvand %%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%% February 2018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%% %40Mhz %FFT: 128 %64QAM %%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% Sub carriers (total/data): 114 total%%%%%%%%%%%%%%%
%%%%%%%% Number of Pilots:6 {-53,-25,-11,11,25,53} %%%%%%%%%
%%%%% Signal is TX on sub-carriers -58 to -2 and 2 to 58 %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
clear all;
clc;
%% *** Initialize the parameters ***
%802.11n 40MHz channel: 114 sub-carriers (108 data, 6 pilot)
Bit_Num = 6; %64QAM = 2^6
FFT_Num = 128; %FFT length
Carrier_Num = 108; %Nsd: No. data carrier
OFDM_per_Symbol = 1;
%CP=32; % N-FFT/4 = 128/4=32
%LI = 18; %B/W -11 to +11 pilots , there are 18 data
Np = 6; % No. pilot carrier
Carriers = 1:Carrier_Num+Np; % Total no. carreirs 114
N_Num = Bit_Num*Carrier_Num*OFDM_per_Symbol;
%% ***Generate the random binary stream for transmit-Transmitter starts***
BitTx= round(rand(1,(N_Num)));
%% ***Modulate (generates 64QAM symbols)***
N_Num=length(BitTx);
SymQAMtmp=reshape(BitTx,6,N_Num/6).';
SymQAMtmptmp=bi2de(SymQAMtmp,2,'left-msb');
QAMTable = [ -7-7j, 7-7j, -1-7j, 1-7j, -5-7j, 5-7j,...
-3-7j, 3-7j, -7+7j, 7+7j, -1+7j, 1+7j,...
-5+7j, 5+7j, -3+7j, 3+7j, -7-1j, 7-1j,...
-1-1j, 1-1j, -5-1j, 5-1j, -3-1j, 3-1j,...
-7+1j, 7+1j, -1+1j, 1+1j, -5+1j, 5+1j,...
-3+1j, 3+1j, -7-5j, 7-5j, -1-5j, 1-5j,...
-5-5j, 5-5j, -3-5j, 3-5j, -7+5j, 7+5j,...
-1+5j, 1+5j, -5+5j, 5+5j, -3+5j, 3+5j,...
-7-3j, 7-3j, -1-3j, 1-3j, -5-3j, 5-3j,...
-3-3j, 3-3j, -7+3j, 7+3j, -1+3j, 1+3j,...
-5+3j, 5+3j, -3+3j, 3+3j];
SymQAM=QAMTable(SymQAMtmptmp+1);
%% ***Generate the preamble signal***
fsMHz = 40; % sampling frequency
nFFTSize = 128;
% for each symbol bits a1 to a114 are assigned to subcarrier
% index [–58 to –2 +2 to +58]
% Short preamble
subcarrierIndex = [-58:-2 2:58]; %for 40Mhz and FFT 128
S1 = [zeros(1,6) 0 0 1+1j 0 0 0 -1-1j 0 0 0 1+1j 0 0 0 -1-1j 0 0 0 -1-1j 0 0 0 1+1j 0 0 0 ...
0 0 0 0 -1-1j 0 0 0 -1-1j 0 0 0 1+1j 0 0 0 1+1j 0 0 0 1+1j 0 0 0 1+1j 0 0 0 0 0 ...
0 0 0 0 0 0 0 0 0 0 1+1j 0 0 0 -1-1j 0 0 0 1+1j 0 0 0 -1-1j 0 0 0 -1-1j 0 0 0 1+1j ...
0 0 0 0 0 0 0 -1-1j 0 0 0 -1-1j 0 0 0 1+1j 0 0 0 1+1j 0 0 0 1+1j 0 0 0 1+1j 0 0 zeros(1,5)];
S1 = sqrt(19/4)*(S1);
% Long preamble
S2 = [zeros(1,8),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,...
-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,-1,-1,1,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,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,1,1,1,zeros(1,7)];
S1_td=ifft(S1,128);
S2_td=ifft(S2,128);
%STEP3 Adding CP to the time domain preamble symbol 1 and symbol 2
CP= ceil(FFT_Num/4);
S2_tdcp=[S2_td(end-CP+1:end) S2_td S2_td];
% concatenating multiple symbols to form 10 short preamble
S1_tdcp = [S1_td S1_td S1_td(1:32)];
preamble = [S1_tdcp S2_tdcp];
%% ***Generate the pilot signal***
train_sym1= round(rand(1,(2*OFDM_per_Symbol)));
train_sym2= round(rand(1,(2*OFDM_per_Symbol)));
t= 2*(train_sym1.*2-1)+(train_sym2.*2-1);
treal= t(1:2:2*OFDM_per_Symbol);
timage= t(2:2:2*OFDM_per_Symbol);
training_symbols1= treal+1i*timage;
training_symbols2= training_symbols1.';
training_symbols=repmat(training_symbols2,1,Np);
%kData = [-58:-54,-52:-26,-24:-12,-10:-2,2:10,12:24,26:52,54:58];
pilot = [1,29,43,62,76,104]; %start position of pilots/**shift border from -58 to 1 to start first pilot and so on ... because of positive vector in Matlab
%pilot = [6,34,48,67,81,109];
%% ***P/S transform***
SymQAM1=reshape(SymQAM,Carrier_Num,OFDM_per_Symbol).';
%% ***Insert the pilot symbols***
signal=1:Carrier_Num+Np;
signal(pilot)=[];
SymQAM2(:,pilot)=training_symbols;
SymQAM2(:,signal)=SymQAM1;
SymQAM3=SymQAM2.';
%% ***IFFT transform***
SymIFFT=ifft(SymQAM3,FFT_Num,1);
%% ***GI Insertion***
SymTxtmp= zeros(FFT_Num+CP,OFDM_per_Symbol);
SymTxtmp(1:CP,:)= SymIFFT(FFT_Num-CP+1:FFT_Num,:);
SymTxtmp(CP+1:CP+FFT_Num,:)= SymIFFT;
SymTx=reshape(SymTxtmp,1,(FFT_Num+CP)*OFDM_per_Symbol);
%% *************** Transmitter ends *****************************
%% *************** Receiver starts ******************************
%% ***Packet detection***
SymRxdel=[zeros(1,CP) SymTx(1:length(SymTx)-CP)]; % Delayed
y = xcorr(SymTx,SymRxdel);
[m,n]=max(y);
t_offset_Packet_detection = n-1;
SymRx= y(t_offset_Packet_detection+1:end);
%% ***GI Removal***
SymRxtmp= reshape(SymTx,FFT_Num+CP,OFDM_per_Symbol);
SymRx= SymRxtmp(CP+1:CP+FFT_Num,:);
SymRx=reshape(SymRx,1,128);
%% ***Time offset estimation***
Toff=input('Enter time offset any numeric number(for example 100):');
SymRx2=[zeros(1,Toff),SymRx];
if length(SymRx2)>length(S1_tdcp)
pad = length(SymRx2)-length(S1_tdcp);
S1_tdcp = [S1_tdcp zeros(1,pad)];
elseif length(SymRx2)<length(S1_tdcp)
pad = length(S1_tdcp)-length(SymRx2);
SymRx2 = [SymRx2 zeros(1,pad)];
end
out_len = length(SymRx2);
out = zeros(1,out_len);
tmp = S1_tdcp;
for k = 1:out_len
out(k) = SymRx2*tmp';
tmp = [0 tmp(1:end-1)];
end
[m,n]=max(out);
t_offset_Time_estimation = n-1;
%% ***FFT transform***
SymRx=reshape(SymRx,FFT_Num,OFDM_per_Symbol);
SymFFT=fft(SymRx,FFT_Num,1);
SymFFT=SymFFT(1:Carrier_Num+Np,:);
%% ***Channel Estimation***
% extract pilots from received signal
SymFFT1=SymFFT.';
Rx_training_symbols= SymFFT1(:,pilot);
Rx_training_symbols0= reshape(Rx_training_symbols,OFDM_per_Symbol*Np,1);
% reshape original pilots
training_symbols0= reshape(training_symbols,1,OFDM_per_Symbol*Np);
training_symbols1= diag(training_symbols0);
training_symbols2= inv(training_symbols1);
Hls= (training_symbols2)*Rx_training_symbols0;
Hls1= reshape(Hls,OFDM_per_Symbol,Np);
HLs=[];
HLs2=[];
%%%%%%%% my problem with this section, I know for 4 pilot with this loop, with 3 repeat with 16 iteration make 48 data carrier for 802.11a/generates
%%%%%%%% But with 6 pliots,doest not work this loops, because 6-1=5,and for iteration value is not integer: 108/5=21.5
for k=1:Np-1
HLs2=[];
for j=1:16
HLs1(:,1)=(Hls1(:,k+1)-Hls1(:,k))*(j-1)/LI+Hls1(:,k);
HLs2=[HLs2,HLs1];
end
HLs=[HLs,HLs2];
end
HLs=[HLs,HLs2];
SymFFT1=SymFFT.';
SymFFT2=SymFFT1(:,signal);
SymFFT3= SymFFT2./HLs;
SymFFT=SymFFT3.';
%% ***Demodulate***
SymDeQAMtmp=reshape(SymFFT,1,OFDM_per_Symbol*Carrier_Num);
m=real(SymDeQAMtmp);
n=abs(real(SymDeQAMtmp));
p=imag(SymDeQAMtmp);
q=abs(imag(SymDeQAMtmp));
s=2*(m==n)-1;
t=2*(p==q)-1;
SymDeQAMtmpshift=SymDeQAMtmp+((-2)*(s+1i*t));
bit0=imag(SymDeQAMtmp);
bit1=imag(SymDeQAMtmpshift);
bit2=real(SymDeQAMtmp);
bit3=real(SymDeQAMtmpshift);
SymDeQAMtmptmp=zeros(Bit_Num,OFDM_per_Symbol*Carrier_Num);
SymDeQAMtmptmp(1,:)=bit0;
SymDeQAMtmptmp(2,:)=bit1;
SymDeQAMtmptmp(3,:)=bit2;
SymDeQAMtmptmp(4,:)=bit3;
for j=1:(Bit_Num*OFDM_per_Symbol*Carrier_Num)
if SymDeQAMtmptmp(j)>0
SymDeQAMtmptmp(j)=0;
else SymDeQAMtmptmp(j)=1;
end
end
SymDeQAM=reshape(SymDeQAMtmptmp,1,Bit_Num*OFDM_per_Symbol*Carrier_Num);