%% Control Output Rate When Upsampling
% Convert a signal from 40 MHz to 100 MHz by using the dsp.HDLFIRRateConverter System object™. Use the optional request input signal to control the output data rate. When the object receives the request signal, it returns a new output data sample. This example models a clock rate of 200 MHz by requesting an output sample every second call to the object.
% Define the sample rate and length of the input signal, and a fixed-point cosine waveform. Create a SignalSource object to provide data samples on demand.

Fs = 40e6;                                  
Ns = 50;                                    
t = (0:Ns-1).'/Fs;                          
x = fi(cos(2*pi*1.2e6*t),1,16,14);          
inputSource = dsp.SignalSource(x);

%
% Define the rate conversion parameters. Use an interpolation factor of 5 and a decimation factor of 2. Determine the number of calls to the object needed to convert Ns samples.

L = 5;                                      
M = 2;                 
numSteps = floor(2*Ns*L/M);

%
% Create the HDL FIR rate converter System object. Configure it to perform rate conversion using the specified factors and an equiripple FIR filter. Enable the optional ready and request ports.

Numerator = firpm(70,[0 0.15 0.25 1],[1 1 0 0]);      
rateConverter = dsp.HDLFIRRateConverter(L,M,Numerator,...
                                        'ReadyPort',true,...
                                        'RequestPort',true);

%
% Create a Logic Analyzer to capture and view the input and output signals.

la = dsp.LogicAnalyzer('NumInputPorts',6,'SampleTime',1/Fs,'TimeSpan',numSteps/Fs);
modifyDisplayChannel(la,1,'Name','dataIn','Format','Analog','Height',8)
modifyDisplayChannel(la,2,'Name','validIn')
modifyDisplayChannel(la,3,'Name','request')
modifyDisplayChannel(la,4,'Name','dataOut','Format','Analog','Height',8)
modifyDisplayChannel(la,5,'Name','validOut')
modifyDisplayChannel(la,6,'Name','ready')

%
% Generate a signal that requests a new output sample every second call to the object.

request = false(numSteps,1);
request(1:2:end) = true;

%
% Initialize the ready signal. The object is always ready for input data on the first call.

ready = true;

%
% Call the System object to perform the rate conversion and obtain each output sample. Apply a new input sample when the object indicates it is ready. Otherwise, set validIn to false. The object returns valid output samples when request is set to true.
% Note: This object syntax runs only in R2016b or later. If you are using an earlier release, replace each call of an object with the equivalent step syntax. For example, replace myObject(x) with step(myObject,x).

for k = 1:numSteps  
    if ready
        dataIn = inputSource();
    end
    validIn = ready;
    [dataOut,validOut,ready] = rateConverter(dataIn,validIn,request(k));
    la(dataIn,validIn,request(k),dataOut,validOut,ready)    
end

%
% Copyright 2012 The MathWorks, Inc.