From de147377814d2eef480659e857f28626fd964d33 Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Fri, 18 Nov 2022 17:45:55 +0100 Subject: [PATCH 01/11] Implement first version --- .../Blocks/Examples/TestHardwareIIO.mo | 58 + .../Blocks/Examples/package.order | 1 + Modelica_DeviceDrivers/Blocks/HardwareIO.mo | 73 + Modelica_DeviceDrivers/HardwareIO/IIO.mo | 25 + .../HardwareIO/IIO_/data_read.mo | 13 + .../HardwareIO/IIO_/package.mo | 5 + .../HardwareIO/IIO_/package.order | 1 + .../HardwareIO/IIOchannel.mo | 28 + .../HardwareIO/package.order | 3 + .../Resources/Include/MDDIIO.h | 78 + .../Resources/Library/win64/libiio.lib | Bin 0 -> 36920 bytes .../Resources/thirdParty/libiio/iio.h | 1974 +++++++++++++++++ 12 files changed, 2259 insertions(+) create mode 100644 Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo create mode 100644 Modelica_DeviceDrivers/HardwareIO/IIO.mo create mode 100644 Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo create mode 100644 Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo create mode 100644 Modelica_DeviceDrivers/HardwareIO/IIO_/package.order create mode 100644 Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo create mode 100644 Modelica_DeviceDrivers/Resources/Include/MDDIIO.h create mode 100644 Modelica_DeviceDrivers/Resources/Library/win64/libiio.lib create mode 100644 Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h diff --git a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo new file mode 100644 index 00000000..96cfcc8e --- /dev/null +++ b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo @@ -0,0 +1,58 @@ +within Modelica_DeviceDrivers.Blocks.Examples; +model TestHardwareIIO "Example to access the Inertial Measurement Unit of a Pinephone via InternetIO" + import Modelica_DeviceDrivers; +extends Modelica.Icons.Example; + + Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.IIOConfig iio(deviceName="mobian.local") + annotation (Placement(transformation(extent={{-80,60},{-60,80}}))); + Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.PhysicalDataRead dataRead_x( + sampleTime=0.1, + iio=iio.dh, + devicename="mpu6050", + channelname="accel_x") annotation (Placement(transformation(extent={{-80,20},{-60,40}}))); + Modelica_DeviceDrivers.Blocks.OperatingSystem.RealtimeSynchronize + realtimeSynchronize + annotation (Placement(transformation(extent={{60,60},{80,80}}))); + Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.PhysicalDataRead dataRead_y( + sampleTime=0.1, + iio=iio.dh, + devicename="mpu6050", + channelname="accel_y") annotation (Placement(transformation(extent={{-80,-10},{-60,10}}))); + Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.PhysicalDataRead dataRead_z( + sampleTime=0.1, + iio=iio.dh, + devicename="mpu6050", + channelname="accel_z") annotation (Placement(transformation(extent={{-80,-40},{-60,-20}}))); + Modelica.Blocks.Routing.Multiplex3 a annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); + Modelica.Blocks.Math.Feedback feedback[3] annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); + Modelica.Blocks.Sources.RealExpression realExpression[3](y={0.11838963325622613, + 0.17931387736615592,9.054748576489855}) annotation (Placement(transformation(extent={{-40,-60},{-20,-40}}))); + Modelica.Blocks.Continuous.Integrator v[3] annotation (Placement(transformation(extent={{20,-10},{40,10}}))); + Modelica.Blocks.Continuous.Integrator s[3] annotation (Placement(transformation(extent={{60,-10},{80,10}}))); + Modelica.Mechanics.MultiBody.Visualizers.FixedShape fixedShape( + shapeType="sphere", + r_shape=a.y, + length=0.1, + width=0.1, + height=0.1) annotation (Placement(transformation(extent={{20,60},{40,80}}))); + inner Modelica.Mechanics.MultiBody.World world annotation (Placement(transformation(extent={{-20,60},{0,80}}))); +equation + connect(dataRead_x.y, a.u1[1]) annotation (Line(points={{-59,30},{-50,30},{-50,7},{-42,7}}, color={0,0,127})); + connect(dataRead_y.y, a.u2[1]) annotation (Line(points={{-59,0},{-42,0}}, color={0,0,127})); + connect(dataRead_z.y, a.u3[1]) annotation (Line(points={{-59,-30},{-50,-30},{-50,-7},{-42,-7}}, color={0,0,127})); + connect(a.y, feedback.u1) annotation (Line(points={{-19,0},{-8,0}}, color={0,0,127})); + connect(realExpression.y, feedback.u2) annotation (Line(points={{-19,-50},{0,-50},{0,-8}}, color={0,0,127})); + connect(feedback.y, v.u) annotation (Line(points={{9,0},{18,0}}, color={0,0,127})); + connect(v.y, s.u) annotation (Line(points={{41,0},{58,0}}, color={0,0,127})); + connect(world.frame_b, fixedShape.frame_a) + annotation (Line( + points={{0,70},{20,70}}, + color={95,95,95}, + thickness=0.5)); + annotation ( + experiment(StopTime=5.0), + Documentation(info=" +

This example was tested with a Mobian installation on a Pinephone. The package iiod has to be installed on the phone. It works out-of-the-box without further configuration.

+

Any other linux device supporting IIO can be used. Only the IIO deamon has to be installed and configured.

+")); +end TestHardwareIIO; diff --git a/Modelica_DeviceDrivers/Blocks/Examples/package.order b/Modelica_DeviceDrivers/Blocks/Examples/package.order index 673c5840..1d564b2d 100644 --- a/Modelica_DeviceDrivers/Blocks/Examples/package.order +++ b/Modelica_DeviceDrivers/Blocks/Examples/package.order @@ -16,6 +16,7 @@ TestInputJoystick TestInputKeyboard TestInputKeyboardKey TestHardwareIOComedi +TestHardwareIIO TestSerialPackager_TCPIP TestSerialPackager_LCM TestSerialPackager_MQTT diff --git a/Modelica_DeviceDrivers/Blocks/HardwareIO.mo b/Modelica_DeviceDrivers/Blocks/HardwareIO.mo index 3e09b6bf..5ad33c05 100644 --- a/Modelica_DeviceDrivers/Blocks/HardwareIO.mo +++ b/Modelica_DeviceDrivers/Blocks/HardwareIO.mo @@ -325,4 +325,77 @@ Enumeration that defines the available reference channels used in a DAQ-card ")); end Types; end Comedi; + + package IIO "Support for the linux device communication library 'libiio'" + extends Modelica.Icons.Package; + + record IIOConfig "Configuration for the linux device communication library 'libiio'" + extends Modelica_DeviceDrivers.Utilities.Icons.ComediRecordIcon; + + import Modelica_DeviceDrivers.HardwareIO.IIO; + parameter String deviceName = "" "Network address of IIO device. Leave empty for local device (Linux only)"; + + final parameter IIO dh = IIO(deviceName) "Handle to comedi device"; + + annotation (defaultComponentName="iio", + preferredView="info", + Icon(graphics={ + Text( + extent={{-98,72},{94,46}}, + textString="%deviceName"), + Bitmap(extent={{-96,-92},{10,20}}, fileName= + "modelica://Modelica_DeviceDrivers/Resources/Images/Icons/gears.png")}), + Documentation(info=" +

Record for configuring a IIO device. At initialization time the IIO device given by the parameter deviceName will be opened and a handle to that device will be assigned to the final parameter dh.This handle needs to be passed as parameter to the remaining IIO read and write blocks.

+

Note

+

If accessing a local linux device, it iis required that the simulation process has sufficient privileges to access the intended device (usually that requires "root" privileges).

+")); + end IIOConfig; + + block PhysicalDataRead "Read Real value from IIO channel" + extends Modelica_DeviceDrivers.Utilities.Icons.ComediBlockIcon; + import Modelica_DeviceDrivers.HardwareIO.IIO; + import Modelica_DeviceDrivers.HardwareIO.IIOchannel; + + parameter Modelica.Units.SI.Period sampleTime=0.01 "Sample time of block"; + parameter IIO iio "Handle to comedi device"; + parameter String devicename "Device name"; + parameter String channelname "Channel name"; + Modelica.Blocks.Interfaces.RealOutput y + annotation (Placement(transformation(extent={{100,-10},{120,10}}))); + protected + final parameter IIOchannel channel = IIOchannel(iio, devicename, channelname); + Real scaleData "Scale value read from channel"; + Real rawData "Raw value read from channel"; + + equation + when initial() then + scaleData = Modelica_DeviceDrivers.HardwareIO.IIO_.data_read(channel, "scale"); + end when; + when sample(0,sampleTime) then + rawData = Modelica_DeviceDrivers.HardwareIO.IIO_.data_read(channel, "raw"); + y = scaleData*rawData; + end when; + + annotation (defaultComponentName="dataRead", + preferredView="info", + Icon(graphics={Text(extent={{-222, + 88},{222,58}}, + textColor={0,0,0}, + textString="Device: %devicename"), Text(extent={{-222, + 54},{222,24}}, + textString="channel: %channelname", + textColor={0,0,0}), Text(extent={{-220, + 20},{224,-10}}, + textString="Ts: %sampleTime", + textColor={0,0,0}), Text(extent={{-220, + -104},{224,-134}}, + textString="Device: %iio", + textColor={0,0,0}), Text(extent={{-152,142},{148,102}}, + textString="%name")}), Documentation(info=" +

The parameter iio needs to be set to a valid IIO context handle, i.e., needs to be set to the record member dh of a IIOConfig record instance.

+

Uses the Comedi function iio_channel_attr_read_double(..) to read the a raw and scale attribute of a IIO channel and multiplies them to get the value reading.

+")); + end PhysicalDataRead; + end IIO; end HardwareIO; diff --git a/Modelica_DeviceDrivers/HardwareIO/IIO.mo b/Modelica_DeviceDrivers/HardwareIO/IIO.mo new file mode 100644 index 00000000..eeb40805 --- /dev/null +++ b/Modelica_DeviceDrivers/HardwareIO/IIO.mo @@ -0,0 +1,25 @@ +within Modelica_DeviceDrivers.HardwareIO; +class IIO + "Interface to the Industrial I/O (http://analogdevicesinc.github.io/libiio/), a linux subsystem to communicate with ICs" +extends ExternalObject; + +encapsulated function constructor "Open device" + import Modelica; + extends Modelica.Icons.Function; + import Modelica_DeviceDrivers.HardwareIO.IIO; + input String targetname "Network address of IIO device. Leave empty for local device (Linux only)"; + output IIO iio "File handle to IIO context"; + external "C" iio = MDD_iio_open(targetname) + annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); +end constructor; + +encapsulated function destructor "Close device" + import Modelica; + extends Modelica.Icons.Function; + import Modelica_DeviceDrivers.HardwareIO.IIO; + input IIO iio "File handle to IIO context"; + external "C" MDD_iio_close(iio) + annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); +end destructor; + +end IIO; diff --git a/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo b/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo new file mode 100644 index 00000000..85a0531f --- /dev/null +++ b/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo @@ -0,0 +1,13 @@ +within Modelica_DeviceDrivers.HardwareIO.IIO_; +encapsulated function data_read "Read from analog channel" + import Modelica; + extends Modelica.Icons.Function; + import Modelica_DeviceDrivers.HardwareIO.IIO; + input IIO iio "Device handle"; + input String devicename = "/dev/comedi0" "Device name"; + input String channelname = "/dev/comedi0" "Device name"; + input String attrname = "/dev/comedi0" "Device name"; + output Real data "Value that is read from channel"; + external "C" data = MDD_iio_data_read(iio, devicename, channelname, attrname) + annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); +end data_read; diff --git a/Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo b/Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo new file mode 100644 index 00000000..fac12da7 --- /dev/null +++ b/Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo @@ -0,0 +1,5 @@ +within Modelica_DeviceDrivers.HardwareIO; +package IIO_ "Accompanying functions for the IIO object" + extends Modelica_DeviceDrivers.Utilities.Icons.DriverIcon; + +end IIO_; diff --git a/Modelica_DeviceDrivers/HardwareIO/IIO_/package.order b/Modelica_DeviceDrivers/HardwareIO/IIO_/package.order new file mode 100644 index 00000000..fe31a77b --- /dev/null +++ b/Modelica_DeviceDrivers/HardwareIO/IIO_/package.order @@ -0,0 +1 @@ +data_read diff --git a/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo b/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo new file mode 100644 index 00000000..71552501 --- /dev/null +++ b/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo @@ -0,0 +1,28 @@ +within Modelica_DeviceDrivers.HardwareIO; +class IIOchannel + "Interface to a Industrial I/O device channel" +extends ExternalObject; + +encapsulated function constructor "Open channel" + import Modelica; + extends Modelica.Icons.Function; + import Modelica_DeviceDrivers.HardwareIO.IIO; + import Modelica_DeviceDrivers.HardwareIO.IIOchannel; + input IIO iio "File handle to IIO context"; + input String devicename "Device name"; + input String channelname "Channel name"; + output IIOchannel channel "File handle to IIO channel"; + external "C" channel = MDD_iio_open_channel(iio, devicename, channelname) + annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); +end constructor; + +encapsulated function destructor "Close channel" + import Modelica; + extends Modelica.Icons.Function; + import Modelica_DeviceDrivers.HardwareIO.IIOchannel; + input IIOchannel channel "Channel context"; + external "C" MDD_iio_close_channel(channel) + annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); +end destructor; + +end IIOchannel; diff --git a/Modelica_DeviceDrivers/HardwareIO/package.order b/Modelica_DeviceDrivers/HardwareIO/package.order index 769a4c1d..36861649 100644 --- a/Modelica_DeviceDrivers/HardwareIO/package.order +++ b/Modelica_DeviceDrivers/HardwareIO/package.order @@ -1,2 +1,5 @@ Comedi Comedi_ +IIO +IIOchannel +IIO_ diff --git a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h new file mode 100644 index 00000000..1a0348c8 --- /dev/null +++ b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h @@ -0,0 +1,78 @@ +/** Linux Comedi DAQ support (header-only library). + * + * @file + * @author bernhard-thiele + * @since 2012-06-26 + * @copyright see accompanying file LICENSE_Modelica_DeviceDrivers.txt + */ + +#ifndef MDDIIO_H_ +#define MDDIIO_H_ + +#include +#include <../thirdParty/libiio/iio.h> + +#include "ModelicaUtilities.h" + +#define IIO_ENSURE(expr, message, context) { \ + if (!(expr)) { \ + (void) ModelicaFormatError("%s %s (%s:%d)\n", message, context, __FILE__, __LINE__); \ + } \ +} + +// Streaming devices + +static struct iio_buffer *rxbuf; +static struct iio_channel **channels; +static unsigned int channel_count; + +void* MDD_iio_open(const char* targetname) { + static struct iio_context *ctx; + if(strlen(targetname) > 0) { + IIO_ENSURE(ctx = iio_create_network_context(targetname), "Could not open IIO host", targetname); + } + else { + IIO_ENSURE(ctx = iio_create_local_context(), "Could not open IIO host", "locally"); + } + IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname); + + return (void*) ctx; +} + +void MDD_iio_close(void* p_ctx) { + static struct iio_context *ctx; + ctx = (struct iio_context *) p_ctx; + if (ctx) { + iio_context_destroy(ctx); + } +} + +void* MDD_iio_open_channel(void *p_ctx, const char* devicename, const char* channelname) { + static struct iio_context *ctx; + ctx = (struct iio_context *) p_ctx; + + static struct iio_device *dev; + IIO_ENSURE(dev = iio_context_find_device(ctx, devicename), "Device not found: ", devicename); + + struct iio_channel *chn; + IIO_ENSURE(chn = iio_device_find_channel(dev, channelname, false), "Channel not found: ", channelname); + + return (void *) chn; +} + +void MDD_iio_close_channel (void* p_chn) { +} + +double MDD_iio_data_read(void* p_chn, const char* attrname) { + struct iio_channel *chn; + chn = (struct iio_channel *) p_chn; + + double val = 0; + + int ret = iio_channel_attr_read_double(chn, attrname, &val); + IIO_ENSURE(ret == 0, "Attribute not found: ", attrname); + + return val; +} + +#endif /* MDDIIO_H_ */ diff --git a/Modelica_DeviceDrivers/Resources/Library/win64/libiio.lib b/Modelica_DeviceDrivers/Resources/Library/win64/libiio.lib new file mode 100644 index 0000000000000000000000000000000000000000..fdea5f93feb9549756d8579338951fa8007f921c GIT binary patch literal 36920 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 MJ!J3aW(=JF2QY~bB>(^b literal 0 HcmV?d00001 diff --git a/Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h b/Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h new file mode 100644 index 00000000..cefac60e --- /dev/null +++ b/Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h @@ -0,0 +1,1974 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2014 Analog Devices, Inc. + * Author: Paul Cercueil + */ + +/** @file iio.h + * @brief Public interface */ + +#ifndef __IIO_H__ +#define __IIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +#if (defined(_WIN32) || defined(__MBED__)) +#ifndef _SSIZE_T_DEFINED +typedef ptrdiff_t ssize_t; +#define _SSIZE_T_DEFINED +#endif +#else +#include +#endif + +#if defined(_MSC_VER) && (_MSC_VER < 1800) && !defined(__BOOL_DEFINED) +#undef bool +#undef false +#undef true +#define bool char +#define false 0 +#define true 1 +#else +#include +#endif + +#if defined(__GNUC__) && !defined(MATLAB_MEX_FILE) && !defined(MATLAB_LOADLIBRARY) +#ifndef __cnst +#define __cnst __attribute__((const)) +#endif +#ifndef __pure +#define __pure __attribute__((pure)) +#endif +#define __notused __attribute__((unused)) +#ifdef IIO_CHECK_RET +#define __check_ret __attribute__((warn_unused_result)) +#else +#define __check_ret +#endif +#else +#define __cnst +#define __pure +#define __notused +#define __check_ret +#endif + +#ifdef _WIN32 +# ifdef LIBIIO_STATIC +# define __api +# elif defined(LIBIIO_EXPORTS) +# define __api __declspec(dllexport) +# else +# define __api __declspec(dllimport) +# endif +#elif __GNUC__ >= 4 && !defined(MATLAB_MEX_FILE) && !defined(MATLAB_LOADLIBRARY) +# define __api __attribute__((visibility ("default"))) +#else +# define __api +#endif + +struct iio_context; +struct iio_device; +struct iio_channel; +struct iio_buffer; + +struct iio_context_info; +struct iio_scan_context; +struct iio_scan_block; + +/* + * header guard to protect these enums from being defined + * twice + */ +#ifndef _IIO_TYPES_H_ +#define _IIO_TYPES_H_ + +/** + * @enum iio_chan_type + * @brief IIO channel type + * + * A IIO channel has a type specifying the type of data associated with the + * channel. + */ +enum iio_chan_type { + IIO_VOLTAGE, + IIO_CURRENT, + IIO_POWER, + IIO_ACCEL, + IIO_ANGL_VEL, + IIO_MAGN, + IIO_LIGHT, + IIO_INTENSITY, + IIO_PROXIMITY, + IIO_TEMP, + IIO_INCLI, + IIO_ROT, + IIO_ANGL, + IIO_TIMESTAMP, + IIO_CAPACITANCE, + IIO_ALTVOLTAGE, + IIO_CCT, + IIO_PRESSURE, + IIO_HUMIDITYRELATIVE, + IIO_ACTIVITY, + IIO_STEPS, + IIO_ENERGY, + IIO_DISTANCE, + IIO_VELOCITY, + IIO_CONCENTRATION, + IIO_RESISTANCE, + IIO_PH, + IIO_UVINDEX, + IIO_ELECTRICALCONDUCTIVITY, + IIO_COUNT, + IIO_INDEX, + IIO_GRAVITY, + IIO_POSITIONRELATIVE, + IIO_PHASE, + IIO_MASSCONCENTRATION, + IIO_CHAN_TYPE_UNKNOWN = INT_MAX +}; + +/** + * @enum iio_modifier + * @brief IIO channel modifier + * + * In a addition to a type a IIO channel can optionally have a channel modifier + * further specifying the data type of of the channel. + */ +enum iio_modifier { + IIO_NO_MOD, + IIO_MOD_X, + IIO_MOD_Y, + IIO_MOD_Z, + IIO_MOD_X_AND_Y, + IIO_MOD_X_AND_Z, + IIO_MOD_Y_AND_Z, + IIO_MOD_X_AND_Y_AND_Z, + IIO_MOD_X_OR_Y, + IIO_MOD_X_OR_Z, + IIO_MOD_Y_OR_Z, + IIO_MOD_X_OR_Y_OR_Z, + IIO_MOD_LIGHT_BOTH, + IIO_MOD_LIGHT_IR, + IIO_MOD_ROOT_SUM_SQUARED_X_Y, + IIO_MOD_SUM_SQUARED_X_Y_Z, + IIO_MOD_LIGHT_CLEAR, + IIO_MOD_LIGHT_RED, + IIO_MOD_LIGHT_GREEN, + IIO_MOD_LIGHT_BLUE, + IIO_MOD_QUATERNION, + IIO_MOD_TEMP_AMBIENT, + IIO_MOD_TEMP_OBJECT, + IIO_MOD_NORTH_MAGN, + IIO_MOD_NORTH_TRUE, + IIO_MOD_NORTH_MAGN_TILT_COMP, + IIO_MOD_NORTH_TRUE_TILT_COMP, + IIO_MOD_RUNNING, + IIO_MOD_JOGGING, + IIO_MOD_WALKING, + IIO_MOD_STILL, + IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z, + IIO_MOD_I, + IIO_MOD_Q, + IIO_MOD_CO2, + IIO_MOD_VOC, + IIO_MOD_LIGHT_UV, + IIO_MOD_LIGHT_DUV, + IIO_MOD_PM1, + IIO_MOD_PM2P5, + IIO_MOD_PM4, + IIO_MOD_PM10, + IIO_MOD_ETHANOL, + IIO_MOD_H2, + IIO_MOD_O2, +}; + +/** + * @enum iio_event_type + * @brief IIO event type + * + * Some IIO devices can deliver events. The type of the event can be specified + * by one of the iio_event_type values. + */ +enum iio_event_type { + IIO_EV_TYPE_THRESH, + IIO_EV_TYPE_MAG, + IIO_EV_TYPE_ROC, + IIO_EV_TYPE_THRESH_ADAPTIVE, + IIO_EV_TYPE_MAG_ADAPTIVE, + IIO_EV_TYPE_CHANGE, +}; + +/** + * @enum iio_event_direction + * @brief IIO event direction + * + * When applicable, this enum specifies the direction of the iio_event_type. + */ +enum iio_event_direction { + IIO_EV_DIR_EITHER, + IIO_EV_DIR_RISING, + IIO_EV_DIR_FALLING, + IIO_EV_DIR_NONE, +}; + +#endif /* _IIO_TYPES_H_ */ + +/* ---------------------------------------------------------------------------*/ +/* ------------------------- Scan functions ----------------------------------*/ +/** @defgroup Scan Functions for scanning available contexts + * @{ + * @struct iio_scan_context + * @brief The scanning context + * + * @struct iio_context_info + * @brief The information related to a discovered context + */ + + +/** @brief Create a scan context + * @param backend A NULL-terminated string containing a comma-separated + * list of the backend(s) to use for scanning. + * @param flags Unused for now. Set to 0. + * @return on success, a pointer to a iio_scan_context structure + * @return On failure, NULL is returned and errno is set appropriately + * + * NOTE: Libiio version 0.20 and above can handle multiple + * strings, for instance "local:usb:", "ip:usb:", "local:usb:ip:", and + * require a colon as the delimiter. + * Libiio version 0.24 and above prefer a comma instead of colon as the + * delimiter, and handle specifying backend-specific information. For + * instance, "local,usb=0456:*" will scan the local backend and limit + * scans on USB to vendor ID 0x0456, and accept all product IDs. The + * "usb=0456:b673" string would limit the scan to the device with this + * particular VID/PID. Both IDs are expected in hexadecimal, no 0x + * prefix needed. */ +__api __check_ret struct iio_scan_context * iio_create_scan_context( + const char *backend, unsigned int flags); + + +/** @brief Destroy the given scan context + * @param ctx A pointer to an iio_scan_context structure + * + * NOTE: After that function, the iio_scan_context pointer shall be invalid. */ +__api void iio_scan_context_destroy(struct iio_scan_context *ctx); + + +/** @brief Enumerate available contexts + * @param ctx A pointer to an iio_scan_context structure + * @param info A pointer to a 'const struct iio_context_info **' typed variable. + * The pointed variable will be initialized on success. + * @returns On success, the number of contexts found. + * @returns On failure, a negative error number. + */ +__api __check_ret ssize_t iio_scan_context_get_info_list(struct iio_scan_context *ctx, + struct iio_context_info ***info); + + +/** @brief Free a context info list + * @param info A pointer to a 'const struct iio_context_info *' typed variable + */ +__api void iio_context_info_list_free(struct iio_context_info **info); + + +/** @brief Get a description of a discovered context + * @param info A pointer to an iio_context_info structure + * @return A pointer to a static NULL-terminated string + */ +__api __check_ret __pure const char * iio_context_info_get_description( + const struct iio_context_info *info); + + +/** @brief Get the URI of a discovered context + * @param info A pointer to an iio_context_info structure + * @return A pointer to a static NULL-terminated string + */ +__api __check_ret __pure const char * iio_context_info_get_uri( + const struct iio_context_info *info); + + +/** @brief Create a scan block + * @param backend A NULL-terminated string containing the backend to use for + * scanning. If NULL, all the available backends are used. + * @param flags Unused for now. Set to 0. + * @return on success, a pointer to a iio_scan_block structure + * @return On failure, NULL is returned and errno is set appropriately + * + * Introduced in version 0.20. */ +__api struct iio_scan_block * iio_create_scan_block( + const char *backend, unsigned int flags); + + +/** @brief Destroy the given scan block + * @param blk A pointer to an iio_scan_block structure + * + * NOTE: After that function, the iio_scan_block pointer shall be invalid. + * + * Introduced in version 0.20. */ +__api void iio_scan_block_destroy(struct iio_scan_block *blk); + + +/** @brief Enumerate available contexts via scan block + * @param blk A pointer to a iio_scan_block structure. + * @returns On success, the number of contexts found. + * @returns On failure, a negative error number. + * + * Introduced in version 0.20. */ +__api ssize_t iio_scan_block_scan(struct iio_scan_block *blk); + + +/** @brief Get the iio_context_info for a particular context + * @param blk A pointer to an iio_scan_block structure + * @param index The index corresponding to the context. + * @return A pointer to the iio_context_info for the context + * @returns On success, a pointer to the specified iio_context_info + * @returns On failure, NULL is returned and errno is set appropriately + * + * Introduced in version 0.20. */ +__api struct iio_context_info *iio_scan_block_get_info( + struct iio_scan_block *blk, unsigned int index); + + +/** @} *//* ------------------------------------------------------------------*/ +/* ------------------------- Top-level functions -----------------------------*/ +/** @defgroup TopLevel Top-level functions + * @{ */ + + +/** @brief Get the version of the libiio library + * @param major A pointer to an unsigned integer (NULL accepted) + * @param minor A pointer to an unsigned integer (NULL accepted) + * @param git_tag A pointer to a 8-characters buffer (NULL accepted) */ +__api void iio_library_get_version(unsigned int *major, + unsigned int *minor, char git_tag[8]); + + +/** @brief Get a string description of an error code + * @param err The error code + * @param dst A pointer to the memory area where the NULL-terminated string + * corresponding to the error message will be stored + * @param len The available length of the memory area, in bytes */ +__api void iio_strerror(int err, char *dst, size_t len); + + +/** @brief Check if the specified backend is available + * @param backend The name of the backend to query + * @return True if the backend is available, false otherwise + * + * Introduced in version 0.9. */ +__api __check_ret __cnst bool iio_has_backend(const char *backend); + + +/** @brief Get the number of available backends + * @return The number of available backends + * + * Introduced in version 0.9. */ +__api __check_ret __cnst unsigned int iio_get_backends_count(void); + + +/** @brief Retrieve the name of a given backend + * @param index The index corresponding to the attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the index is invalid, NULL is returned + * + * Introduced in version 0.9. */ +__api __check_ret __cnst const char * iio_get_backend(unsigned int index); + + +/** @} *//* ------------------------------------------------------------------*/ +/* ------------------------- Context functions -------------------------------*/ +/** @defgroup Context Context + * @{ + * @struct iio_context + * @brief Contains the representation of an IIO context */ + + +/** @brief Create a context from local or remote IIO devices + * @return On success, A pointer to an iio_context structure + * @return On failure, NULL is returned and errno is set appropriately + * + * NOTE: This function will create a context with the URI + * provided in the IIOD_REMOTE environment variable. If not set, a local + * context will be created instead. */ +__api __check_ret struct iio_context * iio_create_default_context(void); + + +/** @brief Create a context from local IIO devices (Linux only) + * @return On success, A pointer to an iio_context structure + * @return On failure, NULL is returned and errno is set appropriately */ +__api __check_ret struct iio_context * iio_create_local_context(void); + + +/** @brief Create a context from a XML file + * @param xml_file Path to the XML file to open + * @return On success, A pointer to an iio_context structure + * @return On failure, NULL is returned and errno is set appropriately + * + * NOTE: The format of the XML must comply to the one returned by + * iio_context_get_xml. */ +__api __check_ret struct iio_context * iio_create_xml_context(const char *xml_file); + + +/** @brief Create a context from XML data in memory + * @param xml Pointer to the XML data in memory + * @param len Length of the XML string in memory (excluding the final \0) + * @return On success, A pointer to an iio_context structure + * @return On failure, NULL is returned and errno is set appropriately + * + * NOTE: The format of the XML must comply to the one returned by + * iio_context_get_xml */ +__api __check_ret struct iio_context * iio_create_xml_context_mem( + const char *xml, size_t len); + + +/** @brief Create a context from the network + * @param host Hostname, IPv4 or IPv6 address where the IIO Daemon is running + * @return On success, a pointer to an iio_context structure + * @return On failure, NULL is returned and errno is set appropriately */ +__api __check_ret struct iio_context * iio_create_network_context(const char *host); + + +/** @brief Create a context from a URI description + * @param uri A URI describing the context location + * @return On success, a pointer to a iio_context structure + * @return On failure, NULL is returned and errno is set appropriately + * + * NOTE: The following URIs are supported based on compile time backend + * support: + * - Local backend, "local:"\n + * Does not have an address part. For example "local:" + * - XML backend, "xml:"\n Requires a path to the XML file for the address part. + * For example "xml:/home/user/file.xml" + * - Network backend, "ip:"\n Requires a hostname, IPv4, or IPv6 to connect to + * a specific running IIO Daemon or no address part for automatic discovery + * when library is compiled with ZeroConf support. For example + * "ip:192.168.2.1", or "ip:localhost", or "ip:" + * or "ip:plutosdr.local". To support alternative port numbers the + * standard ip:host:port format is used. A special format is required as + * defined in RFC2732 for IPv6 literal hostnames, (adding '[]' around the host) + * to use a ip:[x:x:x:x:x:x:x:x]:port format. + * Valid examples would be: + * - ip: Any host on default port + * - ip::40000 Any host on port 40000 + * - ip:analog.local Default port + * - ip:brain.local:40000 Port 40000 + * - ip:192.168.1.119 Default Port + * - ip:192.168.1.119:40000 Port 40000 + * - ip:2601:190:400:da:47b3:55ab:3914:bff1 Default Port + * - ip:[2601:190:400:da:9a90:96ff:feb5:acaa]:40000 Port 40000 + * - USB backend, "usb:"\n When more than one usb device is attached, requires + * bus, address, and interface parts separated with a dot. For example + * "usb:3.32.5". Where there is only one USB device attached, the shorthand + * "usb:" can be used. + * - Serial backend, "serial:"\n Requires: + * - a port (/dev/ttyUSB0), + * - baud_rate (default 115200) + * - serial port configuration + * - data bits (5 6 7 8 9) + * - parity ('n' none, 'o' odd, 'e' even, 'm' mark, 's' space) + * - stop bits (1 2) + * - flow control ('\0' none, 'x' Xon Xoff, 'r' RTSCTS, 'd' DTRDSR) + * + * For example "serial:/dev/ttyUSB0,115200" or "serial:/dev/ttyUSB0,115200,8n1"*/ +__api __check_ret struct iio_context * iio_create_context_from_uri(const char *uri); + + +/** @brief Duplicate a pre-existing IIO context + * @param ctx A pointer to an iio_context structure + * @return On success, A pointer to an iio_context structure + * @return On failure, NULL is returned and errno is set appropriately + * + * NOTE: This function is not supported on 'usb:' contexts, since libusb + * can only claim the interface once. "Function not implemented" is the expected errno. + * Any context which is cloned, must be destroyed via calling iio_context_destroy() */ +__api __check_ret struct iio_context * iio_context_clone(const struct iio_context *ctx); + + +/** @brief Destroy the given context + * @param ctx A pointer to an iio_context structure + * + * NOTE: After that function, the iio_context pointer shall be invalid. */ +__api void iio_context_destroy(struct iio_context *ctx); + + +/** @brief Get the version of the backend in use + * @param ctx A pointer to an iio_context structure + * @param major A pointer to an unsigned integer (NULL accepted) + * @param minor A pointer to an unsigned integer (NULL accepted) + * @param git_tag A pointer to a 8-characters buffer (NULL accepted) + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_context_get_version(const struct iio_context *ctx, + unsigned int *major, unsigned int *minor, char git_tag[8]); + + +/** @brief Obtain a XML representation of the given context + * @param ctx A pointer to an iio_context structure + * @return A pointer to a static NULL-terminated string */ +__api __check_ret __pure const char * iio_context_get_xml(const struct iio_context *ctx); + + +/** @brief Get the name of the given context + * @param ctx A pointer to an iio_context structure + * @return A pointer to a static NULL-terminated string + * + * NOTE:The returned string will be local, + * xml or network when the context has been + * created with the local, xml and network backends respectively.*/ +__api __check_ret __pure const char * iio_context_get_name(const struct iio_context *ctx); + + +/** @brief Get a description of the given context + * @param ctx A pointer to an iio_context structure + * @return A pointer to a static NULL-terminated string + * + * NOTE:The returned string will contain human-readable information about + * the current context. */ +__api __check_ret __pure const char * iio_context_get_description( + const struct iio_context *ctx); + + +/** @brief Get the number of context-specific attributes + * @param ctx A pointer to an iio_context structure + * @return The number of context-specific attributes + * + * Introduced in version 0.9. */ +__api __check_ret __pure unsigned int iio_context_get_attrs_count( + const struct iio_context *ctx); + + +/** @brief Retrieve the name and value of a context-specific attribute + * @param ctx A pointer to an iio_context structure + * @param index The index corresponding to the attribute + * @param name A pointer to a const char * pointer (NULL accepted) + * @param value A pointer to a const char * pointer (NULL accepted) + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * Introduced in version 0.9. */ +__api __check_ret int iio_context_get_attr( + const struct iio_context *ctx, unsigned int index, + const char **name, const char **value); + + +/** @brief Retrieve the value of a context-specific attribute + * @param ctx A pointer to an iio_context structure + * @param name The name of the context attribute to read + * @return On success, a pointer to a static NULL-terminated string + * @return If the name does not correspond to any attribute, NULL is + * returned + * + * Introduced in version 0.9. */ +__api __check_ret const char * iio_context_get_attr_value( + const struct iio_context *ctx, const char *name); + + +/** @brief Enumerate the devices found in the given context + * @param ctx A pointer to an iio_context structure + * @return The number of devices found */ +__api __check_ret __pure unsigned int iio_context_get_devices_count( + const struct iio_context *ctx); + + +/** @brief Get the device present at the given index + * @param ctx A pointer to an iio_context structure + * @param index The index corresponding to the device + * @return On success, a pointer to an iio_device structure + * @return If the index is invalid, NULL is returned */ +__api __check_ret __pure struct iio_device * iio_context_get_device( + const struct iio_context *ctx, unsigned int index); + + +/** @brief Try to find a device structure by its ID, label or name + * @param ctx A pointer to an iio_context structure + * @param name A NULL-terminated string corresponding to the ID, label or name + * of the device to search for + * @return On success, a pointer to an iio_device structure + * @return If the parameter does not correspond to the ID, label or name of + * any known device, NULL is returned */ +__api __check_ret __pure struct iio_device * iio_context_find_device( + const struct iio_context *ctx, const char *name); + + +/** @brief Set a timeout for I/O operations + * @param ctx A pointer to an iio_context structure + * @param timeout_ms A positive integer representing the time in milliseconds + * after which a timeout occurs. A value of 0 is used to specify that no + * timeout should occur. + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_context_set_timeout( + struct iio_context *ctx, unsigned int timeout_ms); + + +/** @} *//* ------------------------------------------------------------------*/ +/* ------------------------- Device functions --------------------------------*/ +/** @defgroup Device Device + * @{ + * @struct iio_device + * @brief Represents a device in the IIO context */ + + +/** @brief Retrieve a pointer to the iio_context structure + * @param dev A pointer to an iio_device structure + * @return A pointer to an iio_context structure */ +__api __check_ret __pure const struct iio_context * iio_device_get_context( + const struct iio_device *dev); + + +/** @brief Retrieve the device ID (e.g. iio:device0) + * @param dev A pointer to an iio_device structure + * @return A pointer to a static NULL-terminated string */ +__api __check_ret __pure const char * iio_device_get_id(const struct iio_device *dev); + + +/** @brief Retrieve the device name (e.g. xadc) + * @param dev A pointer to an iio_device structure + * @return A pointer to a static NULL-terminated string + * + * NOTE: if the device has no name, NULL is returned. */ +__api __check_ret __pure const char * iio_device_get_name(const struct iio_device *dev); + + +/** @brief Retrieve the device label (e.g. lo_pll0_rx_adf4351) + * @param dev A pointer to an iio_device structure + * @return A pointer to a static NULL-terminated string + * + * NOTE: if the device has no label, NULL is returned. */ +__api __check_ret __pure const char * iio_device_get_label(const struct iio_device *dev); + + +/** @brief Enumerate the channels of the given device + * @param dev A pointer to an iio_device structure + * @return The number of channels found */ +__api __check_ret __pure unsigned int iio_device_get_channels_count( + const struct iio_device *dev); + + +/** @brief Enumerate the device-specific attributes of the given device + * @param dev A pointer to an iio_device structure + * @return The number of device-specific attributes found */ +__api __check_ret __pure unsigned int iio_device_get_attrs_count( + const struct iio_device *dev); + +/** @brief Enumerate the buffer-specific attributes of the given device + * @param dev A pointer to an iio_device structure + * @return The number of buffer-specific attributes found */ +__api __check_ret __pure unsigned int iio_device_get_buffer_attrs_count( + const struct iio_device *dev); + +/** @brief Get the channel present at the given index + * @param dev A pointer to an iio_device structure + * @param index The index corresponding to the channel + * @return On success, a pointer to an iio_channel structure + * @return If the index is invalid, NULL is returned */ +__api __check_ret __pure struct iio_channel * iio_device_get_channel( + const struct iio_device *dev, unsigned int index); + + +/** @brief Get the device-specific attribute present at the given index + * @param dev A pointer to an iio_device structure + * @param index The index corresponding to the attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the index is invalid, NULL is returned */ +__api __check_ret __pure const char * iio_device_get_attr( + const struct iio_device *dev, unsigned int index); + +/** @brief Get the buffer-specific attribute present at the given index + * @param dev A pointer to an iio_device structure + * @param index The index corresponding to the attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the index is invalid, NULL is returned */ +__api __check_ret __pure const char * iio_device_get_buffer_attr( + const struct iio_device *dev, unsigned int index); + +/** @brief Try to find a channel structure by its name of ID + * @param dev A pointer to an iio_device structure + * @param name A NULL-terminated string corresponding to the name or the ID of + * the channel to search for + * @param output True if the searched channel is output, False otherwise + * @return On success, a pointer to an iio_channel structure + * @return If the name or ID does not correspond to any known channel of the + * given device, NULL is returned */ +__api __check_ret __pure struct iio_channel * iio_device_find_channel( + const struct iio_device *dev, const char *name, bool output); + + +/** @brief Try to find a device-specific attribute by its name + * @param dev A pointer to an iio_device structure + * @param name A NULL-terminated string corresponding to the name of the + * attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the name does not correspond to any known attribute 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. */ +__api __check_ret __pure const char * iio_device_find_attr( + const struct iio_device *dev, const char *name); + +/** @brief Try to find a buffer-specific attribute by its name + * @param dev A pointer to an iio_device structure + * @param name A NULL-terminated string corresponding to the name of the + * attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the name does not correspond to any known attribute 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. */ +__api __check_ret __pure const char * iio_device_find_buffer_attr( + const struct iio_device *dev, const char *name); + +/** @brief Read the content of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param dst A pointer to the memory area where the NULL-terminated string + * corresponding to the value read will be stored + * @param len The available length of the memory area, in bytes + * @return On success, the number of bytes written to the buffer + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to iio_device_attr_read, + * it is now possible to read all of the attributes of a device. + * + * The buffer is filled with one block of data per attribute of the device, + * by the order they appear in the iio_device structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, it corresponds to the errno code that were + * returned when reading the attribute; if positive, it corresponds to the + * length of the data read. In that case, the rest of the block contains + * the data. */ +__api __check_ret ssize_t iio_device_attr_read(const struct iio_device *dev, + const char *attr, char *dst, size_t len); + + +/** @brief Read the content of all device-specific attributes + * @param dev A pointer to an iio_device structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the device-specific attributes are read in one single + * command. */ +__api __check_ret int iio_device_attr_read_all(struct iio_device *dev, + int (*cb)(struct iio_device *dev, const char *attr, + const char *value, size_t len, void *d), + void *data); + + +/** @brief Read the content of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a bool variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_attr_read_bool(const struct iio_device *dev, + const char *attr, bool *val); + + +/** @brief Read the content of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a long long variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_attr_read_longlong(const struct iio_device *dev, + const char *attr, long long *val); + + +/** @brief Read the content of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a double variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_attr_read_double(const struct iio_device *dev, + const char *attr, double *val); + + +/** @brief Set the value of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param src A NULL-terminated string to set the attribute to + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to iio_device_attr_write, + * it is now possible to write all of the attributes of a device. + * + * The buffer must contain one block of data per attribute of the device, + * by the order they appear in the iio_device structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, the attribute is not written; if positive, + * it corresponds to the length of the data to write. In that case, the rest + * of the block must contain the data. */ +__api __check_ret ssize_t iio_device_attr_write(const struct iio_device *dev, + const char *attr, const char *src); + + +/** @brief Set the value of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param src A pointer to the data to be written + * @param len The number of bytes that should be written + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned */ +__api __check_ret ssize_t iio_device_attr_write_raw(const struct iio_device *dev, + const char *attr, const void *src, size_t len); + + +/** @brief Set the values of all device-specific attributes + * @param dev A pointer to an iio_device structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the device-specific attributes are written in one single + * command. */ +__api __check_ret int iio_device_attr_write_all(struct iio_device *dev, + ssize_t (*cb)(struct iio_device *dev, + const char *attr, void *buf, size_t len, void *d), + void *data); + + +/** @brief Set the value of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A bool value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_attr_write_bool(const struct iio_device *dev, + const char *attr, bool val); + + +/** @brief Set the value of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A long long value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_attr_write_longlong(const struct iio_device *dev, + const char *attr, long long val); + + +/** @brief Set the value of the given device-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A double value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_attr_write_double(const struct iio_device *dev, + const char *attr, double val); + +/** @brief Read the content of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param dst A pointer to the memory area where the NULL-terminated string + * corresponding to the value read will be stored + * @param len The available length of the memory area, in bytes + * @return On success, the number of bytes written to the buffer + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to + * iio_device_buffer_attr_read, it is now possible to read all of the attributes + * of a device. + * + * The buffer is filled with one block of data per attribute of the buffer, + * by the order they appear in the iio_device structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, it corresponds to the errno code that were + * returned when reading the attribute; if positive, it corresponds to the + * length of the data read. In that case, the rest of the block contains + * the data. */ +__api __check_ret ssize_t iio_device_buffer_attr_read(const struct iio_device *dev, + const char *attr, char *dst, size_t len); + +/** @brief Read the content of all buffer-specific attributes + * @param dev A pointer to an iio_device structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the buffer-specific attributes are read in one single + * command. */ +__api __check_ret int iio_device_buffer_attr_read_all(struct iio_device *dev, + int (*cb)(struct iio_device *dev, const char *attr, + const char *value, size_t len, void *d), + void *data); + + +/** @brief Read the content of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a bool variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_buffer_attr_read_bool(const struct iio_device *dev, + const char *attr, bool *val); + + +/** @brief Read the content of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a long long variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_buffer_attr_read_longlong(const struct iio_device *dev, + const char *attr, long long *val); + + +/** @brief Read the content of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a double variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_buffer_attr_read_double(const struct iio_device *dev, + const char *attr, double *val); + + +/** @brief Set the value of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param src A NULL-terminated string to set the attribute to + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to + * iio_device_buffer_attr_write, it is now possible to write all of the + * attributes of a device. + * + * The buffer must contain one block of data per attribute of the buffer, + * by the order they appear in the iio_device structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, the attribute is not written; if positive, + * it corresponds to the length of the data to write. In that case, the rest + * of the block must contain the data. */ +__api __check_ret ssize_t iio_device_buffer_attr_write(const struct iio_device *dev, + const char *attr, const char *src); + + +/** @brief Set the value of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param src A pointer to the data to be written + * @param len The number of bytes that should be written + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned */ +__api __check_ret ssize_t iio_device_buffer_attr_write_raw(const struct iio_device *dev, + const char *attr, const void *src, size_t len); + + +/** @brief Set the values of all buffer-specific attributes + * @param dev A pointer to an iio_device structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the buffer-specific attributes are written in one single + * command. */ +__api __check_ret int iio_device_buffer_attr_write_all(struct iio_device *dev, + ssize_t (*cb)(struct iio_device *dev, + const char *attr, void *buf, size_t len, void *d), + void *data); + + +/** @brief Set the value of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A bool value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_buffer_attr_write_bool(const struct iio_device *dev, + const char *attr, bool val); + + +/** @brief Set the value of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A long long value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_buffer_attr_write_longlong(const struct iio_device *dev, + const char *attr, long long val); + + +/** @brief Set the value of the given buffer-specific attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A double value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_buffer_attr_write_double(const struct iio_device *dev, + const char *attr, double val); + + +/** @brief Associate a pointer to an iio_device structure + * @param dev A pointer to an iio_device structure + * @param data The pointer to be associated */ +__api void iio_device_set_data(struct iio_device *dev, void *data); + + +/** @brief Retrieve a previously associated pointer of an iio_device structure + * @param dev A pointer to an iio_device structure + * @return The pointer previously associated if present, or NULL */ +__api void * iio_device_get_data(const struct iio_device *dev); + + +/** @brief Retrieve the trigger of a given device + * @param dev A pointer to an iio_device structure + * @param trigger a pointer to a pointer of an iio_device structure. The pointed + * pointer will be set to the address of the iio_device structure corresponding + * to the associated trigger device. + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_get_trigger(const struct iio_device *dev, + const struct iio_device **trigger); + + +/** @brief Associate a trigger to a given device + * @param dev A pointer to an iio_device structure + * @param trigger a pointer to the iio_device structure corresponding to the + * trigger that should be associated. + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_set_trigger(const struct iio_device *dev, + const struct iio_device *trigger); + + +/** @brief Return True if the given device is a trigger + * @param dev A pointer to an iio_device structure + * @return True if the device is a trigger, False otherwise */ +__api __check_ret __pure bool iio_device_is_trigger(const struct iio_device *dev); + +/** @brief Configure the number of kernel buffers for a device + * + * This function allows to change the number of buffers on kernel side. + * @param dev A pointer to an iio_device structure + * @param nb_buffers The number of buffers + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_set_kernel_buffers_count(const struct iio_device *dev, + unsigned int nb_buffers); + +/** @} *//* ------------------------------------------------------------------*/ +/* ------------------------- Channel functions -------------------------------*/ +/** @defgroup Channel Channel + * @{ + * @struct iio_channel + * @brief Represents an input or output channel of a device */ + + +/** @brief Retrieve a pointer to the iio_device structure + * @param chn A pointer to an iio_channel structure + * @return A pointer to an iio_device structure */ +__api __check_ret __pure const struct iio_device * iio_channel_get_device( + const struct iio_channel *chn); + + +/** @brief Retrieve the channel ID (e.g. voltage0) + * @param chn A pointer to an iio_channel structure + * @return A pointer to a static NULL-terminated string */ +__api __check_ret __pure const char * iio_channel_get_id(const struct iio_channel *chn); + + +/** @brief Retrieve the channel name (e.g. vccint) + * @param chn A pointer to an iio_channel structure + * @return A pointer to a static NULL-terminated string + * + * NOTE: if the channel has no name, NULL is returned. */ +__api __check_ret __pure const char * iio_channel_get_name(const struct iio_channel *chn); + + +/** @brief Return True if the given channel is an output channel + * @param chn A pointer to an iio_channel structure + * @return True if the channel is an output channel, False otherwise */ +__api __check_ret __pure bool iio_channel_is_output(const struct iio_channel *chn); + + +/** @brief Return True if the given channel is a scan element + * @param chn A pointer to an iio_channel structure + * @return True if the channel is a scan element, False otherwise + * + * NOTE: a channel that is a scan element is a channel that can + * generate samples (for an input channel) or receive samples (for an output + * channel) after being enabled. */ +__api __check_ret __pure bool iio_channel_is_scan_element(const struct iio_channel *chn); + + +/** @brief Enumerate the channel-specific attributes of the given channel + * @param chn A pointer to an iio_channel structure + * @return The number of channel-specific attributes found */ +__api __check_ret __pure unsigned int iio_channel_get_attrs_count( + const struct iio_channel *chn); + + +/** @brief Get the channel-specific attribute present at the given index + * @param chn A pointer to an iio_channel structure + * @param index The index corresponding to the attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the index is invalid, NULL is returned */ +__api __check_ret __pure const char * iio_channel_get_attr( + const struct iio_channel *chn, unsigned int index); + + +/** @brief Try to find a channel-specific attribute by its name + * @param chn A pointer to an iio_channel structure + * @param name A NULL-terminated string corresponding to the name of the + * attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the name does not correspond to any known attribute of the given + * channel, 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. */ +__api __check_ret __pure const char * iio_channel_find_attr( + const struct iio_channel *chn, const char *name); + + +/** @brief Retrieve the filename of an attribute + * @param chn A pointer to an iio_channel structure + * @param attr a NULL-terminated string corresponding to the name of the + * attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the attribute name is unknown, NULL is returned */ +__api __check_ret __pure const char * iio_channel_attr_get_filename( + const struct iio_channel *chn, const char *attr); + + +/** @brief Read the content of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param dst A pointer to the memory area where the NULL-terminated string + * corresponding to the value read will be stored + * @param len The available length of the memory area, in bytes + * @return On success, the number of bytes written to the buffer + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to iio_channel_attr_read, + * it is now possible to read all of the attributes of a channel. + * + * The buffer is filled with one block of data per attribute of the channel, + * by the order they appear in the iio_channel structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, it corresponds to the errno code that were + * returned when reading the attribute; if positive, it corresponds to the + * length of the data read. In that case, the rest of the block contains + * the data. */ +__api __check_ret ssize_t iio_channel_attr_read(const struct iio_channel *chn, + const char *attr, char *dst, size_t len); + + +/** @brief Read the content of all channel-specific attributes + * @param chn A pointer to an iio_channel structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the channel-specific attributes are read in one single + * command. */ +__api __check_ret int iio_channel_attr_read_all(struct iio_channel *chn, + int (*cb)(struct iio_channel *chn, + const char *attr, const char *val, size_t len, void *d), + void *data); + + +/** @brief Read the content of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a bool variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_channel_attr_read_bool(const struct iio_channel *chn, + const char *attr, bool *val); + + +/** @brief Read the content of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a long long variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_channel_attr_read_longlong(const struct iio_channel *chn, + const char *attr, long long *val); + + +/** @brief Read the content of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A pointer to a double variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_channel_attr_read_double(const struct iio_channel *chn, + const char *attr, double *val); + + +/** @brief Set the value of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param src A NULL-terminated string to set the attribute to + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to iio_channel_attr_write, + * it is now possible to write all of the attributes of a channel. + * + * The buffer must contain one block of data per attribute of the channel, + * by the order they appear in the iio_channel structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, the attribute is not written; if positive, + * it corresponds to the length of the data to write. In that case, the rest + * of the block must contain the data. */ +__api __check_ret ssize_t iio_channel_attr_write(const struct iio_channel *chn, + const char *attr, const char *src); + + +/** @brief Set the value of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param src A pointer to the data to be written + * @param len The number of bytes that should be written + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned */ +__api __check_ret ssize_t iio_channel_attr_write_raw(const struct iio_channel *chn, + const char *attr, const void *src, size_t len); + + +/** @brief Set the values of all channel-specific attributes + * @param chn A pointer to an iio_channel structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the channel-specific attributes are written in one single + * command. */ +__api __check_ret int iio_channel_attr_write_all(struct iio_channel *chn, + ssize_t (*cb)(struct iio_channel *chn, + const char *attr, void *buf, size_t len, void *d), + void *data); + + +/** @brief Set the value of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A bool value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_channel_attr_write_bool(const struct iio_channel *chn, + const char *attr, bool val); + + +/** @brief Set the value of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A long long value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_channel_attr_write_longlong(const struct iio_channel *chn, + const char *attr, long long val); + + +/** @brief Set the value of the given channel-specific attribute + * @param chn A pointer to an iio_channel structure + * @param attr A NULL-terminated string corresponding to the name of the + * attribute + * @param val A double value to set the attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_channel_attr_write_double(const struct iio_channel *chn, + const char *attr, double val); + + +/** @brief Enable the given channel + * @param chn A pointer to an iio_channel structure + * + * NOTE:Before creating an iio_buffer structure with + * iio_device_create_buffer, it is required to enable at least one channel of + * the device to read from. */ +__api void iio_channel_enable(struct iio_channel *chn); + + +/** @brief Disable the given channel + * @param chn A pointer to an iio_channel structure */ +__api void iio_channel_disable(struct iio_channel *chn); + + +/** @brief Returns True if the channel is enabled + * @param chn A pointer to an iio_channel structure + * @return True if the channel is enabled, False otherwise */ +__api __check_ret bool iio_channel_is_enabled(const struct iio_channel *chn); + + +/** @brief Demultiplex the samples of a given channel + * @param chn A pointer to an iio_channel structure + * @param buffer A pointer to an iio_buffer structure + * @param dst A pointer to the memory area where the demultiplexed data will be + * stored + * @param len The available length of the memory area, in bytes + * @return The size of the demultiplexed data, in bytes */ +__api __check_ret size_t iio_channel_read_raw(const struct iio_channel *chn, + struct iio_buffer *buffer, void *dst, size_t len); + + +/** @brief Demultiplex and convert the samples of a given channel + * @param chn A pointer to an iio_channel structure + * @param buffer A pointer to an iio_buffer structure + * @param dst A pointer to the memory area where the converted data will be + * stored + * @param len The available length of the memory area, in bytes + * @return The size of the converted data, in bytes */ +__api __check_ret size_t iio_channel_read(const struct iio_channel *chn, + struct iio_buffer *buffer, void *dst, size_t len); + + +/** @brief Multiplex the samples of a given channel + * @param chn A pointer to an iio_channel structure + * @param buffer A pointer to an iio_buffer structure + * @param src A pointer to the memory area where the sequential data will + * be read from + * @param len The length of the memory area, in bytes + * @return The number of bytes actually multiplexed */ +__api __check_ret size_t iio_channel_write_raw(const struct iio_channel *chn, + struct iio_buffer *buffer, const void *src, size_t len); + + +/** @brief Convert and multiplex the samples of a given channel + * @param chn A pointer to an iio_channel structure + * @param buffer A pointer to an iio_buffer structure + * @param src A pointer to the memory area where the sequential data will + * be read from + * @param len The length of the memory area, in bytes + * @return The number of bytes actually converted and multiplexed */ +__api __check_ret size_t iio_channel_write(const struct iio_channel *chn, + struct iio_buffer *buffer, const void *src, size_t len); + + +/** @brief Associate a pointer to an iio_channel structure + * @param chn A pointer to an iio_channel structure + * @param data The pointer to be associated */ +__api void iio_channel_set_data(struct iio_channel *chn, void *data); + + +/** @brief Retrieve a previously associated pointer of an iio_channel structure + * @param chn A pointer to an iio_channel structure + * @return The pointer previously associated if present, or NULL */ +__api void * iio_channel_get_data(const struct iio_channel *chn); + + +/** @brief Get the type of the given channel + * @param chn A pointer to an iio_channel structure + * @return The type of the channel */ +__api __check_ret __pure enum iio_chan_type iio_channel_get_type( + const struct iio_channel *chn); + + +/** @brief Get the modifier type of the given channel + * @param chn A pointer to an iio_channel structure + * @return The modifier type of the channel */ +__api __check_ret __pure enum iio_modifier iio_channel_get_modifier( + const struct iio_channel *chn); + + +/** @} *//* ------------------------------------------------------------------*/ +/* ------------------------- Buffer functions --------------------------------*/ +/** @defgroup Buffer Buffer + * @{ + * @struct iio_buffer + * @brief An input or output buffer, used to read or write samples */ + + +/** @brief Retrieve a pointer to the iio_device structure + * @param buf A pointer to an iio_buffer structure + * @return A pointer to an iio_device structure */ +__api __check_ret __pure const struct iio_device * iio_buffer_get_device( + const struct iio_buffer *buf); + + +/** @brief Create an input or output buffer associated to the given device + * @param dev A pointer to an iio_device structure + * @param samples_count The number of samples that the buffer should contain + * @param cyclic If True, enable cyclic mode + * @return On success, a pointer to an iio_buffer structure + * @return On error, NULL is returned, and errno is set to the error code + * + * NOTE: Channels that have to be written to / read from must be enabled + * before creating the buffer. */ +__api __check_ret struct iio_buffer * iio_device_create_buffer(const struct iio_device *dev, + size_t samples_count, bool cyclic); + + +/** @brief Destroy the given buffer + * @param buf A pointer to an iio_buffer structure + * + * NOTE: After that function, the iio_buffer pointer shall be invalid. */ +__api void iio_buffer_destroy(struct iio_buffer *buf); + +/** @brief Get a pollable file descriptor + * + * Can be used to know when iio_buffer_refill() or iio_buffer_push() can be + * called + * @param buf A pointer to an iio_buffer structure + * @return On success, valid file descriptor + * @return On error, a negative errno code is returned + */ +__api __check_ret int iio_buffer_get_poll_fd(struct iio_buffer *buf); + +/** @brief Make iio_buffer_refill() and iio_buffer_push() blocking or not + * + * After this function has been called with blocking == false, + * iio_buffer_refill() and iio_buffer_push() will return -EAGAIN if no data is + * ready. + * A device is blocking by default. + * @param buf A pointer to an iio_buffer structure + * @param blocking true if the buffer API should be blocking, else false + * @return On success, 0 + * @return On error, a negative errno code is returned + */ +__api __check_ret int iio_buffer_set_blocking_mode(struct iio_buffer *buf, bool blocking); + + +/** @brief Fetch more samples from the hardware + * @param buf A pointer to an iio_buffer structure + * @return On success, the number of bytes read is returned + * @return On error, a negative errno code is returned + * + * NOTE: Only valid for input buffers */ +__api __check_ret ssize_t iio_buffer_refill(struct iio_buffer *buf); + + +/** @brief Send the samples to the hardware + * @param buf A pointer to an iio_buffer structure + * @return On success, the number of bytes written is returned + * @return On error, a negative errno code is returned + * + * NOTE: Only valid for output buffers */ +__api __check_ret ssize_t iio_buffer_push(struct iio_buffer *buf); + + +/** @brief Send a given number of samples to the hardware + * @param buf A pointer to an iio_buffer structure + * @param samples_count The number of samples to submit + * @return On success, the number of bytes written is returned + * @return On error, a negative errno code is returned + * + * NOTE: Only valid for output buffers */ +__api __check_ret ssize_t iio_buffer_push_partial(struct iio_buffer *buf, + size_t samples_count); + +/** @brief Cancel all buffer operations + * @param buf The buffer for which operations should be canceled + * + * This function cancels all outstanding buffer operations previously scheduled. + * This means any pending iio_buffer_push() or iio_buffer_refill() operation + * will abort and return immediately, any further invocations of these functions + * on the same buffer will return immediately with an error. + * + * Usually iio_buffer_push() and iio_buffer_refill() will block until either all + * data has been transferred or a timeout occurs. This can depending on the + * configuration take a significant amount of time. iio_buffer_cancel() is + * useful to bypass these conditions if the buffer operation is supposed to be + * stopped in response to an external event (e.g. user input). + * + * To be able to capture additional data after calling this function the buffer + * should be destroyed and then re-created. + * + * This function can be called multiple times for the same buffer, but all but + * the first invocation will be without additional effect. + * + * This function is thread-safe, but not signal-safe, i.e. it must not be called + * from a signal handler. + */ +__api void iio_buffer_cancel(struct iio_buffer *buf); + + +/** @brief Get the start address of the buffer + * @param buf A pointer to an iio_buffer structure + * @return A pointer corresponding to the start address of the buffer */ +__api void * iio_buffer_start(const struct iio_buffer *buf); + + +/** @brief Find the first sample of a channel in a buffer + * @param buf A pointer to an iio_buffer structure + * @param chn A pointer to an iio_channel structure + * @return A pointer to the first sample found, or to the end of the buffer if + * no sample for the given channel is present in the buffer + * + * NOTE: This function, coupled with iio_buffer_step and iio_buffer_end, + * can be used to iterate on all the samples of a given channel present in the + * buffer, doing the following: + * + * @verbatim + for (void *ptr = iio_buffer_first(buffer, chn); ptr < iio_buffer_end(buffer); ptr += iio_buffer_step(buffer)) { + .... + } + @endverbatim */ +__api void * iio_buffer_first(const struct iio_buffer *buf, + const struct iio_channel *chn); + + +/** @brief Get the step size between two samples of one channel + * @param buf A pointer to an iio_buffer structure + * @return the difference between the addresses of two consecutive samples of + * one same channel */ +__api __check_ret ptrdiff_t iio_buffer_step(const struct iio_buffer *buf); + + +/** @brief Get the address that follows the last sample in a buffer + * @param buf A pointer to an iio_buffer structure + * @return A pointer corresponding to the address that follows the last sample + * present in the buffer */ +__api void * iio_buffer_end(const struct iio_buffer *buf); + + +/** @brief Call the supplied callback for each sample found in a buffer + * @param buf A pointer to an iio_buffer structure + * @param callback A pointer to a function to call for each sample found + * @param data A user-specified pointer that will be passed to the callback + * @return number of bytes processed. + * + * NOTE: The callback receives four arguments: + * * A pointer to the iio_channel structure corresponding to the sample, + * * A pointer to the sample itself, + * * The length of the sample in bytes, + * * The user-specified pointer passed to iio_buffer_foreach_sample. */ +__api __check_ret ssize_t iio_buffer_foreach_sample(struct iio_buffer *buf, + ssize_t (*callback)(const struct iio_channel *chn, + void *src, size_t bytes, void *d), void *data); + + +/** @brief Associate a pointer to an iio_buffer structure + * @param buf A pointer to an iio_buffer structure + * @param data The pointer to be associated */ +__api void iio_buffer_set_data(struct iio_buffer *buf, void *data); + + +/** @brief Retrieve a previously associated pointer of an iio_buffer structure + * @param buf A pointer to an iio_buffer structure + * @return The pointer previously associated if present, or NULL */ +__api void * iio_buffer_get_data(const struct iio_buffer *buf); + +/** @} *//* ------------------------------------------------------------------*/ +/* ---------------------------- HWMON support --------------------------------*/ +/** @defgroup Hwmon Compatibility with hardware monitoring (hwmon) devices + * @{ + * @enum hwmon_chan_type + * @brief Hwmon channel type + * + * Libiio support hardware-monitoring (hwmon) devices as well. This enum + * specifies the type of data associated with the hwmon channel. + * + * NOTE: as of 2021 only the current hwmon API is supported. The old + * and deprecated APIs are not supported, and won't be supported unless we + * have a case where updating a hwmon driver is not possible. + */ +enum hwmon_chan_type { + HWMON_VOLTAGE, + HWMON_FAN, + HWMON_PWM, + HWMON_TEMP, + HWMON_CURRENT, + HWMON_POWER, + HWMON_ENERGY, + HWMON_HUMIDITY, + HWMON_INTRUSION, + HWMON_CHAN_TYPE_UNKNOWN = IIO_CHAN_TYPE_UNKNOWN, +}; + +/** + * @brief Get the type of the given hwmon channel + * @param chn A pointer to an iio_channel structure + * @return The type of the hwmon channel */ +static inline enum hwmon_chan_type +hwmon_channel_get_type(const struct iio_channel *chn) +{ + return (enum hwmon_chan_type) iio_channel_get_type(chn); +} + +/** + * @brief Get whether or not the device is a hardware monitoring device + * @param dev A pointer to an iio_device structure + * @return True if the device is a hardware monitoring device, + * false if it is a IIO device */ +static inline bool iio_device_is_hwmon(const struct iio_device *dev) +{ + const char *id = iio_device_get_id(dev); + + return id[0] == 'h'; +} + + +/** @} *//* ------------------------------------------------------------------*/ +/* ------------------------- Low-level functions -----------------------------*/ +/** @defgroup Debug Debug and low-level functions + * @{ + * @struct iio_data_format + * @brief Contains the format of a data sample. + * + * The different fields inform about the correct way to convert one sample from + * its raw format (as read from / generated by the hardware) to its real-world + * value. + */ +struct iio_data_format { + /** @brief Total length of the sample, in bits */ + unsigned int length; + + /** @brief Length of valuable data in the sample, in bits */ + unsigned int bits; + + /** @brief Right-shift to apply when converting sample */ + unsigned int shift; + + /** @brief Contains True if the sample is signed */ + bool is_signed; + + /** @brief Contains True if the sample is fully defined, sign extended, etc. */ + bool is_fully_defined; + + /** @brief Contains True if the sample is in big-endian format */ + bool is_be; + + /** @brief Contains True if the sample should be scaled when converted */ + bool with_scale; + + /** @brief Contains the scale to apply if with_scale is set */ + double scale; + + /** @brief Number of times length repeats (added in v0.8) */ + unsigned int repeat; +}; + + +/** @brief Get the current sample size + * @param dev A pointer to an iio_device structure + * @return On success, the sample size in bytes + * @return On error, a negative errno code is returned + * + * NOTE: The sample size is not constant and will change when channels + * get enabled or disabled. */ +__api __check_ret ssize_t iio_device_get_sample_size(const struct iio_device *dev); + + +/** @brief Get the index of the given channel + * @param chn A pointer to an iio_channel structure + * @return On success, the index of the specified channel + * @return On error, a negative errno code is returned */ +__api __check_ret __pure long iio_channel_get_index(const struct iio_channel *chn); + + +/** @brief Get a pointer to a channel's data format structure + * @param chn A pointer to an iio_channel structure + * @return A pointer to the channel's iio_data_format structure */ +__api __check_ret __cnst const struct iio_data_format * iio_channel_get_data_format( + const struct iio_channel *chn); + + +/** @brief Convert the sample from hardware format to host format + * @param chn A pointer to an iio_channel structure + * @param dst A pointer to the destination buffer where the converted sample + * should be written + * @param src A pointer to the source buffer containing the sample */ +__api void iio_channel_convert(const struct iio_channel *chn, + void *dst, const void *src); + + +/** @brief Convert the sample from host format to hardware format + * @param chn A pointer to an iio_channel structure + * @param dst A pointer to the destination buffer where the converted sample + * should be written + * @param src A pointer to the source buffer containing the sample */ +__api void iio_channel_convert_inverse(const struct iio_channel *chn, + void *dst, const void *src); + + +/** @brief Enumerate the debug attributes of the given device + * @param dev A pointer to an iio_device structure + * @return The number of debug attributes found */ +__api __check_ret __pure unsigned int iio_device_get_debug_attrs_count( + const struct iio_device *dev); + + +/** @brief Get the debug attribute present at the given index + * @param dev A pointer to an iio_device structure + * @param index The index corresponding to the debug attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the index is invalid, NULL is returned */ +__api __check_ret __pure const char * iio_device_get_debug_attr( + const struct iio_device *dev, unsigned int index); + + +/** @brief Try to find a debug attribute by its name + * @param dev A pointer to an iio_device structure + * @param name A NULL-terminated string corresponding to the name of the + * debug attribute + * @return On success, a pointer to a static NULL-terminated string + * @return If the name does not correspond to any known debug attribute of the + * given device, NULL is returned + * + * NOTE: This function is useful to detect the presence of a debug + * attribute. + * It can also be used to retrieve the name of a debug attribute as a pointer + * to a static string from a dynamically allocated string. */ +__api __check_ret __pure const char * iio_device_find_debug_attr( + const struct iio_device *dev, const char *name); + + +/** @brief Read the content of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param dst A pointer to the memory area where the NULL-terminated string + * corresponding to the value read will be stored + * @param len The available length of the memory area, in bytes + * @return On success, the number of bytes written to the buffer + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to + * iio_device_debug_attr_read, it is now possible to read all of the debug + * attributes of a device. + * + * The buffer is filled with one block of data per debug attribute of the + * device, by the order they appear in the iio_device structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, it corresponds to the errno code that were + * returned when reading the debug attribute; if positive, it corresponds + * to the length of the data read. In that case, the rest of the block contains + * the data. */ +__api __check_ret ssize_t iio_device_debug_attr_read(const struct iio_device *dev, + const char *attr, char *dst, size_t len); + + +/** @brief Read the content of all debug attributes + * @param dev A pointer to an iio_device structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the debug attributes are read in one single command. */ +__api __check_ret int iio_device_debug_attr_read_all(struct iio_device *dev, + int (*cb)(struct iio_device *dev, const char *attr, + const char *value, size_t len, void *d), + void *data); + + +/** @brief Set the value of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param src A NULL-terminated string to set the debug attribute to + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned + * + * NOTE:By passing NULL as the "attr" argument to + * iio_device_debug_attr_write, it is now possible to write all of the + * debug attributes of a device. + * + * The buffer must contain one block of data per debug attribute of the device, + * by the order they appear in the iio_device structure. + * + * The first four bytes of one block correspond to a 32-bit signed value in + * network order. If negative, the debug attribute is not written; if positive, + * it corresponds to the length of the data to write. In that case, the rest + * of the block must contain the data. */ +__api __check_ret ssize_t iio_device_debug_attr_write(const struct iio_device *dev, + const char *attr, const char *src); + + +/** @brief Set the value of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param src A pointer to the data to be written + * @param len The number of bytes that should be written + * @return On success, the number of bytes written + * @return On error, a negative errno code is returned */ +__api __check_ret ssize_t iio_device_debug_attr_write_raw(const struct iio_device *dev, + const char *attr, const void *src, size_t len); + + +/** @brief Set the values of all debug attributes + * @param dev A pointer to an iio_device structure + * @param cb A pointer to a callback function + * @param data A pointer that will be passed to the callback function + * @return On success, 0 is returned + * @return On error, a negative errno code is returned + * + * NOTE: This function is especially useful when used with the network + * backend, as all the debug attributes are written in one single command. */ +__api __check_ret int iio_device_debug_attr_write_all(struct iio_device *dev, + ssize_t (*cb)(struct iio_device *dev, + const char *attr, void *buf, size_t len, void *d), + void *data); + + +/** @brief Read the content of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param val A pointer to a bool variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_debug_attr_read_bool(const struct iio_device *dev, + const char *attr, bool *val); + + +/** @brief Read the content of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param val A pointer to a long long variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_debug_attr_read_longlong(const struct iio_device *dev, + const char *attr, long long *val); + + +/** @brief Read the content of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param val A pointer to a double variable where the value should be stored + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_debug_attr_read_double(const struct iio_device *dev, + const char *attr, double *val); + + +/** @brief Set the value of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param val A bool value to set the debug attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_debug_attr_write_bool(const struct iio_device *dev, + const char *attr, bool val); + + +/** @brief Set the value of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param val A long long value to set the debug attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_debug_attr_write_longlong(const struct iio_device *dev, + const char *attr, long long val); + + +/** @brief Set the value of the given debug attribute + * @param dev A pointer to an iio_device structure + * @param attr A NULL-terminated string corresponding to the name of the + * debug attribute + * @param val A double value to set the debug attribute to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_debug_attr_write_double(const struct iio_device *dev, + const char *attr, double val); + + +/** @brief Identify the channel or debug attribute corresponding to a filename + * @param dev A pointer to an iio_device structure + * @param filename A NULL-terminated string corresponding to the filename + * @param chn A pointer to a pointer of an iio_channel structure. The pointed + * pointer will be set to the address of the iio_channel structure if the + * filename correspond to the attribute of a channel, or NULL otherwise. + * @param attr A pointer to a NULL-terminated string. The pointer + * pointer will be set to point to the name of the attribute corresponding to + * the filename. + * @return On success, 0 is returned, and *chn and *attr are modified. + * @return On error, a negative errno code is returned. *chn and *attr are not + * modified. */ +__api __check_ret int iio_device_identify_filename(const struct iio_device *dev, + const char *filename, struct iio_channel **chn, + const char **attr); + + +/** @brief Set the value of a hardware register + * @param dev A pointer to an iio_device structure + * @param address The address of the register + * @param value The value to set the register to + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_reg_write(struct iio_device *dev, + uint32_t address, uint32_t value); + + +/** @brief Get the value of a hardware register + * @param dev A pointer to an iio_device structure + * @param address The address of the register + * @param value A pointer to the variable where the value will be written + * @return On success, 0 is returned + * @return On error, a negative errno code is returned */ +__api __check_ret int iio_device_reg_read(struct iio_device *dev, + uint32_t address, uint32_t *value); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#undef __api + +#endif /* __IIO_H__ */ From 172715f91079b42d6f22f4cf9ca4704df0368d2f Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Wed, 23 Nov 2022 14:54:39 +0100 Subject: [PATCH 02/11] Implement Bullse Eye Level for IIO visualization --- .../Blocks/Examples/TestHardwareIIO.mo | 115 ++++++++++++------ 1 file changed, 81 insertions(+), 34 deletions(-) diff --git a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo index 96cfcc8e..144debd0 100644 --- a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo +++ b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo @@ -1,56 +1,103 @@ within Modelica_DeviceDrivers.Blocks.Examples; model TestHardwareIIO "Example to access the Inertial Measurement Unit of a Pinephone via InternetIO" import Modelica_DeviceDrivers; -extends Modelica.Icons.Example; + extends Modelica.Icons.Example; Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.IIOConfig iio(deviceName="mobian.local") annotation (Placement(transformation(extent={{-80,60},{-60,80}}))); Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.PhysicalDataRead dataRead_x( - sampleTime=0.1, + sampleTime=0.05, iio=iio.dh, devicename="mpu6050", - channelname="accel_x") annotation (Placement(transformation(extent={{-80,20},{-60,40}}))); + channelname="accel_x") annotation (Placement(transformation(extent={{-80,-10},{-60,10}}))); Modelica_DeviceDrivers.Blocks.OperatingSystem.RealtimeSynchronize - realtimeSynchronize + realtimeSynchronize( + enable=true, + sampled=true, + sampleTime=0.05) annotation (Placement(transformation(extent={{60,60},{80,80}}))); Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.PhysicalDataRead dataRead_y( - sampleTime=0.1, + sampleTime=0.05, iio=iio.dh, devicename="mpu6050", - channelname="accel_y") annotation (Placement(transformation(extent={{-80,-10},{-60,10}}))); + channelname="accel_y") annotation (Placement(transformation(extent={{-80,-40},{-60,-20}}))); Modelica_DeviceDrivers.Blocks.HardwareIO.IIO.PhysicalDataRead dataRead_z( - sampleTime=0.1, + sampleTime=0.05, iio=iio.dh, devicename="mpu6050", - channelname="accel_z") annotation (Placement(transformation(extent={{-80,-40},{-60,-20}}))); - Modelica.Blocks.Routing.Multiplex3 a annotation (Placement(transformation(extent={{-40,-10},{-20,10}}))); - Modelica.Blocks.Math.Feedback feedback[3] annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); - Modelica.Blocks.Sources.RealExpression realExpression[3](y={0.11838963325622613, - 0.17931387736615592,9.054748576489855}) annotation (Placement(transformation(extent={{-40,-60},{-20,-40}}))); - Modelica.Blocks.Continuous.Integrator v[3] annotation (Placement(transformation(extent={{20,-10},{40,10}}))); - Modelica.Blocks.Continuous.Integrator s[3] annotation (Placement(transformation(extent={{60,-10},{80,10}}))); - Modelica.Mechanics.MultiBody.Visualizers.FixedShape fixedShape( - shapeType="sphere", - r_shape=a.y, - length=0.1, - width=0.1, - height=0.1) annotation (Placement(transformation(extent={{20,60},{40,80}}))); - inner Modelica.Mechanics.MultiBody.World world annotation (Placement(transformation(extent={{-20,60},{0,80}}))); + channelname="accel_z") annotation (Placement(transformation(extent={{-80,-70},{-60,-50}}))); + Modelica.Blocks.Routing.Multiplex3 a annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); + + BullsEyeLevel bullsEyeLevel annotation (Placement(transformation(extent={{10,-70},{90,10}}))); + + model BullsEyeLevel + extends Modelica.Blocks.Interfaces.MIMO(nin=3,nout=2); + + parameter Modelica.Units.SI.Length d = 0.02 "Diameter of the virtual detection sphere"; + + Modelica.Units.SI.Length r[3] "Position of the ball"; + Modelica.Units.SI.Velocity v[3] "Velocity of the ball"; + Modelica.Units.SI.Acceleration a[3] "Acceleration of the ball"; + + Modelica.Units.SI.Angle theta "Polar angle from the origin to the ball"; + Modelica.Units.SI.Angle psi "Azimuth angle from the origin to the ball"; + + Modelica.Mechanics.MultiBody.Types.Axis e_r "Normalized vector from the origin to the ball"; + Modelica.Mechanics.MultiBody.Types.Axis e_theta "Normalized vector in azimuth direction on the sphere"; + Modelica.Mechanics.MultiBody.Types.Axis e_psi "Normalized vector in altitude direction on the sphere"; + + Real x2D[2] "Coordinates of the ball center in 2D representation"; + + equation + e_r[1] = sin(theta)*cos(psi); + e_r[2] = sin(theta)*sin(psi); + e_r[3] = cos(theta); + + e_theta[1] = cos(theta)*cos(psi); + e_theta[2] = cos(theta)*sin(psi); + e_theta[3] = -sin(theta); + + e_psi = cross(e_r,e_theta); + + r = d/2*e_r; + der(r) = v; + a = u; + + der(theta) = a*e_theta; + der(psi) = a*e_psi/max(Modelica.Constants.eps,d/2*sin(theta)); + + y = {theta,psi}; + + x2D[1] = -80*sin(theta)*sin(psi); + x2D[2] = 80*sin(theta)*cos(psi); + + annotation (Icon(graphics={ + Ellipse(extent={{-80,80},{80,-80}}, lineColor={0,0,0}), + Ellipse(extent={{-40,40},{40,-40}}, lineColor={0,0,0}), + Line( + points={{0,-90},{0,90}}, + color={0,0,0}, + pattern=LinePattern.None), + Line(points={{0,-90},{0,90}}, color={0,0,0}), + Line(points={{-90,0},{90,0}}, color={0,0,0}), + Ellipse( + extent=DynamicSelect({{-10,10},{10,-10}},{{-10,10}+x2D,{10,-10}+x2D}), + pattern=LinePattern.None, + fillColor={0,0,0}, + fillPattern=FillPattern.Solid)}), Documentation(info=" +

This model implements a virtual ball hinged with a fixed radius to a central fixation resctricting its path to a sphere. The input accelerations act on that ball. The animation is a top view of the sphere with the current position of the ball.

+")); + end BullsEyeLevel; equation - connect(dataRead_x.y, a.u1[1]) annotation (Line(points={{-59,30},{-50,30},{-50,7},{-42,7}}, color={0,0,127})); - connect(dataRead_y.y, a.u2[1]) annotation (Line(points={{-59,0},{-42,0}}, color={0,0,127})); - connect(dataRead_z.y, a.u3[1]) annotation (Line(points={{-59,-30},{-50,-30},{-50,-7},{-42,-7}}, color={0,0,127})); - connect(a.y, feedback.u1) annotation (Line(points={{-19,0},{-8,0}}, color={0,0,127})); - connect(realExpression.y, feedback.u2) annotation (Line(points={{-19,-50},{0,-50},{0,-8}}, color={0,0,127})); - connect(feedback.y, v.u) annotation (Line(points={{9,0},{18,0}}, color={0,0,127})); - connect(v.y, s.u) annotation (Line(points={{41,0},{58,0}}, color={0,0,127})); - connect(world.frame_b, fixedShape.frame_a) - annotation (Line( - points={{0,70},{20,70}}, - color={95,95,95}, - thickness=0.5)); + connect(dataRead_x.y, a.u1[1]) annotation (Line(points={{-59,0},{-50,0},{-50,-23},{-42,-23}}, + color={0,0,127})); + connect(dataRead_y.y, a.u2[1]) annotation (Line(points={{-59,-30},{-42,-30}}, + color={0,0,127})); + connect(dataRead_z.y, a.u3[1]) annotation (Line(points={{-59,-60},{-50,-60},{-50,-37},{-42,-37}}, + color={0,0,127})); + connect(a.y, bullsEyeLevel.u) annotation (Line(points={{-19,-30},{2,-30}}, color={0,0,127})); annotation ( - experiment(StopTime=5.0), + experiment(__Dymola_Algorithm="Dassl", StopTime=20), Documentation(info="

This example was tested with a Mobian installation on a Pinephone. The package iiod has to be installed on the phone. It works out-of-the-box without further configuration.

Any other linux device supporting IIO can be used. Only the IIO deamon has to be installed and configured.

From 418ca0e07984dd8b03619156579f4c9f0d255c34 Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Thu, 1 Dec 2022 09:57:56 +0100 Subject: [PATCH 03/11] Remove experiment annotation --- .../Blocks/Examples/TestHardwareIIO.mo | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo index 144debd0..3d6c739e 100644 --- a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo +++ b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo @@ -89,16 +89,11 @@ model TestHardwareIIO "Example to access the Inertial Measurement Unit of a Pine ")); end BullsEyeLevel; equation - connect(dataRead_x.y, a.u1[1]) annotation (Line(points={{-59,0},{-50,0},{-50,-23},{-42,-23}}, - color={0,0,127})); - connect(dataRead_y.y, a.u2[1]) annotation (Line(points={{-59,-30},{-42,-30}}, - color={0,0,127})); - connect(dataRead_z.y, a.u3[1]) annotation (Line(points={{-59,-60},{-50,-60},{-50,-37},{-42,-37}}, - color={0,0,127})); + connect(dataRead_x.y, a.u1[1]) annotation (Line(points={{-59,0},{-50,0},{-50,-23},{-42,-23}}, color={0,0,127})); + connect(dataRead_y.y, a.u2[1]) annotation (Line(points={{-59,-30},{-42,-30}}, color={0,0,127})); + connect(dataRead_z.y, a.u3[1]) annotation (Line(points={{-59,-60},{-50,-60},{-50,-37},{-42,-37}}, color={0,0,127})); connect(a.y, bullsEyeLevel.u) annotation (Line(points={{-19,-30},{2,-30}}, color={0,0,127})); - annotation ( - experiment(__Dymola_Algorithm="Dassl", StopTime=20), - Documentation(info=" + annotation (Documentation(info="

This example was tested with a Mobian installation on a Pinephone. The package iiod has to be installed on the phone. It works out-of-the-box without further configuration.

Any other linux device supporting IIO can be used. Only the IIO deamon has to be installed and configured.

")); From fe677c981f3addac30d9817829752418a4bffc4d Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Fri, 2 Dec 2022 18:04:31 +0100 Subject: [PATCH 04/11] Bugfix in IIO data_read --- Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo b/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo index 85a0531f..0f5f328a 100644 --- a/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo +++ b/Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo @@ -3,11 +3,10 @@ encapsulated function data_read "Read from analog channel" import Modelica; extends Modelica.Icons.Function; import Modelica_DeviceDrivers.HardwareIO.IIO; - input IIO iio "Device handle"; - input String devicename = "/dev/comedi0" "Device name"; - input String channelname = "/dev/comedi0" "Device name"; - input String attrname = "/dev/comedi0" "Device name"; + import Modelica_DeviceDrivers.HardwareIO.IIOchannel; + input IIOchannel channel "Channel handle"; + input String attrname "Device name"; output Real data "Value that is read from channel"; - external "C" data = MDD_iio_data_read(iio, devicename, channelname, attrname) + external "C" data = MDD_iio_data_read(channel, attrname) annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); end data_read; From 28e5a6298b7a7d26777991ed46ae1b8a69c71962 Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Fri, 2 Dec 2022 18:04:43 +0100 Subject: [PATCH 05/11] Improve IIO documentation --- Modelica_DeviceDrivers/Blocks/HardwareIO.mo | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Modelica_DeviceDrivers/Blocks/HardwareIO.mo b/Modelica_DeviceDrivers/Blocks/HardwareIO.mo index 5ad33c05..28889abc 100644 --- a/Modelica_DeviceDrivers/Blocks/HardwareIO.mo +++ b/Modelica_DeviceDrivers/Blocks/HardwareIO.mo @@ -348,7 +348,9 @@ Enumeration that defines the available reference channels used in a DAQ-card Documentation(info="

Record for configuring a IIO device. At initialization time the IIO device given by the parameter deviceName will be opened and a handle to that device will be assigned to the final parameter dh.This handle needs to be passed as parameter to the remaining IIO read and write blocks.

Note

-

If accessing a local linux device, it iis required that the simulation process has sufficient privileges to access the intended device (usually that requires "root" privileges).

+

On Windows, the code should work fine with the provided libiio.lib file from the libiio Release (https://github.com/analogdevicesinc/libiio).

+

For linux, the IIO library has to be compiled first. Best practice is to run cmake with the BUILD_SHARED_LIBS=OFF parameter. This will create libiio.a in the build directory, which you can place in Resources/library/linux64.

+

If accessing a local linux device, it is required that the simulation process has sufficient privileges to access the intended device (usually that requires "root" privileges).

")); end IIOConfig; From aa4bbf695886aedbe07c381c019570fe8e52bdb7 Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Fri, 2 Dec 2022 18:09:13 +0100 Subject: [PATCH 06/11] Improve documentation of IIO example --- Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo index 3d6c739e..23b55faa 100644 --- a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo +++ b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo @@ -95,6 +95,6 @@ equation connect(a.y, bullsEyeLevel.u) annotation (Line(points={{-19,-30},{2,-30}}, color={0,0,127})); annotation (Documentation(info="

This example was tested with a Mobian installation on a Pinephone. The package iiod has to be installed on the phone. It works out-of-the-box without further configuration.

-

Any other linux device supporting IIO can be used. Only the IIO deamon has to be installed and configured.

+

Any other linux device supporting IIO (i. e. a Raspberry Pi connected to a MPU6050 chip) can be used. Only the IIO deamon has to be installed and configured.

")); end TestHardwareIIO; From 8ea3f33712a0b32d61089c07601f86725ce2ba23 Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Thu, 13 Apr 2023 15:57:07 +0200 Subject: [PATCH 07/11] Add start values and fix unit issues --- Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo index 23b55faa..574b0ee7 100644 --- a/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo +++ b/Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo @@ -28,7 +28,8 @@ model TestHardwareIIO "Example to access the Inertial Measurement Unit of a Pine channelname="accel_z") annotation (Placement(transformation(extent={{-80,-70},{-60,-50}}))); Modelica.Blocks.Routing.Multiplex3 a annotation (Placement(transformation(extent={{-40,-40},{-20,-20}}))); - BullsEyeLevel bullsEyeLevel annotation (Placement(transformation(extent={{10,-70},{90,10}}))); + BullsEyeLevel bullsEyeLevel(theta(fixed=true, start=0), psi(fixed=true, start=0)) + annotation (Placement(transformation(extent={{10,-70},{90,10}}))); model BullsEyeLevel extends Modelica.Blocks.Interfaces.MIMO(nin=3,nout=2); @@ -39,8 +40,8 @@ model TestHardwareIIO "Example to access the Inertial Measurement Unit of a Pine Modelica.Units.SI.Velocity v[3] "Velocity of the ball"; Modelica.Units.SI.Acceleration a[3] "Acceleration of the ball"; - Modelica.Units.SI.Angle theta "Polar angle from the origin to the ball"; - Modelica.Units.SI.Angle psi "Azimuth angle from the origin to the ball"; + Real theta "Polar angle from the origin to the ball" annotation (Dialog(showStartAttribute=true)); + Real psi "Azimuth angle from the origin to the ball" annotation (Dialog(showStartAttribute=true)); Modelica.Mechanics.MultiBody.Types.Axis e_r "Normalized vector from the origin to the ball"; Modelica.Mechanics.MultiBody.Types.Axis e_theta "Normalized vector in azimuth direction on the sphere"; From f4a7697a360172143265a160954d7866e892a2cf Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Thu, 13 Apr 2023 15:57:59 +0200 Subject: [PATCH 08/11] Remove External call of empty C-Function --- Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo b/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo index 71552501..075bf926 100644 --- a/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo +++ b/Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo @@ -21,8 +21,6 @@ encapsulated function destructor "Close channel" extends Modelica.Icons.Function; import Modelica_DeviceDrivers.HardwareIO.IIOchannel; input IIOchannel channel "Channel context"; - external "C" MDD_iio_close_channel(channel) - annotation (Include="#include \"MDDIIO.h\"", Library="libiio"); end destructor; end IIOchannel; From 0663e4c1ef5127f5a246c03cefddb3871f90dc9a Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Thu, 13 Apr 2023 15:58:15 +0200 Subject: [PATCH 09/11] Various C-code fixes --- .../Resources/Include/MDDIIO.h | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h index 1a0348c8..c5c1c8bf 100644 --- a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h +++ b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h @@ -1,8 +1,8 @@ -/** Linux Comedi DAQ support (header-only library). +/** Linux Internet-I/O support (header-only library). * * @file - * @author bernhard-thiele - * @since 2012-06-26 + * @author m-kormann + * @since 2023-04-13 * @copyright see accompanying file LICENSE_Modelica_DeviceDrivers.txt */ @@ -20,18 +20,12 @@ } \ } -// Streaming devices - -static struct iio_buffer *rxbuf; -static struct iio_channel **channels; -static unsigned int channel_count; - void* MDD_iio_open(const char* targetname) { - static struct iio_context *ctx; - if(strlen(targetname) > 0) { + struct iio_context *ctx = NULL; + if (targetname[0] != '\0') { IIO_ENSURE(ctx = iio_create_network_context(targetname), "Could not open IIO host", targetname); } - else { + else { IIO_ENSURE(ctx = iio_create_local_context(), "Could not open IIO host", "locally"); } IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname); @@ -42,7 +36,7 @@ void* MDD_iio_open(const char* targetname) { void MDD_iio_close(void* p_ctx) { static struct iio_context *ctx; ctx = (struct iio_context *) p_ctx; - if (ctx) { + if (ctx) { iio_context_destroy(ctx); } } @@ -60,12 +54,8 @@ void* MDD_iio_open_channel(void *p_ctx, const char* devicename, const char* chan return (void *) chn; } -void MDD_iio_close_channel (void* p_chn) { -} - double MDD_iio_data_read(void* p_chn, const char* attrname) { - struct iio_channel *chn; - chn = (struct iio_channel *) p_chn; + struct iio_channel *chn = (struct iio_channel *) p_chn; double val = 0; From f7acc27190e4922a7891240379dd5145cb122080 Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Thu, 13 Apr 2023 15:59:33 +0200 Subject: [PATCH 10/11] Change identation from tab to four spaces --- .../Resources/Include/MDDIIO.h | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h index c5c1c8bf..fe41add3 100644 --- a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h +++ b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h @@ -15,52 +15,52 @@ #include "ModelicaUtilities.h" #define IIO_ENSURE(expr, message, context) { \ - if (!(expr)) { \ - (void) ModelicaFormatError("%s %s (%s:%d)\n", message, context, __FILE__, __LINE__); \ - } \ + if (!(expr)) { \ + (void) ModelicaFormatError("%s %s (%s:%d)\n", message, context, __FILE__, __LINE__); \ + } \ } void* MDD_iio_open(const char* targetname) { - struct iio_context *ctx = NULL; - if (targetname[0] != '\0') { - IIO_ENSURE(ctx = iio_create_network_context(targetname), "Could not open IIO host", targetname); - } - else { - IIO_ENSURE(ctx = iio_create_local_context(), "Could not open IIO host", "locally"); - } - IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname); + struct iio_context *ctx = NULL; + if (targetname[0] != '\0') { + IIO_ENSURE(ctx = iio_create_network_context(targetname), "Could not open IIO host", targetname); + } + else { + IIO_ENSURE(ctx = iio_create_local_context(), "Could not open IIO host", "locally"); + } + IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname); return (void*) ctx; } void MDD_iio_close(void* p_ctx) { - static struct iio_context *ctx; - ctx = (struct iio_context *) p_ctx; - if (ctx) { - iio_context_destroy(ctx); - } + static struct iio_context *ctx; + ctx = (struct iio_context *) p_ctx; + if (ctx) { + iio_context_destroy(ctx); + } } void* MDD_iio_open_channel(void *p_ctx, const char* devicename, const char* channelname) { - static struct iio_context *ctx; - ctx = (struct iio_context *) p_ctx; + static struct iio_context *ctx; + ctx = (struct iio_context *) p_ctx; - static struct iio_device *dev; - IIO_ENSURE(dev = iio_context_find_device(ctx, devicename), "Device not found: ", devicename); + static struct iio_device *dev; + IIO_ENSURE(dev = iio_context_find_device(ctx, devicename), "Device not found: ", devicename); - struct iio_channel *chn; - IIO_ENSURE(chn = iio_device_find_channel(dev, channelname, false), "Channel not found: ", channelname); + struct iio_channel *chn; + IIO_ENSURE(chn = iio_device_find_channel(dev, channelname, false), "Channel not found: ", channelname); - return (void *) chn; + return (void *) chn; } double MDD_iio_data_read(void* p_chn, const char* attrname) { - struct iio_channel *chn = (struct iio_channel *) p_chn; + struct iio_channel *chn = (struct iio_channel *) p_chn; - double val = 0; + double val = 0; - int ret = iio_channel_attr_read_double(chn, attrname, &val); - IIO_ENSURE(ret == 0, "Attribute not found: ", attrname); + int ret = iio_channel_attr_read_double(chn, attrname, &val); + IIO_ENSURE(ret == 0, "Attribute not found: ", attrname); return val; } From 313d973676a95b6fa8dfea09c1b738fc9b39fb7c Mon Sep 17 00:00:00 2001 From: Maximilian Kormann Date: Fri, 14 Apr 2023 10:48:07 +0200 Subject: [PATCH 11/11] Remove some statics --- Modelica_DeviceDrivers/Resources/Include/MDDIIO.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h index fe41add3..fe374276 100644 --- a/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h +++ b/Modelica_DeviceDrivers/Resources/Include/MDDIIO.h @@ -34,18 +34,16 @@ void* MDD_iio_open(const char* targetname) { } void MDD_iio_close(void* p_ctx) { - static struct iio_context *ctx; - ctx = (struct iio_context *) p_ctx; + struct iio_context *ctx = (struct iio_context *) p_ctx; if (ctx) { iio_context_destroy(ctx); } } void* MDD_iio_open_channel(void *p_ctx, const char* devicename, const char* channelname) { - static struct iio_context *ctx; - ctx = (struct iio_context *) p_ctx; + struct iio_context *ctx = (struct iio_context *) p_ctx; - static struct iio_device *dev; + struct iio_device *dev; IIO_ENSURE(dev = iio_context_find_device(ctx, devicename), "Device not found: ", devicename); struct iio_channel *chn;