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