% plots characteristics and INL/DNL of ADC
% selected by choice
%

choice = 8;
qerror = 0;     % 1--> so quantizer error, 0--> don't show

% resolution of INL/DNL (e.g. 0.1 LSB)
if choice < 8
    res = 0.006;
else
    res = 0.5;
end

delta = 1;      % nominal spacing between levels (input & output)

% compute converter thresholds "th"
switch choice
case 1
   % perfect 3-bit ADC
   th = 0.5:6.5;
case 2
    % gain and offset
   th = 0.9:0.8:6.8;
case 3
   % 3-bit with DNL= +/- 0.4LSB
   th = [ 0.5 1.5 2.9 3.9 4.9 5.5 6.5 ];
case 4
   % 3-bit with DNL=+1/-2  INL=+1/-1  (non-monotonic)
   th = [ 0.5 1.5 2.5 4.7 4.5 5.5 6.5 7.5 ];
case 5
   % 3-bit with missing code
   th = [ 0.5 1.5 2.5 4.0 4.0 5.5 6.5 7.5 ];
case 6
    % inl
    th = (0.5:6.5) - 3.5;
    th = th + ((-3:3) .^ 2)/9;
    th = th + 2.5
 case 7
   th = [ 1 1 3 3 5 5 7 7 ];
case 8
   th = bwlevels(12, 0.01);
case 9
   th = uelevels(12, 0.01);
otherwise
   warning('no ADC defined for this choice');
end

minth = min(th);
maxth = max(th);
N = length(th);

xx = linspace(minth-2*delta, maxth+2*delta, (maxth-minth)/res);
yy = adc(xx, th);

% plot i/o characteristics
figure(1);  clf;
subplot(qerror+1, 1, 1);
ideal = [ floor(minth) ceil(maxth) ];
xmin = ideal(1) - delta;
xmax = ideal(2) + delta;
ymin = ideal(1) - 0.8;
ymax = ideal(2) + 0.8;
plot(xx, yy, 'bo');
hold on;
plot(ideal, ideal, 'g:');
axis([ xmin xmax ymin ymax ]);
if N < 20
    th0 = [ xmin 0.5:delta:N xmax ];
    d = 0:length(th0)-1;
    d(length(d)-1:length(d)) = N;
    stairs(th0, d, 'r');
    plot(0:N, 0:N, 'ro');
    legend('ADC characteristics', 'ideal converter', 2);
end
ylabel('Digital Output Code');
title(sprintf('A/D Characteristics [%d]', choice));
fixfig;

% quantization error
if qerror == 1
    subplot(2, 1, 2);
    plot(xx, yy-xx', 'o');
    ylabel('Quantization error  [LSB]');
    axis([ideal(1)-delta ideal(2)+delta -delta delta]);
    fixfig;
end
xlabel('ADC Input Voltage  [1/\Delta]');
hold off;

% inl/dnl
figure(2);
inldnl_th(th);

if (choice > 7)
    return
end

figure(3);
inldnl(yy, delta);

% histogram

% compute histogram
[counts,centers] = hist(yy, min(yy):delta:max(yy));
figure(4);
bar(centers, counts);
xlabel('ADC output code');
ylabel('Counts');
fixfig;

% eliminate end bins
counts(1)   = 0;
counts(end) = 0;
figure(5);
bar(centers, counts);
xlabel('ADC output code');
ylabel('Counts, End bins removed');
fixfig;

% normalize
dnl = counts/(sum(counts)/(length(counts)-2)) - 1;
dnl(1)   = 0;
dnl(end) = 0;
figure(6);
bar(centers, dnl);
xlabel('ADC output code');
ylabel('DNL = Counts / Mean(Counts)');
fixfig;

% inl
figure(7);
r = cumsum([-0.5  dnl+1]);
stairs(r, [ 0:7 7 ]);
hold on;
plot([ 0 7 ], [ 0 7 ], 'g:');
axis([ -1 8 -0.6 7.6 ]);
xlabel('ADC Input Voltage');
ylabel('Reconstructed Characteristic');
fixfig;
