284 lines
12 KiB
Matlab
284 lines
12 KiB
Matlab
classdef iio_sys_obj < matlab.System & matlab.system.mixin.Propagates ...
|
|
& matlab.system.mixin.CustomIcon
|
|
% iio_sys_obj System Object block for IIO devices
|
|
|
|
properties
|
|
% Public, tunable properties.
|
|
end
|
|
|
|
properties (Access = protected)
|
|
% Protected class properties.
|
|
|
|
% ip_address IP address
|
|
ip_address = '';
|
|
|
|
%dev_name Device name
|
|
dev_name = '';
|
|
|
|
%in_ch_size Input channel size [samples]
|
|
in_ch_size = 8192;
|
|
|
|
%in_ch_no Number of active input channels
|
|
in_ch_no = 1;
|
|
|
|
%out_ch_size Output channel size [samples]
|
|
out_ch_size = 8192;
|
|
|
|
%ot_ch_no Number of active output channels
|
|
out_ch_no = 1;
|
|
end
|
|
|
|
properties (Access = private)
|
|
% Private class properties.
|
|
libname = 'libiio';
|
|
hname = 'iio.h';
|
|
iio_ctx = {};
|
|
iio_dev = {};
|
|
iio_buffer = {};
|
|
iio_channel = {};
|
|
iio_buf_size = 8192;
|
|
iio_scan_elements_no = 0;
|
|
end
|
|
|
|
properties (DiscreteState)
|
|
end
|
|
|
|
methods
|
|
% Constructor
|
|
function obj = iio_sys_obj(varargin)
|
|
% Support name-value pair arguments when constructing the object.
|
|
setProperties(obj,nargin,varargin{:});
|
|
end
|
|
end
|
|
|
|
methods (Access = protected)
|
|
%% Common functions
|
|
function setupImpl(obj,u)
|
|
% Implement tasks that need to be performed only once,
|
|
% such as pre-computed constants.
|
|
|
|
[notfound, warnings]= loadlibrary(obj.libname, obj.hname);
|
|
|
|
if(libisloaded(obj.libname))
|
|
% Create network context
|
|
obj.iio_ctx = calllib(obj.libname, 'iio_create_network_context', obj.ip_address);
|
|
|
|
% Check if the network context is valid
|
|
ctx_valid = calllib(obj.libname, 'iio_context_valid', obj.iio_ctx);
|
|
if(ctx_valid < 0)
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
msgbox('Could not connect to the IIO server!', 'Error','error');
|
|
return;
|
|
end
|
|
|
|
% Get the number of devices
|
|
nb_devices = calllib(obj.libname, 'iio_context_get_devices_count', obj.iio_ctx);
|
|
|
|
% If no devices are present unload the library and exit
|
|
if(nb_devices == 0)
|
|
calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx);
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
msgbox('No devices were detected in the system!', 'Error','error');
|
|
return;
|
|
end
|
|
|
|
% Detect if the targeted device is installed and activate
|
|
% the number of desired channels
|
|
for i = 0 : nb_devices-1
|
|
dev = calllib(obj.libname, 'iio_context_get_device', obj.iio_ctx, i);
|
|
name = calllib(obj.libname, 'iio_device_get_name', dev);
|
|
if(strcmp(name, obj.dev_name))
|
|
% Get the number of channels that the device has
|
|
obj.iio_dev = dev;
|
|
nb_channels = calllib(obj.libname, 'iio_device_get_channels_count', dev);
|
|
if(nb_channels == 0)
|
|
calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx);
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
msgbox('The seleted device does not have any channels!', 'Error','error');
|
|
return;
|
|
end
|
|
|
|
% Enable the system object input channels
|
|
if(obj.in_ch_no ~= 0)
|
|
% Check if the device has output channels. The
|
|
% logic here assumes that a device can have
|
|
% only input or only output channels
|
|
obj.iio_channel{1} = calllib(obj.libname, 'iio_device_get_channel', dev, 0);
|
|
is_output = calllib(obj.libname, 'iio_channel_is_output', obj.iio_channel{1});
|
|
if(is_output == 0)
|
|
calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx);
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
msgbox('The seleted device does not have output channels!', 'Error','error');
|
|
return;
|
|
end
|
|
% Enable all the channels
|
|
for j = 0 : nb_channels-1
|
|
obj.iio_channel{j+1} = calllib(obj.libname, 'iio_device_get_channel', dev, j);
|
|
calllib(obj.libname, 'iio_channel_enable', obj.iio_channel{j+1});
|
|
is_scan_element = calllib(obj.libname, 'iio_channel_is_scan_element', obj.iio_channel{j+1});
|
|
if(is_scan_element == 1)
|
|
obj.iio_scan_elements_no = obj.iio_scan_elements_no + 1;
|
|
end
|
|
end
|
|
|
|
% Create the IIO buffer used to read / write data
|
|
obj.iio_buf_size = obj.in_ch_size * obj.in_ch_no;
|
|
obj.iio_buffer = calllib(obj.libname, 'iio_device_create_buffer', dev,...
|
|
obj.in_ch_size * (obj.in_ch_no / obj.iio_scan_elements_no), 1);
|
|
end
|
|
|
|
% Enable the system object output channels
|
|
if(obj.out_ch_no ~= 0)
|
|
% Check if the device has input channels. The
|
|
% logic here assumes that a device can have
|
|
% only input or only output channels
|
|
obj.iio_channel{1} = calllib(obj.libname, 'iio_device_get_channel', dev, 0);
|
|
is_output = calllib(obj.libname, 'iio_channel_is_output', obj.iio_channel{1});
|
|
if(is_output == 1)
|
|
calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx);
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
msgbox('The seleted device does not have input channels!', 'Error','error');
|
|
return;
|
|
end
|
|
% Enable the channels
|
|
if(obj.out_ch_no <= nb_channels)
|
|
nb_channels = obj.out_ch_no;
|
|
end
|
|
for j = 0 : nb_channels-1
|
|
obj.iio_channel{j+1} = calllib(obj.libname, 'iio_device_get_channel', dev, j);
|
|
calllib(obj.libname, 'iio_channel_enable', obj.iio_channel{j+1});
|
|
end
|
|
for j = nb_channels:obj.out_ch_no-1
|
|
obj.iio_channel{j+1} = calllib(obj.libname, 'iio_device_get_channel', dev, j);
|
|
calllib(obj.libname, 'iio_channel_disable', obj.iio_channel{j+1});
|
|
end
|
|
% Create the IIO buffer used to read / write data
|
|
obj.iio_buf_size = obj.out_ch_size * nb_channels;
|
|
obj.iio_buffer = calllib(obj.libname, 'iio_device_create_buffer', dev, obj.iio_buf_size, 0);
|
|
end
|
|
|
|
return;
|
|
end
|
|
clear dev;
|
|
end
|
|
|
|
% The target device was not detected, display an error and
|
|
% unload the library
|
|
calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx);
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
msgbox('Could not find target device!', 'Error','error');
|
|
else
|
|
% Could not load library
|
|
msgbox('Could not load library!', 'Error','error');
|
|
end
|
|
end
|
|
|
|
function releaseImpl(obj)
|
|
% Release any resources used by the system object
|
|
if(libisloaded(obj.libname))
|
|
calllib(obj.libname, 'iio_buffer_destroy', obj.iio_buffer);
|
|
calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx);
|
|
obj.iio_buffer = {};
|
|
obj.iio_channel = {};
|
|
obj.iio_dev = {};
|
|
obj.iio_ctx = {};
|
|
unloadlibrary(obj.libname);
|
|
end
|
|
end
|
|
|
|
function varargout = stepImpl(obj, varargin)
|
|
% Implement data capture flow.
|
|
if(getNumOutputs(obj) ~= 0)
|
|
varargout = cell(1, getNumOutputs(obj));
|
|
if(libisloaded(obj.libname))
|
|
calllib(obj.libname, 'iio_buffer_refill', obj.iio_buffer);
|
|
data = calllib(obj.libname, 'iio_buffer_first', obj.iio_buffer, obj.iio_channel{1});
|
|
setdatatype(data, 'int16Ptr', obj.iio_buf_size);
|
|
for i = 1:getNumOutputs(obj)
|
|
varargout{i} = double(data.Value(i:getNumOutputs(obj):end));
|
|
end
|
|
else
|
|
for i = 1:getNumOutputs(obj)
|
|
varargout{i} = zeros(obj.out_ch_size, 1);
|
|
end
|
|
end
|
|
end
|
|
|
|
% Implement data transmit flow.
|
|
if(getNumInputs(obj) ~= 0)
|
|
if(libisloaded(obj.libname))
|
|
data = calllib(obj.libname, 'iio_buffer_start', obj.iio_buffer);
|
|
setdatatype(data, 'int16Ptr', obj.iio_buf_size);
|
|
for i = 1:getNumInputs(obj)
|
|
data.Value(i:getNumInputs(obj):obj.iio_buf_size) = int16(varargin{i});
|
|
end
|
|
calllib(obj.libname, 'iio_buffer_push', obj.iio_buffer);
|
|
end
|
|
end
|
|
end
|
|
|
|
function resetImpl(obj)
|
|
% Initialize discrete-state properties.
|
|
end
|
|
|
|
function num = getNumInputsImpl(obj)
|
|
% Get number of inputs.
|
|
num = obj.in_ch_no;
|
|
end
|
|
|
|
function num = getNumOutputsImpl(obj)
|
|
% Get number of outputs.
|
|
num = obj.out_ch_no;
|
|
end
|
|
|
|
function varargout = isOutputFixedSizeImpl(obj)
|
|
% Get outputs fixed size.
|
|
varargout = cell(1, getNumOutputs(obj));
|
|
for i = 1:getNumOutputs(obj)
|
|
varargout{i} = true;
|
|
end
|
|
end
|
|
|
|
function varargout = getOutputDataTypeImpl(obj)
|
|
% Get outputs data types.
|
|
varargout = cell(1, getNumOutputs(obj));
|
|
for i = 1:getNumOutputs(obj)
|
|
varargout{i} = 'double';
|
|
end
|
|
end
|
|
|
|
function varargout = isOutputComplexImpl(obj)
|
|
% Get outputs data types.
|
|
varargout = cell(1, getNumOutputs(obj));
|
|
for i = 1:getNumOutputs(obj)
|
|
varargout{i} = false;
|
|
end
|
|
end
|
|
|
|
%% Backup/restore functions
|
|
function s = saveObjectImpl(obj)
|
|
% Save private, protected, or state properties in a
|
|
% structure s. This is necessary to support Simulink
|
|
% features, such as SimState.
|
|
end
|
|
|
|
function loadObjectImpl(obj,s,wasLocked)
|
|
% Read private, protected, or state properties from
|
|
% the structure s and assign it to the object obj.
|
|
end
|
|
|
|
%% Simulink functions
|
|
function z = getDiscreteStateImpl(obj)
|
|
% Return structure of states with field names as
|
|
% DiscreteState properties.
|
|
z = struct([]);
|
|
end
|
|
end
|
|
end
|