diff --git a/bindings/csharp/Attr.cs b/bindings/csharp/Attr.cs index dd5994af0..267f43312 100644 --- a/bindings/csharp/Attr.cs +++ b/bindings/csharp/Attr.cs @@ -10,35 +10,69 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace iio { /// class: - /// Contains the representation of a channel or device attribute. - public abstract class Attr + /// Contains the representation of an iio_attr. + public class Attr { + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_attr_read_raw(IntPtr attr, + [Out()] StringBuilder dst, uint len); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_attr_write_raw(IntPtr attr, IntPtr src, + uint len); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_attr_get_name(IntPtr attr); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_attr_get_filename(IntPtr attr); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_attr_get_static_value(IntPtr attr); + + internal IntPtr attr; + /// The name of this attribute. public readonly string name; /// The filename in sysfs to which this attribute is bound. public readonly string filename; - internal Attr(string name, string filename = null) + internal Attr(IntPtr attr) { - this.filename = filename == null ? name : filename; - this.name = name; + this.attr = attr; + this.name = Marshal.PtrToStringAnsi(iio_attr_get_name(attr)); + this.filename = Marshal.PtrToStringAnsi(iio_attr_get_filename(attr)); } /// Read the value of this attribute as a string. /// The attribute could not be read. - public abstract string read(); + public string read() + { + StringBuilder builder = new StringBuilder(1024); + int err = iio_attr_read_raw(attr, builder, (uint)builder.Capacity); + if (err < 0) + throw new IIOException("Unable to read attribute", err); + return builder.ToString(); + } /// Set this attribute to the value contained in the string argument. /// The string value to set the parameter to. /// The attribute could not be written. - public abstract void write(string val); + public void write(string val) + { + IntPtr valptr = Marshal.StringToHGlobalAnsi(val); + int err = iio_attr_write_raw(attr, valptr, (uint)val.Length); + if (err < 0) + throw new IIOException("Unable to write attribute", err); + } /// Read the value of this attribute as a bool. /// The attribute could not be read. diff --git a/bindings/csharp/Block.cs b/bindings/csharp/Block.cs index 769ebe272..50783876f 100644 --- a/bindings/csharp/Block.cs +++ b/bindings/csharp/Block.cs @@ -66,7 +66,9 @@ public Block(IOBuffer buf, uint size) protected override void Destroy() { - iio_block_destroy(hdl); + if (!stream_block) { + iio_block_destroy(hdl); + } } public int enqueue(uint bytes_used = 0, bool cyclic = false) diff --git a/bindings/csharp/CMakeLists.txt b/bindings/csharp/CMakeLists.txt index a281051ca..ddc23cba1 100644 --- a/bindings/csharp/CMakeLists.txt +++ b/bindings/csharp/CMakeLists.txt @@ -43,7 +43,9 @@ if (MCS_EXECUTABLE) ${CMAKE_CURRENT_SOURCE_DIR}/ChannelsMask.cs ${CMAKE_CURRENT_SOURCE_DIR}/Context.cs ${CMAKE_CURRENT_SOURCE_DIR}/Device.cs + ${CMAKE_CURRENT_SOURCE_DIR}/EventStream.cs ${CMAKE_CURRENT_SOURCE_DIR}/IOBuffer.cs + ${CMAKE_CURRENT_SOURCE_DIR}/IIOEvent.cs ${CMAKE_CURRENT_SOURCE_DIR}/Trigger.cs ${CMAKE_CURRENT_SOURCE_DIR}/IioLib.cs ${CMAKE_CURRENT_SOURCE_DIR}/Scan.cs diff --git a/bindings/csharp/Channel.cs b/bindings/csharp/Channel.cs index 56510b9ad..cdc37ec3a 100644 --- a/bindings/csharp/Channel.cs +++ b/bindings/csharp/Channel.cs @@ -20,42 +20,6 @@ namespace iio /// Contains the representation of an input or output channel. public class Channel { - private class ChannelAttr : Attr - { - private IntPtr chn; - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_channel_attr_read_raw(IntPtr chn, [In()] string name, [Out()] StringBuilder val, uint len); - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_channel_attr_write_string(IntPtr chn, [In()] string name, string val); - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr iio_channel_attr_get_filename(IntPtr chn, [In()] string attr); - - public ChannelAttr(IntPtr chn, string name) : base(name, Marshal.PtrToStringAnsi(iio_channel_attr_get_filename(chn, name))) - { - this.chn = chn; - } - - public override string read() - { - StringBuilder builder = new StringBuilder(1024); - int err = iio_channel_attr_read_raw(chn, name, builder, (uint) builder.Capacity); - if (err < 0) - throw new IIOException("Unable to read channel attribute", err); - - return builder.ToString(); - } - - public override void write(string str) - { - int err = iio_channel_attr_write_string(chn, name, str); - if (err < 0) - throw new IIOException("Unable to write channel attribute", err); - } - } - /// class: /// Contains the available channel modifiers. public enum ChannelModifier @@ -104,7 +68,15 @@ public enum ChannelModifier IIO_MOD_PM10, IIO_MOD_ETHANOL, IIO_MOD_H2, - IIO_MOD_O2 + IIO_MOD_O2, + IIO_MOD_LINEAR_X, + IIO_MOD_LINEAR_Y, + IIO_MOD_LINEAR_Z, + IIO_MOD_PITCH, + IIO_MOD_YAW, + IIO_MOD_ROLL, + IIO_MOD_LIGHT_UVA, + IIO_MOD_LIGHT_UVB } /// class: @@ -146,6 +118,10 @@ public enum ChannelType IIO_POSITIONRELATIVE, IIO_PHASE, IIO_MASSCONCENTRATION, + IIO_DELTA_ANGL, + IIO_DELTA_VELOCITY, + IIO_COLORTEMP, + IIO_CHROMATICITY, IIO_CHAN_TYPE_UNKNOWN = Int32.MaxValue } @@ -177,6 +153,9 @@ public struct DataFormat /// Number of times length repeats public uint repeat; + + /// Contains a value to be added to the raw sample before applying the scale. + public double offset; } internal IntPtr chn; @@ -281,7 +260,7 @@ internal Channel(Device dev, IntPtr chn) for (uint i = 0; i < nb_attrs; i++) { - attrs.Add(new ChannelAttr(this.chn, Marshal.PtrToStringAnsi(iio_channel_get_attr(chn, i)))); + attrs.Add(new Attr(iio_channel_get_attr(chn, i))); } IntPtr name_ptr = iio_channel_get_name(this.chn); diff --git a/bindings/csharp/Context.cs b/bindings/csharp/Context.cs index b0fbf3c1e..2baa2c128 100644 --- a/bindings/csharp/Context.cs +++ b/bindings/csharp/Context.cs @@ -91,7 +91,7 @@ private static extern IIOPtr iio_create_context(IntPtr ctx_params, private static extern uint iio_context_get_attrs_count(IntPtr ctx); [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_context_get_attr(IntPtr ctx, uint index, out IntPtr name_ptr, out IntPtr value_ptr); + private static extern IntPtr iio_context_get_attr(IntPtr ctx, uint index); /// A XML representation of the current context. public readonly string xml; @@ -153,14 +153,8 @@ private Context(IIOPtr ptr) for (uint i = 0; i < nbAttrs; i++) { - IntPtr name_ptr; - IntPtr value_ptr; - - iio_context_get_attr(hdl, i, out name_ptr, out value_ptr); - string attr_name = Marshal.PtrToStringAnsi(name_ptr); - string attr_value = Marshal.PtrToStringAnsi(value_ptr); - - attrs[attr_name] = attr_value; + Attr attr = new Attr(iio_context_get_attr(hdl, i)); + attrs[attr.name] = attr.read(); } } diff --git a/bindings/csharp/Device.cs b/bindings/csharp/Device.cs index ea27a8822..95499e0a3 100644 --- a/bindings/csharp/Device.cs +++ b/bindings/csharp/Device.cs @@ -19,105 +19,6 @@ namespace iio /// Contains the representation of an IIO device. public class Device { - private class DeviceAttr : Attr - { - internal IntPtr dev; - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_attr_read(IntPtr dev, [In()] string name, [Out()] StringBuilder val, uint len); - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_attr_write(IntPtr dev, [In()] string name, [In()] string val); - - public DeviceAttr(IntPtr dev, string name) : base(name) - { - this.dev = dev; - } - - public override string read() - { - StringBuilder builder = new StringBuilder(1024); - int err = iio_device_attr_read(dev, name, builder, 1024); - if (err < 0) - throw new IIOException("Unable to read device attribute", err); - - return builder.ToString(); - } - - public override void write(string str) - { - int err = iio_device_attr_write(dev, name, str); - if (err < 0) - throw new IIOException("Unable to write device attribute", err); - } - } - - private class DeviceDebugAttr : Attr - { - private IntPtr dev; - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_debug_attr_read(IntPtr dev, [In()] string name, [Out()] StringBuilder val, uint len); - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_debug_attr_write(IntPtr dev, [In()] string name, [In()] string val); - - public DeviceDebugAttr(IntPtr dev, string name) : base(name) - { - this.dev = dev; - } - - public override string read() - { - StringBuilder builder = new StringBuilder(1024); - int err = iio_device_debug_attr_read(dev, name, builder, 1024); - if (err < 0) - throw new IIOException("Unable to read debug attribute", err); - - return builder.ToString(); - } - - public override void write(string str) - { - int err = iio_device_debug_attr_write(dev, name, str); - if (err < 0) - throw new IIOException("Unable to write debug attribute", err); - } - } - - private class DeviceBufferAttr : Attr - { - private IntPtr dev; - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_buffer_attr_read(IntPtr dev, [In] string name, [Out] StringBuilder val, uint len); - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_buffer_attr_write(IntPtr dev, [In] string name, [In] string val); - - public DeviceBufferAttr(IntPtr dev, string name) : base(name) - { - this.dev = dev; - } - - public override string read() - { - StringBuilder builder = new StringBuilder(16384); - int err = iio_device_buffer_attr_read(dev, name, builder, 16384); - if (err < 0) - throw new IIOException("Unable to read buffer attribute", err); - - return builder.ToString(); - } - - public override void write(string str) - { - int err = iio_device_buffer_attr_write(dev, name, str); - if (err < 0) - throw new IIOException("Unable to write buffer attribute", err); - } - } - /// Gets the context of the current device. public readonly Context ctx; @@ -142,9 +43,6 @@ public override void write(string str) [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] private static extern uint iio_device_get_debug_attrs_count(IntPtr dev); - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern uint iio_device_get_buffer_attrs_count(IntPtr dev); - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] private static extern IntPtr iio_device_get_attr(IntPtr dev, uint index); @@ -152,10 +50,7 @@ public override void write(string str) private static extern IntPtr iio_device_get_debug_attr(IntPtr dev, uint index); [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr iio_device_get_buffer_attr(IntPtr dev, uint index); - - [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern int iio_device_get_trigger(IntPtr dev, IntPtr triggerptr); + private static extern IIOPtr iio_device_get_trigger(IntPtr dev); [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] private static extern int iio_device_set_trigger(IntPtr dev, IntPtr trigger); @@ -190,9 +85,6 @@ public override void write(string str) /// A list of all the debug attributes that this device has. public readonly List debug_attrs; - /// A list of all the buffer attributes that this device has. - public List buffer_attrs { get; private set; } - /// A list of all the objects that this device possesses. public readonly List channels; @@ -203,12 +95,10 @@ internal Device(Context ctx, IntPtr dev) channels = new List(); attrs = new List(); debug_attrs = new List(); - buffer_attrs = new List(); uint nb_channels = iio_device_get_channels_count(dev); uint nb_attrs = iio_device_get_attrs_count(dev); uint nb_debug_attrs = iio_device_get_debug_attrs_count(dev); - uint nb_buffer_attrs = iio_device_get_buffer_attrs_count(dev); for (uint i = 0; i < nb_channels; i++) { @@ -217,17 +107,12 @@ internal Device(Context ctx, IntPtr dev) for (uint i = 0; i < nb_attrs; i++) { - attrs.Add(new DeviceAttr(dev, Marshal.PtrToStringAnsi(iio_device_get_attr(dev, i)))); + attrs.Add(new Attr(iio_device_get_attr(dev, i))); } for (uint i = 0; i < nb_debug_attrs; i++) { - debug_attrs.Add(new DeviceDebugAttr(dev, Marshal.PtrToStringAnsi(iio_device_get_debug_attr(dev, i)))); - } - - for (uint i = 0; i < nb_buffer_attrs; i++) - { - buffer_attrs.Add(new DeviceBufferAttr(dev, Marshal.PtrToStringAnsi(iio_device_get_buffer_attr(dev, i)))); + debug_attrs.Add(new Attr(iio_device_get_debug_attr(dev, i))); } id = Marshal.PtrToStringAnsi(iio_device_get_id(dev)); @@ -282,16 +167,13 @@ public void set_trigger(Trigger trig) /// The instance could not be retrieved. public Trigger get_trigger() { - IntPtr ptr = IntPtr.Zero; - int err = iio_device_get_trigger(this.dev, ptr); - if (err < 0) - throw new IIOException("Unable to get trigger", err); - - ptr = Marshal.ReadIntPtr(ptr); + IIOPtr ptr = iio_device_get_trigger(this.dev); + if (!ptr) + throw new IIOException("Unable to get trigger", ptr); foreach (Trigger trig in ctx.devices) { - if (trig.dev == ptr) + if (trig.dev == ptr.ptr) { return trig; } diff --git a/bindings/csharp/EventStream.cs b/bindings/csharp/EventStream.cs new file mode 100644 index 000000000..f2c63e16f --- /dev/null +++ b/bindings/csharp/EventStream.cs @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2024 Analog Devices, Inc. + * Author: Alexandra Trifan + */ + +using System; +using System.Runtime.InteropServices; + +namespace iio +{ + /// class: + /// Contains the representation of an event stream. + public class EventStream : IIOObject + { + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern IIOPtr iio_device_create_event_stream(IntPtr dev); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern void iio_event_stream_destroy(IntPtr stream); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_event_stream_read(IntPtr stream, IntPtr ev, + [MarshalAs(UnmanagedType.I1)] bool nonblock); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_event_get_channel(IntPtr ev, IntPtr dev, + [MarshalAs(UnmanagedType.I1)] bool diff); + + public readonly Device dev; + + public EventStream(Device device) + { + IIOPtr ptr = iio_device_create_event_stream(device.dev); + if (!ptr) + throw new IIOException("Unable to create iio.EventStream", ptr); + + this.hdl = ptr.ptr; + this.dev = device; + } + + /// Read an event from the event stream. + /// if True, the operation won't block and return -EBUSY if + /// there is currently no event in the queue. + /// It is possible to stop a blocking call of read_event + /// by calling Destroy in a different thread. + /// In that case, read_event will throw an exception. + /// Unable to read event. + public IIOEvent read_event(bool nonblock) + { + IIOEventPtr iioeventptr; + iioeventptr.id = 0; + iioeventptr.timestamp = 0; + IntPtr eventptr = Marshal.AllocHGlobal(Marshal.SizeOf(iioeventptr)); + + int ret = iio_event_stream_read(hdl, eventptr, nonblock); + if (ret < 0) + throw new IIOException("Unable to read event", ret); + + IntPtr chnptr = iio_event_get_channel(eventptr, dev.dev, false); + Channel chn = new Channel(dev, chnptr); + IntPtr diffchnptr = iio_event_get_channel(eventptr, dev.dev, true); + if (diffchnptr != IntPtr.Zero) + { + Channel chndiff = new Channel(dev, diffchnptr); + return new IIOEvent(eventptr, chn, chndiff); + } + return new IIOEvent(eventptr, chn); + } + + protected override void Destroy() + { + iio_event_stream_destroy(hdl); + } + } +} diff --git a/bindings/csharp/IIOEvent.cs b/bindings/csharp/IIOEvent.cs new file mode 100644 index 000000000..2f213b412 --- /dev/null +++ b/bindings/csharp/IIOEvent.cs @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2024 Analog Devices, Inc. + * Author: Alexandra Trifan + */ + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace iio +{ + [StructLayout(LayoutKind.Sequential)] + public struct IIOEventPtr + { + public ulong id; + public long timestamp; + } + + /// class: + /// Contains the representation of an iio_event. + public class IIOEvent + { + /// class: + /// Contains the available event types. + public enum EventType + { + 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, + IIO_EV_TYPE_MAG_REFERENCED, + IIO_EV_TYPE_GESTURE + } + + /// class: + /// Contains the available event directions. + public enum EventDirection + { + IIO_EV_DIR_EITHER, + IIO_EV_DIR_RISING, + IIO_EV_DIR_FALLING, + IIO_EV_DIR_NONE, + IIO_EV_DIR_SINGLETAP, + IIO_EV_DIR_DOUBLETAP + } + + internal IntPtr ev; + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_event_get_type(IntPtr ev); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_event_get_direction(IntPtr ev); + + internal IIOEventPtr event_ptr; + public readonly Channel chn; + public readonly Channel chn_diff; + public readonly ulong id; + public readonly long timestamp; + + /// The type of this event. + public EventType type { get; private set; } + + /// Represents the direction of the event. + public EventDirection direction { get; private set; } + + internal IIOEvent(IntPtr ev, Channel chn, Channel chndiff = null) + { + this.ev = ev; + event_ptr = (IIOEventPtr) Marshal.PtrToStructure(ev, typeof(IIOEventPtr)); + this.id = event_ptr.id; + this.timestamp = event_ptr.timestamp; + this.chn = chn; + this.chn_diff = chndiff; + this.type = (EventType) ((this.id >> 56) & 0xff); + this.direction = (EventDirection) ((this.id >> 48) & 0x7f); + } + } +} diff --git a/bindings/csharp/IOBuffer.cs b/bindings/csharp/IOBuffer.cs index 631dab530..298828f7c 100644 --- a/bindings/csharp/IOBuffer.cs +++ b/bindings/csharp/IOBuffer.cs @@ -36,6 +36,12 @@ public class IOBuffer : IIOObject [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] private static extern int iio_buffer_disable(IntPtr buf); + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern uint iio_buffer_get_attrs_count(IntPtr buf); + + [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_buffer_get_attr(IntPtr buf, uint index); + internal ChannelsMask mask; /// The size of this buffer, in samples. @@ -44,6 +50,9 @@ public class IOBuffer : IIOObject /// The associated object. public readonly Device dev; + /// A list of all the attributes that this buffer has. + public readonly List attrs; + private bool is_enabled; public bool enabled { @@ -77,6 +86,13 @@ public IOBuffer(Device dev, ChannelsMask mask, uint index = 0) this.hdl = ptr.ptr; this.is_enabled = false; + + attrs = new List(); + uint nb_buffer_attrs = iio_buffer_get_attrs_count(hdl); + for (uint i = 0; i < nb_buffer_attrs; i++) + { + attrs.Add(new Attr(iio_buffer_get_attr(hdl, i))); + } } protected override void Destroy() diff --git a/bindings/csharp/IioLib.cs b/bindings/csharp/IioLib.cs index d8c3a4ea2..ed769795b 100644 --- a/bindings/csharp/IioLib.cs +++ b/bindings/csharp/IioLib.cs @@ -13,33 +13,37 @@ namespace iio { - public class IIOPtr + public struct IIOPtr { public readonly IntPtr ptr; - public readonly int error; public IIOPtr(IntPtr ptr) { this.ptr = ptr; + } + public int computeError() + { + int error; if (IntPtr.Size == 4) { - this.error = (uint) ptr >= unchecked((uint) -4095) ? (int) ptr : 0; + error = (uint) ptr >= unchecked((uint) -4095) ? (int) ptr : 0; } else { - this.error = (ulong) ptr >= unchecked((ulong) -4095L) ? (int)(long) ptr : 0; + error = (ulong) ptr >= unchecked((ulong) -4095L) ? (int)(long) ptr : 0; } + return error; } /// Get a string representation of the error. public string str() { + int error = computeError(); return IioLib.strerror(error); } - ~IIOPtr() {} - public static bool operator !(IIOPtr r) { - return r.error > 0; + int error = r.computeError(); + return error > 0; } } diff --git a/bindings/csharp/Stream.cs b/bindings/csharp/Stream.cs index 9cd79e05b..70d86901a 100644 --- a/bindings/csharp/Stream.cs +++ b/bindings/csharp/Stream.cs @@ -18,10 +18,10 @@ private static extern IIOPtr iio_buffer_create_stream(IntPtr buf, uint nb_blocks, uint samples_count); [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern void iio_stream_destroy(IntPtr buf); + private static extern void iio_stream_destroy(IntPtr stream); [DllImport(IioLib.dllname, CallingConvention = CallingConvention.Cdecl)] - private static extern IIOPtr iio_stream_get_next_block(IntPtr buf); + private static extern IIOPtr iio_stream_get_next_block(IntPtr stream); public readonly IOBuffer buf; public readonly uint nb_blocks; diff --git a/bindings/csharp/examples/ExampleIIOEvent.cs b/bindings/csharp/examples/ExampleIIOEvent.cs new file mode 100644 index 000000000..1c3a6073d --- /dev/null +++ b/bindings/csharp/examples/ExampleIIOEvent.cs @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2024 Analog Devices, Inc. + * Author: Alexandra Trifan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using iio; + +namespace IIOCSharp +{ + class ExampleIIOEvent + { + static void Main(string[] args) + { + Scan scan = new Scan(); + if (scan.nb_results > 0) { + Console.WriteLine("* Scanned contexts: " + scan.nb_results); + } + foreach (var entry in scan.results) { + Console.WriteLine("\t" + entry.Key + " " + entry.Value); + } + scan.Dispose(); + + if (args.Length <= 1) + { + Console.WriteLine("Please provide the context URI and IIO device.\n"); + return; + } + + string uri = args[0]; + string ev_device = args[1]; + Context ctx; + try + { + ctx = new Context(uri); + } catch (IIOException e) + { + Console.WriteLine(e.ToString()); + return; + } + + Console.WriteLine("* IIO context created: " + ctx.name); + Console.WriteLine("* IIO context description: " + ctx.description); + + Console.WriteLine("* IIO context has " + ctx.devices.Count + " devices:"); + foreach (Device dev in ctx.devices) { + Console.WriteLine("\t" + dev.id + ": " + dev.name); + if (dev.name == ev_device) + { + EventStream event_stream = new EventStream(dev); + while (true) + { + try + { + IIOEvent ev = event_stream.read_event(false); + string timestamp = ev.timestamp.ToString(); + string print_ev = "Event: time: " + timestamp; + if (ev.chn != null) + { + print_ev += ", channel(s): " + ev.chn.id.ToString(); + } + if (ev.chn_diff != null) + { + print_ev += " - " + ev.chn_diff.id; + } + print_ev += ", evtype: " + ev.type; + print_ev += ", direction: " + ev.direction; + Console.WriteLine(print_ev); + } + catch (IIOException e) + { + Console.WriteLine("Error: " + e.ToString()); + event_stream.Dispose(); + return; + } + } + event_stream.Dispose(); + } + } + } + } +} diff --git a/bindings/csharp/examples/ExampleProgram.cs b/bindings/csharp/examples/ExampleProgram.cs index 95c711681..d86740aa5 100644 --- a/bindings/csharp/examples/ExampleProgram.cs +++ b/bindings/csharp/examples/ExampleProgram.cs @@ -30,23 +30,36 @@ class ExampleProgram { static void Main(string[] args) { - Context ctx = new Context("10.44.2.241"); - if (ctx == null) + uint blocksize = 1024; + Scan scan = new Scan(); + if (scan.nb_results > 0) { + Console.WriteLine("* Scanned contexts: " + scan.nb_results); + } + foreach (var entry in scan.results) { + Console.WriteLine("\t" + entry.Key + " " + entry.Value); + } + scan.Dispose(); + + Context ctx; + try + { + ctx = new Context("ip:192.168.2.1"); + } catch (IIOException e) { - Console.WriteLine("Unable to create IIO context"); + Console.WriteLine(e.ToString()); return; } - Console.WriteLine("IIO context created: " + ctx.name); - Console.WriteLine("IIO context description: " + ctx.description); + Console.WriteLine("* IIO context created: " + ctx.name); + Console.WriteLine("* IIO context description: " + ctx.description); - Console.WriteLine("IIO context has " + ctx.devices.Count + " devices:"); + Console.WriteLine("* IIO context has " + ctx.devices.Count + " devices:"); foreach (Device dev in ctx.devices) { Console.WriteLine("\t" + dev.id + ": " + dev.name); if (dev is Trigger) { - Console.WriteLine("Found trigger! Rate=" + ((Trigger) dev).get_rate()); + Console.WriteLine("* Found trigger! Rate=" + ((Trigger) dev).get_rate()); } Console.WriteLine("\t\t" + dev.channels.Count + " channels found:"); @@ -68,25 +81,58 @@ static void Main(string[] args) Console.WriteLine("\t\t\t" + chn.attrs.Count + " channel-specific attributes found:"); foreach (Attr attr in chn.attrs) { - Console.WriteLine("\t\t\t\t" + attr.name); - if (attr.name.CompareTo("frequency") == 0) + string attr_name = "\t\t\t\t" + attr.name; + string attr_val = ""; + try { - Console.WriteLine("Attribute content: " + attr.read()); + if (attr.name == "calibscale") + { + double val = attr.read_double(); + Console.WriteLine(attr_name + " " + val); + } + else + { + attr_val = attr.read(); + Console.WriteLine(attr_name + " " + attr_val); + } + } + catch (IIOException) + { + Console.WriteLine(attr_name); } } - } /* If we find cf-ad9361-lpc, try to read a few bytes from the first channel */ if (dev.name.CompareTo("cf-ad9361-lpc") == 0) { - Channel chn = dev.channels[0]; - chn.enable(); - IOBuffer buf = new IOBuffer(dev, 0x8000); - buf.refill(); - - Console.WriteLine("Read " + chn.read(buf).Length + " bytes from hardware"); + ChannelsMask chnmask = new ChannelsMask((uint)dev.channels.Count); + Channel rx0_i = dev.channels[0]; + rx0_i.enable(chnmask); + Channel rx0_q = dev.channels[1]; + rx0_q.enable(chnmask); + + IOBuffer buf = new IOBuffer(dev, chnmask); + uint sampleSize = dev.get_sample_size(chnmask); + Console.WriteLine("* Sample size is " + sampleSize + "\n"); + + Console.WriteLine("\t\t\t" + buf.attrs.Count + " buffer-specific attributes found:"); + foreach (Attr attr in buf.attrs) + { + Console.WriteLine("\t\t\t\t" + attr.name + " " + attr.read()); + } + + Stream stream = new Stream(buf, 4, blocksize); + for (int i=0; i < 10; i++) { + Block block = stream.next(); + byte[] databuf = new byte[blocksize]; + block.read(databuf); + Console.WriteLine("* ("+ i + ") Read " + databuf.Length + " bytes from hardware"); + } + + stream.Dispose(); buf.Dispose(); + chnmask.Dispose(); } if (dev.attrs.Count == 0) @@ -94,16 +140,13 @@ static void Main(string[] args) continue; } - Console.WriteLine("\t\t" + dev.attrs.Count + " device-specific attributes found:"); + Console.WriteLine("\n\t\t" + dev.attrs.Count + " device-specific attributes found:"); foreach (Attr attr in dev.attrs) { Console.WriteLine("\t\t\t" + attr.name); } } - - /* Wait for user input */ - Console.ReadLine(); } } }