%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright 2018 Lime Microsystems Ltd.
%
% Licensed under the Apache License, Version 2.0 (the 'License');
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
%    http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an 'AS IS' BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Simple ASK data link
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% run ASK.m
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   S E T T I N G S
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear all;
close all;
fir=0; % 0=no filter 1=Gausian 
useLimeSDR=true;
leaveSDRrunningAfter=false;
saveGraphs=false;
minPktLength=8192; % Current LimeSDR requirement
itt=3;
fpltname='ASK';
fwfm=strcat(fpltname,'.wfm');
FSR=1; % Sample rate frequency
fLMSsettings='DEMO_1Msps_866MHz_-50dBm.ini';
pkg load communications
fftSize=32;
frames=32;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   G E N E R A T E   T R A N S M I T   S I G N A L
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
t=0:1023;
k=2*pi;
m=[1,1,-1,1,-1,-1,1,-1]; % data
rep=fftSize*frames/length(m);
rep=fftSize*frames/length(m);
if(fir==1) % gaussian impulse response
  kk=2; % number of symbols
  hh=((0:(kk*rep-1))/(kk*rep-1)-0.5);
  h=exp(-25*(hh.*hh));
else % oversample
  h=ones(1,rep);
end
mm=zeros(rep,length(m)); % up sample
mm(1,:)=m;
mm=reshape(mm,1,[]);
m=0*mm;
for ci=1:length(h) % apply FIR
  m+=h(ci)*mm;
  mm=shift(mm,1);
end
m+=1;
m/=2;
iqDataTx=0.3*m.*exp(i*2*pi*t/8); % amplitude modulate offset ssb carrier
%iqDataTx=0.3*m; % amplitude modulate carrier - does not work due to RX DC cancellation!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   R A D I O   S E T U P
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if useLimeSDR==true 
	LoadLimeSuite; 	% LimeSDR initialisation and use
	LimeInitialize();
  LimeLoadConfig(fLMSsettings); % use settings file from LimeSuite
  iqDataTxo=reshape(repmat(iqDataTx,2,1),1,[]); % convert to MIMO format
	LimeStartStreaming(length(iqDataTxo));
	LimeLoopWFMStart(iqDataTx); % play back data
end

figure;
%cm=[0:0.01:1;zeros(1,101);1:-0.01:0]'; % 101 pt RGB map
cm=[0:0.01:1;(0:0.01:1).^2;1:-0.01:0]'; % 101 pt RGB map
colormap(cm);
for cint=1:itt  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  %
  %   P R O C E S S   R E C E I V E   S I G N A L
  %
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 if useLimeSDR==true 
	  iqDataRx = LimeReceiveSamples(length(iqDataTx));
  else % if not using LimeSDR, patch transmit stream direct to RX
  	iqDataRx=iqDataTx;
  end
  ask=abs(iqDataRx); % basic FM demodulator
  subplot(2,2,1);
  plot(real(iqDataRx),'b-',imag(iqDataRx),'r-');
  grid on;
  title('Raw Waveform');
  xlabel('Time Points');
  ylabel('Level');
  subplot(2,2,2);
  plot(ask,'b-');
  grid on;
  title('Demodulated ASK Waveform');
  xlabel('Time Points');
  ylabel('Level');
 
  subplot(2,2,3);  % basic windowed water fall type graph. 
  wtfl=fft(conj(reshape(iqDataRx,fftSize,[])').*hanning(fftSize)',fftSize,2)/fftSize; % windowed horizontal multiple FFT
  wtfl2=zeros((frames),fftSize);
  wtfld=mag2db(abs(fftshift(wtfl,2))+1e-5);
  img=imagesc(wtfld);
  grid on;
  title('Waterfall Graph');
  xlabel('Frequency');
  ylabel('Time');
  
  subplot(2,2,4);  % windowed fft 
  len=length(iqDataRx);
  fscale=(-(len/2):(len/2-1))/len*FSR; % MHz
  spctrm=fftshift(fft(iqDataRx.*hanning(len)')/len); % note hamming is column vector, transpose
  spctrm=20*log10(abs(spctrm)+1e-6);
  plot(fscale,spctrm,'bo-');
  grid on;
  title('Windowed Received Data Spectrum');
  xlabel('Frequency MHz');
  ylabel('Magnitude dBFS');
  legend('level dB');
  if saveGraphs
    print( fpltname, '-dpng' );
  end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%   R A D I O   S H U T D O W N
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if (leaveSDRrunningAfter==false) && (useLimeSDR==true)
  printf('Purging LimeSDR resources\n'); 
  LimeLoopWFMStop(); % stop streaming
  LimeStopStreaming(); % also resets Rx Tx buffers 
  LimeDestroy(); % deallocate resources
end
fpltname=strcat(fpltname,'.wfm');
WFMwrite( fpltname, iqDataTx );
