%% Design NCO Source
% *Note*: This example runs only in R2016b or later. If you are using an earlier 
% release, replace each call to the function with the equivalent |step| syntax. 
% For example, myObject() becomes step(myObject).
% 
% Design an NCO source according to given specifications.

df = 0.05; % Frequency resolution = 0.05 Hz
minSFDR = 96; % Spurious free dynamic range >= 96 dB
Ts = 1/8000; % Sample period = 1/8000 sec
dphi = pi/2; % Desired phase offset = pi/2;
%% 
% Calculate number of accumulator bits required for the given frequency 
% resolution.
%%
Nacc = ceil(log2(1/(df*Ts)));
%% 
% Actual frequency resolution achieved.
%%
actdf = 1/(Ts*2^Nacc);
%% 
% Calculate number of quantized accumulator bits required from the SFDR 
% requirement
%%
Nqacc = ceil((minSFDR-12)/6);
%% 
% Calculate the phase offset
%%
phOffset = 2^Nacc*dphi/(2*pi);
%% 
% Design the NCO source. 
%%
nco = dsp.NCO('PhaseOffset', phOffset,...
    'NumDitherBits', 4, ...
    'NumQuantizerAccumulatorBits', Nqacc,...
    'SamplesPerFrame', 1/Ts, ...
    'CustomAccumulatorDataType', numerictype([],Nacc));
san = dsp.SpectrumAnalyzer('SampleRate', 1/Ts, ...
    'PlotAsTwoSidedSpectrum', false);
%% 
% View the output of the NCO source on a spectrum analyzer. Change the output 
% frequency in the middle of the simulation from 510 Hz to 1520 Hz.
%%
tic;
while toc < 10
    
    if toc < 5
        F0 = 510;      
    else
        F0 = 1520;     
    end
    % Calculate the phase increment
    phIncr = int32(round(F0*Ts*2^Nacc));
    y = nco(phIncr);
    san(y)
end

%% 
% Copyright 2012 The MathWorks, Inc.