% Create A SineTable for PIC DDS

% **************************************************
%
% (C) Copyright notice
%
% Written by Richard Prinz.
% Copyright 2003 by Richard Prinz.
% OE1RIB Richard.Prinz@MIN.at
%
% Permission to use, copy, and modify this program
% without restriction is hereby granted, as long as
%
% 1) this copyright notice appears in each copy of
%    the program source code and
%
% 2) the source code is not used for commercial
%    purposes.
%
% This program is freely distributable without
% licensing fees and is provided without guarantee
% or warrantee expressed or implied.
%
% This program is -not- in the public domain.
%
% **************************************************


% ----- USER CONFIG -----

TableSize = 256;                % number of elements in sinetable
Floop = 28;                     % number of instructions per DDS loop
Freq = 1000;                    % wanted output Frequency
AccWidth = 3;                   % accumulator width 3 Bytes
fXtal = 4000000;                % main PIC16F84 oscilliator Frequency in Hz

% ----- DON'T CHANGE ANYTHING AFTER HERE -----




format long

disp('***********************************************************************************');

c = 360 / TableSize;
i = 0 : TableSize - 1;
d = c * i;
e = d * pi / 180;
f = sin(e);
g = f * fix((TableSize / 2) - 1);
fSineTable = fix(TableSize / 2) + g;
%iSineTable = fix(fSineTable);
iSineTable = round(fSineTable);

% Plot SineTable
if 1 == 1
    figure(1);
    clf;
    plot(fSineTable, '-ro');
    hold on;
    plot(iSineTable, '-b*');
    title(sprintf('SineTable using %d Elements', TableSize));
    xlabel(sprintf('(comparison between Int and Float Table entries)\nZoom to show details'));
    legend('Float','Int',-1);
end

% fill iSineTable to next 8 digit boundary and reshape
baseSineTable = cat(2, iSineTable, zeros(1, abs( size(iSineTable, 2) - fix( (size(iSineTable, 2) + 7) / 8) * 8)));

% create decimal table for copying into source
disp(sprintf('Decimal Sine Table using %d Elements', TableSize));
disp(' ');
decSineTable = reshape(baseSineTable, 8, size(baseSineTable, 2) / 8);
decSineTable = rot90(decSineTable);
decSineTable = flipud(decSineTable);
disp(decSineTable)

% create hex table for copying into source
disp(sprintf('\nHexadecimal Sine Table using %d Elements', TableSize));
disp(' ');
hexSineTable = cellstr( strcat('0x',dec2base(baseSineTable, 16, 2)));
hexSineTable = reshape(hexSineTable, 8, size(hexSineTable, 1) / 8);
hexSineTable = rot90(hexSineTable);
hexSineTable = flipud(hexSineTable);
%disp(hexSineTable)
for i=1:size(hexSineTable,1)
    disp(sprintf('dt\t\t\t\t%s,%s,%s,%s,%s,%s,%s,%s',char(hexSineTable(i,1)), char(hexSineTable(i,2)), char(hexSineTable(i,3)), char(hexSineTable(i,4)), char(hexSineTable(i,5)), char(hexSineTable(i,6)), char(hexSineTable(i,7)), char(hexSineTable(i,8))));
end

disp('***********************************************************************************');




finst = fXtal / 4;              % pic instructions per second
faccmax = 2^(AccWidth * 8);
ftest = fix(finst / Freq);      % pic instructions possible per 1 period
fconst = (finst / Floop) / faccmax;
fstep = fix(Freq / fconst)

facc = 0;
fsamples = 0;
lastacc = 0;
fsineout = zeros(1, ftest);
ftriangle = zeros(1, ftest);
for i = 1:Floop:ftest
    facc = facc + fstep;
    facchighbyte = mod(fix(facc / 2^((AccWidth - 1) * 8)), TableSize);
    fsineout(1, i:i + Floop) = iSineTable(facchighbyte + 1);
    ftriangle(1, i:i + Floop) = facchighbyte + 1;
    if lastacc ~= facchighbyte
        fsamples = fsamples + 1;
    end
    lastacc = facchighbyte;
end
figure(2);
clf;
%plot(fres,'-rs','MarkerSize',2);
plot(fsineout,'-r');
hold on;
plot(ftriangle,'--b');
grid on;
title(sprintf('PicDDS Sine Plot (%d Hz)', Freq));
ylabel('SineTable Value');
xlabel(sprintf('1 Period allows %d PIC Instructions =\n%.6f seconds = %d SineTab Samples = %d Cycles/Sample', ftest, (1/finst)*ftest, fsamples, Floop));
legend('Sine','SawTooth',1);
%fres

