diff --git a/+adi/+libiio/attribute.m b/+adi/+libiio/attribute.m index fb538243..f5b7e2ae 100644 --- a/+adi/+libiio/attribute.m +++ b/+adi/+libiio/attribute.m @@ -1,18 +1,118 @@ classdef attribute < handle - % methods - % function obj = attribute() - % % CHANNEL constructor method for matlabshared.libiio.context - % % - % % Returns the matlabshared.libiio.context object - % coder.allowpcode('plain'); - % end - % end - - %% Internal Helper Functions methods (Static) + %% attribute methods + function status = iio_attr_read_raw(attrPtr, dstPtr, len) + % Read the content of the given attribute + % + % Args: + % attrPtr: A pointer to an iio_attr structure + % dstPtr: A pointer to the memory area where the read data + % will be stored + % len: The available length of the memory area, in bytes + % + % Returns: + % On success, the number of bytes written to the buffer + % On error, a negative errno code is returned + % + % libiio function: iio_attr_read_raw + validateattributes(len, { 'double','single' }, ... + {'real', 'scalar', 'finite', 'nonnan', 'nonempty', ... + 'nonnegative', 'integer'}); + + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_read_raw', attrPtr, dstPtr, len); + else + status = coder.ceval('iio_attr_read_raw', attrPtr, dstPtr, len); + end + end + + function status = iio_attr_write_raw(attrPtr, srcPtr, len) + % Read the content of the given attribute + % + % Args: + % attrPtr: A pointer to an iio_attr structure + % srcPtr: A pointer to the data to be written + % len: The number of bytes that should be written + % + % Returns: + % On success, the number of bytes written + % On error, a negative errno code is returned + % + % libiio function: iio_attr_write_raw + validateattributes(len, { 'double','single' }, ... + {'real', 'scalar', 'finite', 'nonnan', 'nonempty', ... + 'nonnegative', 'integer'}); + + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_write_raw', attrPtr, srcPtr, len); + else + status = coder.ceval('iio_attr_write_raw', attrPtr, srcPtr, len); + end + end + + function name = iio_attr_get_name(attrPtr) + % Retrieve the name of an attribute + % + % Args: + % attrPtr: A pointer to an iio_attr structure + % + % Returns: + % A pointer to a static NULL-terminated string + % + % libiio function: iio_attr_get_name + + if coder.target('MATLAB') + name = adi.libiio.attribute.calllibADI('iio_attr_get_name', attrPtr); + else + name = coder.ceval('iio_attr_get_name', attrPtr); + end + end + + function name = iio_attr_get_filename(attrPtr) + % Retrieve the filename of an attribute + % + % Args: + % attrPtr: A pointer to an iio_attr structure + % + % Returns: + % A pointer to a static NULL-terminated string + % + % libiio function: iio_attr_get_filename + + if coder.target('MATLAB') + name = adi.libiio.attribute.calllibADI('iio_attr_get_filename', attrPtr); + else + name = coder.ceval('iio_attr_get_filename', attrPtr); + end + end + + function name = iio_attr_get_static_value(attrPtr) + % Retrieve the static value of an attribute + % + % Args: + % attrPtr: A pointer to an iio_attr structure + % + % Returns: + % On success, a pointer to a static NULL-terminated string + % If the attribute does not have a static value, NULL is returned. + % + % libiio function: iio_attr_get_filename + + if coder.target('MATLAB') + name = adi.libiio.attribute.calllibADI('iio_attr_get_static_value', attrPtr); + else + name = coder.ceval('iio_attr_get_static_value', attrPtr); + end + end + function [status, value] = iio_attr_read_bool(attrPtr) valPtr = libpointer('bool', 0); - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_read_bool', attrPtr, valPtr); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_read_bool', attrPtr, valPtr); + else + status = coder.ceval('iio_attr_read_bool', attrPtr, valPtr); + end + if ~status value = valPtr.value; end @@ -20,7 +120,12 @@ function [status, value] = iio_attr_read_longlong(attrPtr) valPtr = libpointer('int64Ptr', 0); - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_read_longlong', attrPtr, valPtr); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_read_longlong', attrPtr, valPtr); + else + status = coder.ceval('iio_attr_read_longlong', attrPtr, valPtr); + end + if ~status value = valPtr.value; end @@ -28,30 +133,111 @@ function [status, value] = iio_attr_read_double(attrPtr) valPtr = libpointer('double', 0); - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_read_double', attrPtr, valPtr); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_read_double', attrPtr, valPtr); + else + status = coder.ceval('iio_attr_read_double', attrPtr, valPtr); + end + if ~status value = valPtr.value; end end function status = iio_attr_write_string(attrPtr, value) - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_write_string', attrPtr, value); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_write_string', attrPtr, value); + else + status = coder.ceval('iio_attr_write_string', attrPtr, value); + end end function status = iio_attr_write_bool(attrPtr, value) - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_write_bool', attrPtr, value); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_write_bool', attrPtr, value); + else + status = coder.ceval('iio_attr_write_bool', attrPtr, value); + end end function status = iio_attr_write_longlong(attrPtr, value) - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_write_longlong', attrPtr, value); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_write_longlong', attrPtr, value); + else + status = coder.ceval('iio_attr_write_longlong', attrPtr, value); + end end function status = iio_attr_write_double(attrPtr, value) - status = calllib(adi.libiio.attribute.getIIOLibName(), 'iio_attr_write_double', attrPtr, value); + if coder.target('MATLAB') + status = adi.libiio.attribute.calllibADI('iio_attr_write_double', attrPtr, value); + else + status = coder.ceval('iio_attr_write_double', attrPtr, value); + end end + end + %%Helpers + methods (Hidden, Access = private, Static) function libName = getIIOLibName() libName = 'libiio1'; end + + function headername = getIIOHeaderName() + headername = 'iio.h'; + end + + function [notfound, warnings] = loadLibIIO() + notfound = []; + warnings = []; + libName = adi.libiio.attribute.getIIOLibName(); + headername = adi.libiio.attribute.getIIOHeaderName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % [notfound, warnings] = loadlibrary(libName,headername); + % if ~isempty(notfound) + % % error + % end + % IsLibiioLoaded = libisloaded(libName); + % end + + if ~libisloaded(libName) + [notfound, warnings] = loadlibrary(libName,headername); + if ~isempty(notfound) + % error + end + end + end + + function unloadLibIIO() + libName = adi.libiio.attribute.getIIOLibName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % IsLibiioLoaded = libisloaded(libName); + % end + % + % if IsLibiioLoaded + % unloadlibrary(libName); + % end + + if libisloaded(libName) + unloadlibrary(libName); + end + end + + function varargout = calllibADI(fn, varargin) + [notfound, warnings] = adi.libiio.attribute.loadLibIIO(); + varargout = cell(1, nargout); + varargoutLocal = calllib(adi.libiio.attribute.getIIOLibName(), fn, varargin{:}); + % adi.libiio.attribute.unloadLibIIO(); + [varargout{:}] = varargoutLocal; + end + + function strout = ntstr(strin) + % Appends a null character to terminate the string. + % This is needed for code generation since MATLAB character + % arrays are not null terminated in code generation. + strout = [uint8(strin) uint8(0)]; + end end end \ No newline at end of file diff --git a/+adi/+libiio/context.m b/+adi/+libiio/context.m index 05aefc38..e830245c 100644 --- a/+adi/+libiio/context.m +++ b/+adi/+libiio/context.m @@ -1,17 +1,131 @@ classdef context < handle - %% Internal Helper Functions methods (Static) - %% Context Methods + %% context methods function ctxPtr = iio_create_context(ctxParamsPtr, uri) - ctxPtr = calllib(adi.libiio.context.getIIOLibName(), 'iio_create_context', ctxParamsPtr, uri); + % Create a context from a URI description + % + % Args: + % ctxParamsPtr: A pointer to a iio_context_params structure + % that contains context creation information; can be NULL + % uri: a URI describing the context location. If NULL, the + % backend will be created using the URI string present in + % the IIOD_REMOTE environment variable, or if not set, a + % local backend is created. + % + % Returns: + % On success, a pointer to a iio_context structure + % On failure, a pointer-encoded error is returned + % + % libiio function: iio_create_context + + if coder.target('MATLAB') + ctxPtr = adi.libiio.context.calllibADI('iio_create_context', ctxParamsPtr, uri); + else + ctxPtr = coder.opaque('struct iio_context*', 'NULL'); + ctxPtr = coder.ceval('iio_create_context', ctxParamsPtr, adi.libiio.context.ntstr(uri)); + end + end + + function iio_context_destroy(ctxPtr) + % Create a context from a URI description + % + % Args: + % ctxPtr: A pointer to a iio_context structure + % + % libiio function: iio_context_destroyiio_context_destroy + + if coder.target('MATLAB') + adi.libiio.context.calllibADI('iio_context_destroy', ctxPtr); + else + coder.ceval('iio_context_destroy', ctxPtr); + end end function devPtr = iio_context_find_device(ctxPtr, name) - devPtr = calllib(adi.libiio.context.getIIOLibName(), 'iio_context_find_device', ctxPtr, name); + % Try to find a device structure by its ID, label or name + % + % Args: + % ctxPtr: A pointer to an iio_context structure + % name: A NULL-terminated string corresponding to the ID, + % label or nameof the device to search for + % + % Returns: + % On success, a pointer to a iio_device structure + % If the parameter does not correspond to the ID, label or + % name of any known device, NULL is returned + % + % libiio function: iio_context_find_device + + if coder.target('MATLAB') + devPtr = adi.libiio.context.calllibADI('iio_context_find_device', ctxPtr, name); + else + devPtr = coder.opaque('struct iio_device*', 'NULL'); + devPtr = coder.ceval('iio_context_find_device', ctxPtr, adi.libiio.context.ntstr(name)); + end end + end + %%Helpers + methods (Hidden, Access = private, Static) function libName = getIIOLibName() libName = 'libiio1'; end + + function headername = getIIOHeaderName() + headername = 'iio.h'; + end + + function [notfound, warnings] = loadLibIIO() + notfound = []; + warnings = []; + libName = adi.libiio.context.getIIOLibName(); + headername = adi.libiio.context.getIIOHeaderName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % [notfound, warnings] = loadlibrary(libName,headername); + % if ~isempty(notfound) + % % error + % end + % IsLibiioLoaded = libisloaded(libName); + % end + + if ~libisloaded(libName) + [notfound, warnings] = loadlibrary(libName,headername); + if ~isempty(notfound) + % error + end + end + end + + function unloadLibIIO() + libName = adi.libiio.context.getIIOLibName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % IsLibiioLoaded = libisloaded(libName); + % end + % + % if IsLibiioLoaded + % unloadlibrary(libName); + % end + + if libisloaded(libName) + unloadlibrary(libName); + end + end + + function varargout = calllibADI(fn, varargin) + [notfound, warnings] = adi.libiio.context.loadLibIIO(); + varargout = cell(1, nargout); + varargoutLocal = calllib(adi.libiio.context.getIIOLibName(), fn, varargin{:}); + % adi.libiio.context.unloadLibIIO(); + [varargout{:}] = varargoutLocal; + end + + function strout = ntstr(strin) + % Appends a null character to terminate the string. + % This is needed for code generation since MATLAB character + % arrays are not null terminated in code generation. + strout = [uint8(strin) uint8(0)]; + end end end \ No newline at end of file diff --git a/+adi/+libiio/device.m b/+adi/+libiio/device.m index 4612a2ec..bfc21739 100644 --- a/+adi/+libiio/device.m +++ b/+adi/+libiio/device.m @@ -1,96 +1,386 @@ classdef device < handle - %% Internal Helper Functions methods (Static) - %% Device Methods - function ctxPtr = iio_device_get_context(devPtr) - ctxPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_context', devPtr); - end - - % function id = iio_device_get_id(devPtr) - % id = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_id', devPtr); - % end - % - % function name = iio_device_get_name(devPtr) - % name = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_name', devPtr); - % end - % - % function label = iio_device_get_label(devPtr) - % label = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_label', devPtr); - % end - - % function count = iio_device_get_channels_count(devPtr) - % count = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_channels_count', devPtr); - % end - % - % function count = iio_device_get_attrs_count(devPtr) - % count = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_attrs_count', devPtr); - % end - % - % function chanPtr = iio_device_get_channel(devPtr, index) - % chanPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_channel', devPtr, index); - % end - % - % function attrPtr = iio_device_get_attr(devPtr, index) - % attrPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_attr', devPtr, index); - % end - - function chanPtr = iio_device_find_channel(dev, id, output) - % iio_device_find_channel(const struct iio_device *dev, const char *name, bool output) + %% device methods + function ctxPtr = iio_device_get_context(devPtr) + % Retrieve a pointer to the iio_context structure + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % A pointer to an iio_context structure + % + % libiio function: iio_device_get_context + + if coder.target('MATLAB') + ctxPtr = adi.libiio.device.calllibADI('iio_device_get_context', devPtr); + else + ctxPtr = coder.opaque('struct iio_context*', 'NULL'); + ctxPtr = coder.ceval('iio_device_get_context', devPtr); + end + end + + function id = iio_device_get_id(devPtr) + % Retrieve the device ID (e.g. iio:device0) + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % A pointer to a static NULL-terminated string + % + % libiio function: iio_device_get_id + + if coder.target('MATLAB') + id = adi.libiio.device.calllibADI('iio_device_get_id', devPtr); + else + id = coder.ceval('iio_device_get_id', devPtr); + end + end + + function name = iio_device_get_name(devPtr) + % Retrieve the device name (e.g. xadc) + % + % Args: + % devPtr: A pointer to an iio_device structure % - % Find channel by name or channel ID. + % Returns: + % A pointer to a static NULL-terminated string + % + % NOTE: + % If the device has no name, NULL is returned + % + % libiio function: iio_device_get_name + + if coder.target('MATLAB') + name = adi.libiio.device.calllibADI('iio_device_get_name', devPtr); + else + name = coder.ceval('iio_device_get_name', devPtr); + end + end + + function label = iio_device_get_label(devPtr) + % Retrieve the device label (e.g. lo_pll0_rx_adf4351) + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % A pointer to a static NULL-terminated string + % + % NOTE: + % If the device has no name, NULL is returned + % + % libiio function: iio_device_get_label + + if coder.target('MATLAB') + label = adi.libiio.device.calllibADI('iio_device_get_label', devPtr); + else + label = coder.ceval('iio_device_get_label', devPtr); + end + end + + function count = iio_device_get_channels_count(devPtr) + % Enumerate the channels of the given device % % Args: - % dev: A pointer to an iio_device structure - % ID: name A NULL-terminated string corresponding to the name + % devPtr: A pointer to an iio_device structure + % + % Returns: + % The number of channels found + % + % libiio function: iio_device_get_channels_count + + if coder.target('MATLAB') + count = adi.libiio.device.calllibADI('iio_device_get_channels_count', devPtr); + else + count = coder.ceval('iio_device_get_channels_count', devPtr); + end + end + + function count = iio_device_get_attrs_count(devPtr) + % Enumerate the device-specific attributes of the given device + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % The number of channels found + % + % libiio function: iio_device_get_attrs_count + + if coder.target('MATLAB') + count = adi.libiio.device.calllibADI('iio_device_get_attrs_count', devPtr); + else + count = coder.ceval('iio_device_get_attrs_count', devPtr); + end + end + + function chanPtr = iio_device_get_channel(devPtr, index) + % Get the channel present at the given index + % + % Args: + % devPtr: A pointer to an iio_device structure + % index: The index corresponding to the channel + % + % Returns: + % On success, a pointer to an iio_channel structure. + % If the index is invalid, NULL is returned. + % + % libiio function: iio_device_get_channel + + if coder.target('MATLAB') + chanPtr = adi.libiio.device.calllibADI('iio_device_get_channel', devPtr, index); + else + chanPtr = coder.opaque('struct iio_channel*', 'NULL'); + chanPtr = coder.ceval('iio_device_get_channel', devPtr, index); + end + end + + function attrPtr = iio_device_get_attr(devPtr, index) + % Get the device-specific attribute present at the given index + % + % Args: + % devPtr: A pointer to an iio_device structure + % index: The index corresponding to the attribute + % + % Returns: + % On success, a pointer to an iio_attr structure. + % If the index is invalid, NULL is returned. + % + % libiio function: iio_device_get_attr + + if coder.target('MATLAB') + attrPtr = adi.libiio.device.calllibADI('iio_device_get_attr', devPtr, index); + else + attrPtr = coder.opaque('struct iio_attr*', 'NULL'); + attrPtr = coder.ceval('iio_device_get_attr', devPtr, index); + end + end + + function chanPtr = iio_device_find_channel(devPtr, id, output) + % Try to find a channel structure by its name of ID + % + % Args: + % devPtr: A pointer to an iio_device structure + % id: name A NULL-terminated string corresponding to the name % name or the ID of the channel to search for % output: True if the searched channel is output, False % otherwise % % Returns: - % On success, a pointer to an iio_channel structure. If the - % name or ID does not correspond to any known channel of the - % given device, NULL is returned. - chanPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_find_channel', dev, id, output); - end - - function [status, attrPtr] = iio_device_find_attr(devPtr, attr) - attrPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_find_attr', devPtr, attr); - status = -int32(isNull(attrPtr)); - end - - % function iio_device_set_data(devPtr, voidPtrToData) - % calllib(adi.libiio.device.getIIOLibName(), 'iio_device_set_data', devPtr, voidPtrToData); - % end - % - % function voidPtr = iio_device_get_data(devPtr) - % voidPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_data', devPtr); - % end - % - % function status = iio_device_set_trigger(devPtr, triggerPtr) - % triggerPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_set_trigger', devPtr, triggerPtr); - % status = cPtrCheck(obj,triggerPtr); - % end - % - % function triggerPtr = iio_device_get_trigger(devPtr) - % triggerPtr = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_get_trigger', devPtr); - % end - % - % function isTrigger = iio_device_is_trigger(devPtr) - % isTrigger = calllib(adi.libiio.device.getIIOLibName(), 'iio_device_is_trigger', devPtr); - % end + % On success, a pointer to an iio_channel structure. + % If the name or ID does not correspond to any known channel + % of the given device, NULL is returned. + % + % libiio function: iio_device_find_channel - function libName = getIIOLibName() - libName = 'libiio1'; + if coder.target('MATLAB') + chanPtr = adi.libiio.device.calllibADI('iio_device_find_channel', devPtr, id, output); + else + chanPtr = coder.opaque('struct iio_channel*', 'NULL'); + chanPtr = coder.ceval('iio_device_find_channel', devPtr, id, output); + end + end + + function attrPtr = iio_device_find_attr(devPtr, name) + % Try to find a device-specific attribute by its name + % + % Args: + % devPtr: A pointer to an iio_device structure + % name: A NULL-terminated string corresponding to the name + % of the attribute + % + % Returns: + % On success, a pointer to an iio_attr structure. + % If the name or ID does not correspond to any known channel + % of the given device, NULL is returned. + % + % NOTE: + % This function is useful to detect the presence of an + % attribute. It can also be used to retrieve the name of an + % attribute as a pointer to a static string from a + % dynamically allocated string. + % + % libiio function: iio_device_find_attr + + if coder.target('MATLAB') + attrPtr = adi.libiio.device.calllibADI('iio_device_find_attr', devPtr, name); + else + attrPtr = coder.opaque('struct iio_attr*', 'NULL'); + attrPtr = coder.ceval('iio_device_find_attr', devPtr, name); + end + end + + function iio_device_set_data(devPtr, dataPtr) + % Associate a pointer to an iio_device structure + % + % Args: + % devPtr: A pointer to an iio_device structure + % dataPtr: The pointer to be associated + % + % libiio function: iio_device_set_data + + if coder.target('MATLAB') + adi.libiio.device.calllibADI('iio_device_set_data', devPtr, dataPtr); + else + coder.ceval('iio_device_set_data', devPtr, dataPtr); + end + end + + function valPtr = iio_device_get_data(devPtr) + % Retrieve a previously associated pointer of an iio_device structure + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % The pointer previously associated if present, or NULL + % + % libiio function: iio_device_get_data + + if coder.target('MATLAB') + valPtr = adi.libiio.device.calllibADI('iio_device_get_data', devPtr); + else + valPtr = coder.opaque('void*', 'NULL'); + valPtr = coder.ceval('iio_device_get_data', devPtr); + end + end + + function triggerPtr = iio_device_get_trigger(devPtr, dataPtr) + % Retrieve the trigger of a given device + % + % Args: + % devPtr: A pointer to an iio_device structure + % dataPtr: The pointer to be associated + % + % Returns: + % On success, a pointer to the trigger's iio_device + % structure is returned. + % On failure, a pointer-encoded error is returned. If no + % trigger has been associated with the given device, the + % error code will be -ENODEV. + % + % libiio function: iio_device_get_trigger + + if coder.target('MATLAB') + triggerPtr = adi.libiio.device.calllibADI('iio_device_get_trigger', devPtr, dataPtr); + else + triggerPtr = coder.opaque('const struct iio_device*', 'NULL'); + triggerPtr = coder.ceval('iio_device_get_trigger', devPtr, dataPtr); + end + end + + function status = iio_device_set_trigger(devPtr, triggerPtr) + % Associate a trigger to a given device + % + % Args: + % devPtr: A pointer to an iio_device structure + % triggerPtr: A pointer to the iio_device structure + % corresponding to the trigger that should be associated. + % + % Returns: + % On success, 0 is returned + % On error, a negative errno code is returned. + % + % libiio function: iio_device_set_trigger + + if coder.target('MATLAB') + status = adi.libiio.device.calllibADI('iio_device_set_trigger', devPtr, triggerPtr); + else + status = coder.ceval('iio_device_set_trigger', devPtr, triggerPtr); + end + end + + function status = iio_device_is_trigger(devPtr) + % Return True if the given device is a trigger + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % True if the device is a trigger, False otherwise + % + % libiio function: iio_device_is_trigger + + if coder.target('MATLAB') + status = adi.libiio.device.calllibADI('iio_device_is_trigger', devPtr); + else + status = coder.ceval('iio_device_is_trigger', devPtr); + end end end - % Wrappers not present in iio.h of v1.0 - % Implemented for backwards compatibility + % Wrappers to maintain backwards-compatibility methods (Static) function nBytes = iio_device_attr_write(devPtr,attr,src) [status, attrPtr] = adi.libiio.device.iio_device_find_attr(devPtr, attr); % cstatus(obj,status,['Attribute: ' attr ' not found']); - nBytes = adi.libiio.attribute.iio_attr_write_string(attrPtr, src); + nBytes = adi.libiio.device.iio_attr_write_string(attrPtr, src); + end + end + + %%Helpers + methods (Hidden, Access = private, Static) + function libName = getIIOLibName() + libName = 'libiio1'; + end + + function headername = getIIOHeaderName() + headername = 'iio.h'; + end + + function [notfound, warnings] = loadLibIIO() + notfound = []; + warnings = []; + libName = adi.libiio.device.getIIOLibName(); + headername = adi.libiio.device.getIIOHeaderName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % [notfound, warnings] = loadlibrary(libName,headername); + % if ~isempty(notfound) + % % error + % end + % IsLibiioLoaded = libisloaded(libName); + % end + + if ~libisloaded(libName) + [notfound, warnings] = loadlibrary(libName,headername); + if ~isempty(notfound) + % error + end + end + end + + function unloadLibIIO() + libName = adi.libiio.device.getIIOLibName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % IsLibiioLoaded = libisloaded(libName); + % end + % + % if IsLibiioLoaded + % unloadlibrary(libName); + % end + + if libisloaded(libName) + unloadlibrary(libName); + end + end + + function varargout = calllibADI(fn, varargin) + [notfound, warnings] = adi.libiio.device.loadLibIIO(); + varargout = cell(1, nargout); + varargoutLocal = calllib(adi.libiio.device.getIIOLibName(), fn, varargin{:}); + % adi.libiio.device.unloadLibIIO(); + [varargout{:}] = varargoutLocal; + end + + function strout = ntstr(strin) + % Appends a null character to terminate the string. + % This is needed for code generation since MATLAB character + % arrays are not null terminated in code generation. + strout = [uint8(strin) uint8(0)]; end end end \ No newline at end of file diff --git a/+adi/+libiio/low_level.m b/+adi/+libiio/low_level.m deleted file mode 100644 index 0dcdf20e..00000000 --- a/+adi/+libiio/low_level.m +++ /dev/null @@ -1,41 +0,0 @@ -classdef (Abstract) low_level < handle% & matlabshared.libiio.device - % matlabshared.libiio.contextV1p0 context class for base matlabshared.libiio.support - % - % This abstract system object defines the APIs necessary to use libIIO - % V1.0 for MATLAB/Simulink simulation as well as codegen on a Linux - % target - - % Copyright 2024 Analog Devices Inc. - %#codegen - - %% Abstract Properties - properties(Abstract, Hidden, Access = protected) - libName - end - - methods - function obj = low_level() - % CONTEXT constructor method for matlabshared.libiio.context - % - % Returns the matlabshared.libiio.context object - coder.allowpcode('plain'); - end - end - - %% Internal Helper Functions - methods (Hidden, Access = {?handle}, Static) - %% Low-level Methods - function attr = iio_device_find_debug_attr(obj, devPtr, name) - % iio_device_find_debug_attr (const struct iio_device *devPtr, const char *name) - % - % Get context from device pointer. - if useCalllib(obj) - attr = calllib(obj.libName, 'iio_device_find_debug_attr', devPtr, name); - else - if useCodegen(obj) - attr = coder.ceval('iio_device_find_debug_attr', devPtr, obj.ntstr(name)); - end - end - end - end -end \ No newline at end of file diff --git a/+adi/+libiio/lowlevel.m b/+adi/+libiio/lowlevel.m new file mode 100644 index 00000000..3cc1effb --- /dev/null +++ b/+adi/+libiio/lowlevel.m @@ -0,0 +1,317 @@ +classdef (Abstract) lowlevel < handle + methods (Static) + %% low-level methods + function chnsMaskPtr = iio_create_channels_mask(value) + % Create a new empty channels mask + % + % Args: + % value: The number of channels in the mask + % + % Returns: + % On success, a pointer to an iio_channels_mask structure + % On error, NULL is returned + % + % libiio function: iio_create_channels_mask + validateattributes(value, { 'double','single' }, ... + {'real', 'scalar', 'finite', 'nonnan', 'nonempty', ... + 'nonnegative', 'integer'}); + + if coder.target('MATLAB') + chnsMaskPtr = adi.libiio.lowlevel.calllibADI('iio_create_channels_mask', value); + else + chnsMaskPtr = coder.opaque('struct iio_channels_mask*', 'NULL'); + chnsMaskPtr = coder.ceval('iio_create_channels_mask', value); + end + end + + function iio_channels_mask_destroy(maskPtr) + % Destroy a channels mask + % + % Args: + % maskPtr: A pointer to an iio_channels_mask structure + % + % libiio function: iio_channels_mask_destroy + + if coder.target('MATLAB') + adi.libiio.lowlevel.calllibADI('iio_channels_mask_destroy', maskPtr); + else + coder.ceval('iio_channels_mask_destroy', maskPtr); + end + end + + function value = iio_device_get_sample_size(devPtr, maskPtr) + % Get the current sample size + % + % Args: + % devPtr: A pointer to an iio_device structure + % maskPtr: A pointer to an iio_channels_mask structure + % + % Returns: + % On success, the sample size in bytes + % On error, a negative errno code is returned + % + % NOTE: The sample size is not constant and will change when + % channels get enabled or disabled. + % + % libiio function: iio_device_get_sample_size + + if coder.target('MATLAB') + value = adi.libiio.lowlevel.calllibADI('iio_device_get_sample_size', devPtr, maskPtr); + else + value = coder.ceval('iio_device_get_sample_size', devPtr, maskPtr); + end + end + + function value = iio_channel_get_index(chnPtr) + % Get the index of the given channel + % + % Args: + % chnPtr: A pointer to an iio_channel structure + % + % Returns: + % On success, the index of the specified channel + % On error, a negative errno code is returned + % + % libiio function: iio_channel_get_index + + if coder.target('MATLAB') + value = adi.libiio.lowlevel.calllibADI('iio_channel_get_index', chnPtr); + else + value = coder.ceval('iio_channel_get_index', chnPtr); + end + end + + function formatPtr = iio_channel_get_data_format(chnPtr) + % Get a pointer to a channel's data format structure + % + % Args: + % chnPtr: A pointer to an iio_channel structure + % + % Returns: + % A pointer to the channel's iio_data_format structure + % + % libiio function: iio_channel_get_data_format + + if coder.target('MATLAB') + formatPtr = adi.libiio.lowlevel.calllibADI('iio_channel_get_data_format', chnPtr); + else + formatPtr = coder.opaque('const struct iio_data_format*', 'NULL'); + formatPtr = coder.ceval('iio_channel_get_data_format', chnPtr); + end + end + + function iio_channel_convert(chnPtr, dstPtr, srcPtr) + % Convert the sample from hardware format to host format + % + % Args: + % chnPtr: A pointer to an iio_channel structure + % dstPtr: A pointer to the destination buffer where the + % converted sample should be written + % srcPtr: A pointer to the source buffer containing the sample + % + % libiio function: iio_channel_convert + + if coder.target('MATLAB') + adi.libiio.lowlevel.calllibADI('iio_channel_convert', chnPtr, dstPtr, srcPtr); + else + coder.ceval('iio_channel_convert', chnPtr, dstPtr, srcPtr); + end + end + + function iio_channel_convert_inverse(chnPtr, dstPtr, srcPtr) + % Convert the sample from host format to hardware format + % + % Args: + % chnPtr: A pointer to an iio_channel structure + % dstPtr: A pointer to the destination buffer where the + % converted sample should be written + % srcPtr: A pointer to the source buffer containing the sample + % + % libiio function: iio_channel_convert_inverse + + if coder.target('MATLAB') + adi.libiio.lowlevel.calllibADI('iio_channel_convert_inverse', chnPtr, dstPtr, srcPtr); + else + coder.ceval('iio_channel_convert_inverse', chnPtr, dstPtr, srcPtr); + end + end + + function count = iio_device_get_debug_attrs_count(devPtr) + % Enumerate the debug attributes of the given device + % + % Args: + % devPtr: A pointer to an iio_device structure + % + % Returns: + % The number of debug attributes found + % + % libiio function: iio_device_get_debug_attrs_count + + if coder.target('MATLAB') + count = adi.libiio.lowlevel.calllibADI('iio_device_get_debug_attrs_count', devPtr); + else + count = coder.ceval('iio_device_get_debug_attrs_count', devPtr); + end + end + + function attrPtr = iio_device_get_debug_attr(devPtr, index) + % Get the debug attribute present at the given index + % + % Args: + % devPtr: A pointer to an iio_device structure + % index: The index corresponding to the debug attribute + % + % Returns: + % On success, a pointer to a static NULL-terminated string + % If the index is invalid, NULL is returned + % + % libiio function: iio_device_get_debug_attr + validateattributes(index, { 'double','single' }, ... + {'real', 'scalar', 'finite', 'nonnan', 'nonempty', ... + 'nonnegative', 'integer'}); + + if coder.target('MATLAB') + attrPtr = adi.libiio.lowlevel.calllibADI('iio_device_get_debug_attr', devPtr, index); + else + attrPtr = coder.opaque('const struct iio_attr*', 'NULL'); + attrPtr = coder.ceval('iio_device_get_debug_attr', devPtr, index); + end + end + + function attrPtr = iio_device_find_debug_attr(devPtr, name) + % Try to find a debug attribute by its name + % + % Args: + % devPtr: A pointer to an iio_device structure + % name: A NULL-terminated string corresponding to the name + % of the debug attribute + % + % Returns: + % On success, a pointer to a static NULL-terminated string + % If the name does not correspond to any known debug + % attribute of the given device, NULL is returned + % + % libiio function: iio_device_find_debug_attr + + if coder.target('MATLAB') + attrPtr = adi.libiio.lowlevel.calllibADI('iio_device_find_debug_attr', devPtr, name); + else + attrPtr = coder.opaque('const struct iio_attr*', 'NULL'); + attrPtr = coder.ceval('iio_device_find_debug_attr', devPtr, adi.libiio.lowlevel.ntstr(name)); + end + end + + function status = iio_device_reg_write(devPtr, address, value) + % Set the value of a hardware register + % + % Args: + % devPtr: A pointer to an iio_device structure + % address: The address of the register + % value: The value to set the register to + % + % Returns: + % On success, 0 is returned + % On error, a negative errno code is returned + % + % libiio function: iio_device_find_debug_attr + validateattributes(value, { 'double','single' }, ... + {'real', 'scalar', 'finite', 'nonnan', 'nonempty', ... + 'nonnegative', 'integer'}); + + if coder.target('MATLAB') + status = adi.libiio.lowlevel.calllibADI('iio_device_reg_write', devPtr, address, value); + else + status = coder.ceval('iio_device_reg_write', devPtr, address, value); + end + end + + function value = iio_device_reg_read(devPtr, address) + % Get the value of a hardware register + % + % Args: + % devPtr: A pointer to an iio_device structure + % address: The address of the register + % + % Returns: + % On success, 0 is returned + % On error, a negative errno code is returned + % + % libiio function: iio_device_find_debug_attr + + valPtr = libpointer('uint32Ptr', 0); + if coder.target('MATLAB') + status = adi.libiio.lowlevel.calllibADI('iio_device_reg_read', devPtr, address, valPtr); + else + status = coder.ceval('iio_device_reg_read', devPtr, address); + end + + if ~status + value = valPtr.value; + end + end + end + + %%Helpers + methods (Hidden, Access = private, Static) + function libName = getIIOLibName() + libName = 'libiio1'; + end + + function headername = getIIOHeaderName() + headername = 'iio.h'; + end + + function [notfound, warnings] = loadLibIIO() + notfound = []; + warnings = []; + libName = adi.libiio.attribute.getIIOLibName(); + headername = adi.libiio.attribute.getIIOHeaderName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % [notfound, warnings] = loadlibrary(libName,headername); + % if ~isempty(notfound) + % % error + % end + % IsLibiioLoaded = libisloaded(libName); + % end + + if ~libisloaded(libName) + [notfound, warnings] = loadlibrary(libName,headername); + if ~isempty(notfound) + % error + end + end + end + + function unloadLibIIO() + libName = adi.libiio.attribute.getIIOLibName(); + % persistent IsLibiioLoaded + % if isempty(IsLibiioLoaded) + % IsLibiioLoaded = libisloaded(libName); + % end + % + % if IsLibiioLoaded + % unloadlibrary(libName); + % end + + if libisloaded(libName) + unloadlibrary(libName); + end + end + + function varargout = calllibADI(fn, varargin) + [notfound, warnings] = adi.libiio.attribute.loadLibIIO(); + varargout = cell(1, nargout); + varargoutLocal = calllib(adi.libiio.attribute.getIIOLibName(), fn, varargin{:}); + % adi.libiio.attribute.unloadLibIIO(); + [varargout{:}] = varargoutLocal; + end + + function strout = ntstr(strin) + % Appends a null character to terminate the string. + % This is needed for code generation since MATLAB character + % arrays are not null terminated in code generation. + strout = [uint8(strin) uint8(0)]; + end + end +end \ No newline at end of file