%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ADC PN Backround Calibration
%
% Jon Guerber, July 2009
%
% This script should simulate a two step ADC along with interstage radix
% esitmation using a PN sequence. Good Luck!
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%% Setup %%%%%%%%%%%%%%%%%%%%%%%%%%
clc
format long
tic
B = 20; %The number of points to take
%%%%%%%%%%%%%%%%%% Input Terms %%%%%%%%%%%%%%%%%%%%%%
%s = (random('Uniform',-1,1,1,2^B))./2; % Random Number Input
s = ((sin(2*pi*7/(2^B)*[0:((2^B)-1)]))/2); % Sine Wave Input
pnn = ((ceil(random('Uniform',-1,1,1,(2^B)))-.5).*2);
pn = .1.*pnn; % Input PN Sequence
vinp = s + pn; % The Input Sequence with PN Added
vin = s; % The Pure Input Sequence
N = 6; % Number of First Stage Bits
Vref = 1; % Reference Voltage
Res_Err = 1; % Residue Error (Multiplied)
G = ((2^N)/2)*Res_Err; % Interstage Gain
%%%%%%%%%% Stage 1 Analog to Digital Conversion %%%%%%%%%
D1 = round((vinp.*((2^N)/Vref)))./((2^N)/Vref); % Solve for the D1 Bits in 0-vref range
Residue = (vin)-(D1); % DAC and Subtraction for Residue
vin2 = Residue.*(G); % Amplify the Residue
%%%%%%%%%%%%%% Stage 2 %%%%%%%%%%%%%%%
N2 = 9; % Number of Second Stage Bits
Res_Err_App = 1.1; % Estimated Residue Error Factor
Gp = ((2^N)/2).*Res_Err_App; % Estimated Radix Value
D2 = round(vin2.*((2^N2)/Vref))./((2^N2)/Vref); % 2nd stage ADC in 0-vref range
Residue2 = vin2-(D2.*(Vref/(2^N2))); % 2nd stage Residue
D = D1.*Gp+D2; % Concatanate Bits with Radix Estimite
plot(D) % Plot the Final Digitzed signal
title('Digital Ouptut with PN injected')
xlabel('Samples')
ylabel('Dgitial Ouptut')
figure
%%%%%%%%%%%% PN Correlation %%%%%%%%%%%%%%%%%%%%
Ex = zeros(1,2^B); % Preallocate all arrays for sim speed
Eave = zeros(1,2^B);
Ex = (pn.*D); % Output multiplied by PN
Ec = cumsum(Ex); % Sum all values up to this point
%k = nnz(pnn);
k = 1:1:(2^B);
Eave = Ec./k; % Take average
plot(Eave) % Plot the convergence of the error term
%axis([0 7e7 .001 .003])
title('Gain Error Estimite with PN Correlation (Correct Error = (Res_Err_App - 1)*(2^N/2))')
xlabel('Samples')
ylabel('Gain Error')
figure
%%%%%%%%%%%% Post Analysis FFT and SNR %%%%%%%%%%%%%%%%%%%%
f=(0:1:(2^B)-1)*(1); % Take FFT
fftout = abs(fft((D/(2^(N-1)))))/(2^B)/Vref*2;
fftoutdB = 20*log10(fftout+1e-20);
%plot(fftoutdB(1:(2^B)/2));
plot(f(1:(2^B)/2)/(2^B),fftoutdB(1:(2^B)/2));
title('Ideal ADC with No Non-Linearity')
xlabel('Normalized Frequency')
ylabel('Magnitude')
Nfft = 2^B;
x_fft=fft(D,Nfft)*2/Nfft;
x_power=abs(x_fft.*conj(x_fft));
xsort=sort(x_power(1:Nfft/2),'descend');
sig_power = xsort(1);
thd_1to6 = sum(xsort(2:7))
thd=10*log10(sig_power/thd_1to6)
snr=10*log10(sig_power/sum(xsort(10:end)))
text( 0.15, snr-100, sprintf('SNR = %5.0fdB',snr));
toc