%

% Copyright 2012 The MathWorks, Inc.

classdef BandwidthOutgoingTest < coder.rtiostreamtest.Test
% BANDWIDTHOUTGOINGTEST determines PC to target link bandwidth
% Makes the pc send large amount of data and checks whether the
% device reports that the data was received correctly. The data is
% just an eight bit counter which wraps around.
%
% Parameters:
%
% pcSize -
% The amount of data that the PC receives in one go (in
% memory chunks)
% targetSize -
% The amount of data the target sends in one go (in memory
% chunks)
% size -
% The total amount of data that will be transmitted between
% the client and the server (in memory chunks)

% Available parameters defined here
properties (Constant)
param_pcSize = 'pcSize';
param_targetSize = 'targetSize';
param_size = 'size';

default_pcSize = 1; % 1 chunk at a time
default_targetSize = 1; % 1 chunk at a time
default_size = 100; % 100 chunks
end

methods (Static)

function [pcSize, targetSize, size] = getParameters(parameters)
% GETPARAMETERS parse parameters into local variables

import coder.rtiostreamtest.*;

pcSize = Test.getSetting(parameters, BandwidthOutgoingTest.param_pcSize, BandwidthOutgoingTest.default_pcSize);
targetSize = Test.getSetting(parameters, BandwidthOutgoingTest.param_targetSize, BandwidthOutgoingTest.default_targetSize);
size = uint32(Test.getSetting(parameters, BandwidthOutgoingTest.param_size, BandwidthOutgoingTest.default_size));
end

end

methods

function this = BandwidthOutgoingTest(name)
if nargin == 0, name = 'BandwidthOutgoingTest.m'; end;
this = this@coder.rtiostreamtest.Test(name);
end

function processThroughput = runTest(~, connection, parameters)
% PROCESSTHROUGHPUT is in B/s
% dimensions

try
%% Initialization
[pcSize, targetSize, size] = coder.rtiostreamtest.BandwidthOutgoingTest.getParameters(parameters);

if targetSize > connection.targetBufferSize
coder.rtiostreamtest.Test.warning('WarningOutgoingSubtestsSkipped', ...
targetSize, connection.targetBufferSize);
processThroughput = 0;
return;
end

dataToSend =...
coder.rtiostreamtest.ServerConnection.generateFastData(size);

% Build the macro
connection.sendCommandAndAck( ...
connection.op_macro_repeat_start);

connection.sendCommandAndAck( ...
connection.op_macro_blockRcvFast, targetSize);

connection.sendCommandAndAck( ...
connection.op_macro_repeat, ...
idivide(size, targetSize));

% If data does not exactly divide
remainder = mod(size, targetSize);
if remainder ~= 0
connection.sendCommandAndAck( ...
connection.op_macro_blockRcvFast, remainder);
end

%% Time critical section

processTic = tic;

% Start macro
connection.sendCommand(connection.op_macro_run);

% Send data
for k = 1 : pcSize : size
% Make sure we don't try to send more than we need to
last = k + pcSize - 1;
if last > size
last = size;
end

% Send to target
connection.blockingSend( ...
dataToSend(k : last));
end

% Wait for confirmation that the test was successful
connection.waitForAck;

elapsed = toc(processTic);

processThroughput = double(size * connection.memUnitSize) / elapsed;

catch origException
% add generic message
[errMsg, errId] = DAStudio.message('Connectivity:RtIOStreamTest:InfoOutgoingError', ...
size, pcSize, targetSize);
exception = MException(errId, '%s', errMsg);
exception = exception.addCause(origException);
throw(exception);
end
end

end
end