% Copyright 2014(c) Analog Devices, Inc. % % All rights reserved. % % Redistribution and use in source and binary forms, with or without modification, % are permitted provided that the following conditions are met: % - Redistributions of source code must retain the above copyright % notice, this list of conditions and the following disclaimer. % - Redistributions in binary form must reproduce the above copyright % notice, this list of conditions and the following disclaimer in % the documentation and/or other materials provided with the % distribution. % - Neither the name of Analog Devices, Inc. nor the names of its % contributors may be used to endorse or promote products derived % from this software without specific prior written permission. % - The use of this software may or may not infringe the patent rights % of one or more patent holders. This license does not release you % from the requirement that you obtain separate licenses from these % patent holders to use this software. % - Use of the software either in source or binary form or filter designs % resulting from the use of this software, must be connected to, run % on or loaded to an Analog Devices Inc. component. % % THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, % INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A % PARTICULAR PURPOSE ARE DISCLAIMED. % % IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, % EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY % RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR % BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, % STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF % THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. classdef libiio_if < handle % libiio_if Interface object for for IIO devices %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Protected properties %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% properties (Access = protected) libname = 'libiio'; hname = 'iio-wrapper.h'; dev_name = ''; data_ch_no = 0; data_ch_size = 0; dev_type = ''; iio_ctx = {}; iio_dev = {}; iio_buffer = {}; iio_channel = {}; iio_buf_size = 8192; iio_scan_elm_no = 0; if_initialized = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Static private methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% methods (Static, Access = private) function out = modInstanceCnt(val) % Manages the number of object instances to handle proper DLL unloading persistent instance_cnt; if isempty(instance_cnt) instance_cnt = 0; end instance_cnt = instance_cnt + val; out = instance_cnt; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Protected methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% methods (Access = protected) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Creates the network context %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, err_msg, msg_log] = createNetworkContext(obj, ip_address) % Initialize the return values ret = -1; err_msg = ''; msg_log = []; % Create the network context obj.iio_ctx = calllib(obj.libname, 'iio_create_network_context', ip_address); % Check if the network context is valid if (isNull(obj.iio_ctx)) obj.iio_ctx = {}; err_msg = 'Could not connect to the IIO server!'; return; end % Increase the object's instance count libiio_if.modInstanceCnt(1); msg_log = [msg_log sprintf('%s: Connected to IP %s\n', class(obj), ip_address)]; % Set the return code to success ret = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Releases the network context and unload the libiio library %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function releaseContext(obj) calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx); obj.iio_ctx = {}; instCnt = libiio_if.modInstanceCnt(-1); if(instCnt == 0) unloadlibrary(obj.libname); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Checks the compatibility of the different software modules. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, err_msg, msg_log] = checkVersions(obj) % Initialize the return values ret = -1; err_msg = ''; msg_log = []; % Create a set of pointers to read the iiod and dll versions data = zeros(1, 10); remote_pMajor = libpointer('uint32Ptr', data(1)); remote_pMinor = libpointer('uint32Ptr', data(2)); remote_pGitTag = libpointer('int8Ptr', [int8(data(3:end)) 0]); local_pMajor = libpointer('uint32Ptr', data(1)); local_pMinor = libpointer('uint32Ptr', data(2)); local_pGitTag = libpointer('int8Ptr', [int8(data(3:end)) 0]); % get remote libiio version calllib(obj.libname, 'iio_context_get_version', obj.iio_ctx, remote_pMajor, remote_pMinor, remote_pGitTag); % extract git hash without trailing null char remote_githash = remote_pGitTag.Value(1:7); remote_version_str = sprintf('Remote libiio version: %d.%d, (git-%s)', remote_pMajor.Value, remote_pMinor.Value, remote_githash); msg_log = [msg_log sprintf('%s: %s\n', class(obj), remote_version_str)]; % get local libiio version calllib(obj.libname, 'iio_library_get_version', local_pMajor, local_pMinor, local_pGitTag); local_githash = local_pGitTag.Value(1:7); local_version_str = sprintf('Local libiio version: %d.%d, (git-%s)', local_pMajor.Value, local_pMinor.Value, local_githash); msg_log = [msg_log sprintf('%s: %s\n', class(obj), local_version_str)]; if(remote_pMajor.Value < local_pMajor.Value) err_msg = ['The libiio version running on the device is outdated! ' ... 'Run the adi_update_tools.sh script to get libiio up to date.']; return; elseif(remote_pMajor.Value > local_pMajor.Value) err_msg = ['The libiio version on the local host is outdated! ' ... 'On Windows, reinstall the dll using the latest installer ' ... 'from the Analog Devices wiki.']; return; end % Set the return code to success ret = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Detect if the specified device is present in the system %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, err_msg, msg_log] = initDevice(obj, dev_name) % Initialize the return values ret = -1; err_msg = ''; msg_log = []; % Store the device name obj.dev_name = dev_name; % Get the number of devices nb_devices = calllib(obj.libname, 'iio_context_get_devices_count', obj.iio_ctx); % If no devices are present return with error if(nb_devices == 0) err_msg = 'No devices were detected in the system!'; return; end msg_log = [msg_log sprintf('%s: Found %d devices in the system\n', class(obj), nb_devices)]; % Detect if the targeted device is installed dev_found = 0; 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, dev_name)) obj.iio_dev = dev; dev_found = 1; break; end clear dev; end % Check if the target device was detected if(dev_found == 0) err_msg = 'Could not find target configuration device!'; return; end msg_log = [msg_log sprintf('%s: %s was found in the system\n', class(obj), obj.dev_name)]; % Set the return code to success ret = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Initializes the output data channels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, err_msg, msg_log] = initOutputDataChannels(obj, ch_no, ch_size) % Initialize the return values ret = -1; err_msg = ''; msg_log = []; % Save the number of channels and size obj.data_ch_no = ch_no; obj.data_ch_size = ch_size; % Get the number of channels that the device has nb_channels = calllib(obj.libname, 'iio_device_get_channels_count', obj.iio_dev); if(nb_channels == 0) err_msg = 'The selected device does not have any channels!'; return; end % Enable the data channels if(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', obj.iio_dev, 0); is_output = calllib(obj.libname, 'iio_channel_is_output', obj.iio_channel{1}); if(is_output == 0) err_msg = 'The selected device does not have output channels!'; return; end % Enable all the channels for j = 0 : nb_channels - 1 obj.iio_channel{j+1} = calllib(obj.libname, 'iio_device_get_channel', obj.iio_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_elm_no = obj.iio_scan_elm_no + 1; end end msg_log = [msg_log sprintf('%s: Found %d output channels for the device %s\n', class(obj), obj.iio_scan_elm_no, obj.dev_name)]; % Check if the number of channels in the device % is greater or equal to the system object % input channels if(obj.iio_scan_elm_no < ch_no) obj.iio_channel = {}; err_msg = 'The selected device does not have enough output channels!'; return; end % Enable the DAC buffer output obj.if_initialized = 1; ret = writeAttributeString(obj, 'altvoltage0*raw', '0'); obj.if_initialized = 0; if(ret < 0) obj.iio_channel = {}; err_msg = 'Could not enable the DAC buffer output!'; return; end % Create the IIO buffer used to write data obj.iio_buf_size = obj.data_ch_size * obj.iio_scan_elm_no; obj.iio_buffer = calllib(obj.libname, 'iio_device_create_buffer', obj.iio_dev,... obj.data_ch_size, 1); end msg_log = [msg_log sprintf('%s: %s output data channels successfully initialized\n', class(obj), obj.dev_name)]; % Set the return code to success ret = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Initializes the input data channels %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, err_msg, msg_log] = initInputDataChannels(obj, ch_no, ch_size) % Initialize the return values ret = -1; err_msg = ''; msg_log = []; % Save the number of channels and size obj.data_ch_no = ch_no; obj.data_ch_size = ch_size; % Get the number of channels that the device has nb_channels = calllib(obj.libname, 'iio_device_get_channels_count', obj.iio_dev); if(nb_channels == 0) err_msg = 'The selected device does not have any channels!'; return; end % Enable the system object output channels if(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', obj.iio_dev, 0); is_output = calllib(obj.libname, 'iio_channel_is_output', obj.iio_channel{1}); if(is_output == 1) err_msg = 'The selected device does not have input channels!'; return; end msg_log = [msg_log sprintf('%s: Found %d input channels for the device %s\n', class(obj), nb_channels, obj.dev_name)]; % Check if the number of channels in the device % is greater or equal to the system object % output channels if(nb_channels < ch_no) obj.iio_channel = {}; err_msg = 'The selected device does not have enough input channels!'; return; end % Enable the channels for j = 0 : ch_no - 1 obj.iio_channel{j+1} = calllib(obj.libname, 'iio_device_get_channel', obj.iio_dev, j); calllib(obj.libname, 'iio_channel_enable', obj.iio_channel{j+1}); end for j = ch_no : nb_channels - 1 obj.iio_channel{j+1} = calllib(obj.libname, 'iio_device_get_channel', obj.iio_dev, j); calllib(obj.libname, 'iio_channel_disable', obj.iio_channel{j+1}); end % Create the IIO buffer used to read data obj.iio_buf_size = obj.data_ch_size * obj.data_ch_no; obj.iio_buffer = calllib(obj.libname, 'iio_device_create_buffer', obj.iio_dev, obj.iio_buf_size, 0); end msg_log = [msg_log sprintf('%s: %s input data channels successfully initialized\n', class(obj), obj.dev_name)]; % Set the return code to success ret = 0; end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Public methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% methods %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Constructor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function obj = libiio_if() % Constructor obj.if_initialized = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Destructor %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function delete(obj) % Release any resources used by the system object. if((obj.if_initialized == 1) && libisloaded(obj.libname)) if(~isempty(obj.iio_buffer)) calllib(obj.libname, 'iio_buffer_destroy', obj.iio_buffer); end if(~isempty(obj.iio_ctx)) calllib(obj.libname, 'iio_context_destroy', obj.iio_ctx); end obj.iio_buffer = {}; obj.iio_channel = {}; obj.iio_dev = {}; obj.iio_ctx = {}; instCnt = libiio_if.modInstanceCnt(-1); if(instCnt == 0) unloadlibrary(obj.libname); end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Initializes the libiio interface %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, err_msg, msg_log] = init(obj, ip_address, ... dev_name, dev_type, ... data_ch_no, data_ch_size) % Initialize the return values ret = -1; err_msg = ''; msg_log = []; % Save the device type obj.dev_type = dev_type; % Set the initialization status to fail obj.if_initialized = 0; % Load the libiio library if(~libisloaded(obj.libname)) try % ignore unknown type warnings due to header parsing limitations warnState = warning('off', 'MATLAB:loadlibrary:TypeNotFound'); cleanupObj = onCleanup(@()warning(warnState)); [notfound, warnings] = loadlibrary(obj.libname, obj.hname, 'addheader', 'iio.h'); cleanupObj = []; % restore the warning state catch exception err_msg = exception.message; return; end end if(~libisloaded(obj.libname)) err_msg = 'Could not load the libiio library!'; return; end % Create the network context [ret, err_msg, msg_log] = createNetworkContext(obj, ip_address); if(ret < 0) return; end % Check the software versions [ret, err_msg, msg_log_new] = checkVersions(obj); msg_log = [msg_log msg_log_new]; if(ret < 0) releaseContext(obj); return; end % Initialize the device [ret, err_msg, msg_log_new] = initDevice(obj, dev_name); msg_log = [msg_log msg_log_new]; if(ret < 0) releaseContext(obj); return; end % Initialize the output data channels if(strcmp(dev_type, 'OUT')) [ret, err_msg, msg_log_new] = initOutputDataChannels(obj, data_ch_no, data_ch_size); msg_log = [msg_log msg_log_new]; if(ret < 0) releaseContext(obj); return; end end % Initialize the input data channels if(strcmp(dev_type, 'IN')) [ret, err_msg, msg_log_new] = initInputDataChannels(obj, data_ch_no, data_ch_size); msg_log = [msg_log msg_log_new]; if(ret < 0) releaseContext(obj); return; end end % Set the initialization status to success obj.if_initialized = 1; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Implement the data capture flow %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, data] = readData(obj) % Initialize the return values ret = -1; data = cell(1, obj.data_ch_no); for i = 1 : obj.data_ch_no data{i} = zeros(obj.data_ch_size, 1); end % Check if the interface is initialized if(obj.if_initialized == 0) return; end % Check if the device type is output if(~strcmp(obj.dev_type, 'IN')) return; end % Read the data calllib(obj.libname, 'iio_buffer_refill', obj.iio_buffer); buffer = calllib(obj.libname, 'iio_buffer_first', obj.iio_buffer, obj.iio_channel{1}); setdatatype(buffer, 'int16Ptr', obj.iio_buf_size); for i = 1 : obj.data_ch_no data{i} = double(buffer.Value(i:obj.data_ch_no:end)); end % Set the return code to success ret = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Implement the data transmit flow %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function ret = writeData(obj, data) % Initialize the return values ret = -1; % Check if the interface is initialized if(obj.if_initialized == 0) return; end % Check if the device type is input if(~strcmp(obj.dev_type, 'OUT')) return; end % Destroy the buffer calllib(obj.libname, 'iio_buffer_destroy', obj.iio_buffer); obj.iio_buffer = {}; % Enable the DAC buffer output ret = writeAttributeString(obj, 'altvoltage0*raw', '0'); if(ret < 0) obj.iio_channel = {}; err_msg = 'Could not enable the DAC buffer output!'; return; end % Create the IIO buffer used to write data obj.iio_buf_size = obj.data_ch_size * obj.iio_scan_elm_no; obj.iio_buffer = calllib(obj.libname, 'iio_device_create_buffer', obj.iio_dev,... obj.data_ch_size, 1); % Transmit the data buffer = calllib(obj.libname, 'iio_buffer_start', obj.iio_buffer); setdatatype(buffer, 'int16Ptr', obj.iio_buf_size); for i = 1 : obj.data_ch_no buffer.Value(i : obj.iio_scan_elm_no : obj.iio_buf_size) = int16(data{i}); end for i = obj.data_ch_no + 1 : obj.iio_scan_elm_no buffer.Value(i : obj.iio_scan_elm_no : obj.iio_buf_size) = 0; end calllib(obj.libname, 'iio_buffer_push', obj.iio_buffer); % Set the return code to success ret = 0; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Find an attribute based on the name. The name can contain wildcard '*' characters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, ch, attr] = findAttribute(obj, attr_name) % Initialize the return values ret = -1; ch = 0; attr = ''; % Check if the interface is initialized if(obj.if_initialized == 0) return; end % Check if this is a device attribute name = calllib(obj.libname, 'iio_device_find_attr', obj.iio_dev, attr_name); if(~isempty(name)) ret = 0; return; end % This is a channel attribute, search for the corresponding channel chn_no = calllib(obj.libname, 'iio_device_get_channels_count', obj.iio_dev); for k = 0 : chn_no - 1 ch = calllib(obj.libname, 'iio_device_get_channel', obj.iio_dev, k); attr_no = calllib(obj.libname, 'iio_channel_get_attrs_count', ch); attr_found = 0; for l = 0 : attr_no - 1 attr = calllib(obj.libname, 'iio_channel_get_attr', ch, l); name = calllib(obj.libname, 'iio_channel_attr_get_filename', ch, attr); % The attribute to find can contain wildcard '*' characters, % search for all the substrings in the attribute name str_find = strsplit(attr_name, '*'); str_find = str_find(find(~strcmp(str_find, ''))); has_wildcard = ~isempty(strfind(attr_name, '*')); attr_found = 1; for i = 1 : length(str_find) if(has_wildcard == 0) ret = strcmp(name, str_find{i}); if(ret == 0) ret = []; end else ret = strfind(name, str_find{i}); end if(isempty(ret)) attr_found = 0; break; end end if(attr_found == 1) break; end clear attr; end % Check if the attribute was found if(attr_found == 0) clear ch; else ret = 1; break; end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Read an attribute as a double value %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, val] = readAttributeDouble(obj, attr_name) % Find the attribute [ret, ch, attr] = findAttribute(obj, attr_name); if(ret < 0) val = 0; return; end % Create a double pointer to be used for data read data = zeros(1, 10); pData = libpointer('doublePtr', data(1)); % Read the attribute value if(ret > 0) calllib(obj.libname, 'iio_channel_attr_read_double', ch, attr, pData); clear ch; clear attr; else calllib(obj.libname, 'iio_device_attr_read_double', obj.iio_dev, attr_name, pData); end val = pData.Value; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Read an attribute as a string value %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [ret, val] = readAttributeString(obj, attr_name) % Find the attribute [ret, ch, attr] = findAttribute(obj, attr_name); if(ret < 0) val = ''; return; end % Create a pointer to be used for data read data = char(ones(1, 512)); pData = libpointer('stringPtr', data); % Read the attribute value if(ret > 0) [~, ~, ~, val] = calllib(obj.libname, 'iio_channel_attr_read', ch, attr, pData, 512); clear ch; clear attr; else [~, ~, ~, val] = calllib(obj.libname, 'iio_device_attr_read', obj.iio_dev, attr_name, pData, 512); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Write a string double value %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function ret = writeAttributeDouble(obj, attr_name, val) % Find the attribute [ret, ch, attr] = findAttribute(obj, attr_name); if(ret < 0) return; end % Write the attribute if(ret > 0) calllib(obj.libname, 'iio_channel_attr_write_double', ch, attr, val); clear ch; clear attr; else calllib(obj.libname, 'iio_device_attr_write_double', obj.iio_dev, attr_name, val); end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Write a string attribute value %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function ret = writeAttributeString(obj, attr_name, str) % Find the attribute [ret, ch, attr] = findAttribute(obj, attr_name); if(ret < 0) return; end % Write the attribute if(ret > 0) calllib(obj.libname, 'iio_channel_attr_write', ch, attr, str); clear ch; clear attr; else calllib(obj.libname, 'iio_device_attr_write', obj.iio_dev, attr_name, str); end end end end