1 /* 2 * libiio - Library for interfacing industrial I/O (IIO) devices 3 * 4 * Copyright (C) 2015 Analog Devices, Inc. 5 * Author: Paul Cercueil <paul.cercueil@analog.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * */ 18 19 using System; 20 using System.Collections.Generic; 21 using System.Linq; 22 using System.Runtime.InteropServices; 23 using System.Text; 24 using System.Threading.Tasks; 25 26 namespace iio 27 { 28 /// <summary><see cref="iio.Device"/> class: 29 /// Contains the representation of an IIO device.</summary> 30 public class Device 31 { 32 private class DeviceAttr : Attr 33 { 34 private IntPtr dev; 35 36 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_attr_read(IntPtr dev, [In()] string name, [Out()] StringBuilder val, uint len)37 private static extern int iio_device_attr_read(IntPtr dev, [In()] string name, [Out()] StringBuilder val, uint len); 38 39 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_attr_write(IntPtr dev, [In()] string name, [In()] string val)40 private static extern int iio_device_attr_write(IntPtr dev, [In()] string name, [In()] string val); 41 DeviceAttr(IntPtr dev, string name)42 public DeviceAttr(IntPtr dev, string name) : base(name) 43 { 44 this.dev = dev; 45 } 46 read()47 public override string read() 48 { 49 StringBuilder builder = new StringBuilder(1024); 50 int err = iio_device_attr_read(dev, name, builder, 1024); 51 if (err < 0) 52 throw new Exception("Unable to read device attribute " + err); 53 return builder.ToString(); 54 } 55 write(string str)56 public override void write(string str) 57 { 58 int err = iio_device_attr_write(dev, name, str); 59 if (err < 0) 60 throw new Exception("Unable to write device attribute " + err); 61 } 62 } 63 64 private class DeviceDebugAttr : Attr 65 { 66 private IntPtr dev; 67 68 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_debug_attr_read(IntPtr dev, [In()] string name, [Out()] StringBuilder val, uint len)69 private static extern int iio_device_debug_attr_read(IntPtr dev, [In()] string name, [Out()] StringBuilder val, uint len); 70 71 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_debug_attr_write(IntPtr dev, [In()] string name, [In()] string val)72 private static extern int iio_device_debug_attr_write(IntPtr dev, [In()] string name, [In()] string val); 73 DeviceDebugAttr(IntPtr dev, string name)74 public DeviceDebugAttr(IntPtr dev, string name) : base(name) 75 { 76 this.dev = dev; 77 } 78 read()79 public override string read() 80 { 81 StringBuilder builder = new StringBuilder(1024); 82 int err = iio_device_debug_attr_read(dev, name, builder, 1024); 83 if (err < 0) 84 throw new Exception("Unable to read debug attribute " + err); 85 return builder.ToString(); 86 } 87 write(string str)88 public override void write(string str) 89 { 90 int err = iio_device_debug_attr_write(dev, name, str); 91 if (err < 0) 92 throw new Exception("Unable to write debug attribute " + err); 93 } 94 } 95 96 private Context ctx; 97 98 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_id(IntPtr dev)99 private static extern IntPtr iio_device_get_id(IntPtr dev); 100 101 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_name(IntPtr dev)102 private static extern IntPtr iio_device_get_name(IntPtr dev); 103 104 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_channels_count(IntPtr dev)105 private static extern uint iio_device_get_channels_count(IntPtr dev); 106 107 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_channel(IntPtr dev, uint index)108 private static extern IntPtr iio_device_get_channel(IntPtr dev, uint index); 109 110 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_attrs_count(IntPtr dev)111 private static extern uint iio_device_get_attrs_count(IntPtr dev); 112 113 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_debug_attrs_count(IntPtr dev)114 private static extern uint iio_device_get_debug_attrs_count(IntPtr dev); 115 116 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_attr(IntPtr dev, uint index)117 private static extern IntPtr iio_device_get_attr(IntPtr dev, uint index); 118 119 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_debug_attr(IntPtr dev, uint index)120 private static extern IntPtr iio_device_get_debug_attr(IntPtr dev, uint index); 121 122 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_trigger(IntPtr dev, IntPtr triggerptr)123 private static extern int iio_device_get_trigger(IntPtr dev, IntPtr triggerptr); 124 125 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_set_trigger(IntPtr dev, IntPtr trigger)126 private static extern int iio_device_set_trigger(IntPtr dev, IntPtr trigger); 127 128 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_get_sample_size(IntPtr dev)129 private static extern int iio_device_get_sample_size(IntPtr dev); 130 131 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_reg_write(IntPtr dev, uint addr, uint value)132 private static extern int iio_device_reg_write(IntPtr dev, uint addr, uint value); 133 134 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_reg_read(IntPtr dev, uint addr, ref uint value)135 private static extern int iio_device_reg_read(IntPtr dev, uint addr, ref uint value); 136 137 internal IntPtr dev; 138 139 /// <summary>An identifier of this device.</summary> 140 /// <remarks>The identifier is only valid in this IIO context</remarks> 141 public readonly string id; 142 143 /// <summary>The name of this device.</summary> 144 public readonly string name; 145 146 /// <summary>A <c>list</c> of all the attributes that this device has.</summary> 147 public readonly List<Attr> attrs; 148 149 /// <summary>A <c>list</c> of all the debug attributes that this device has.</summary> 150 public readonly List<Attr> debug_attrs; 151 152 /// <summary>A <c>list</c> of all the <see cref="iio.Channel"/> objects that this device possesses.</summary> 153 public readonly List<Channel> channels; 154 Device(Context ctx, IntPtr dev)155 internal Device(Context ctx, IntPtr dev) 156 { 157 this.ctx = ctx; 158 this.dev = dev; 159 channels = new List<Channel>(); 160 attrs = new List<Attr>(); 161 debug_attrs = new List<Attr>(); 162 163 uint nb_channels = iio_device_get_channels_count(dev), 164 nb_attrs = iio_device_get_attrs_count(dev), 165 nb_debug_attrs = iio_device_get_debug_attrs_count(dev); 166 167 for (uint i = 0; i < nb_channels; i++) 168 channels.Add(new Channel(iio_device_get_channel(dev, i))); 169 170 for (uint i = 0; i < nb_attrs; i++) 171 attrs.Add(new DeviceAttr(dev, Marshal.PtrToStringAnsi(iio_device_get_attr(dev, i)))); 172 for (uint i = 0; i < nb_debug_attrs; i++) 173 debug_attrs.Add(new DeviceDebugAttr(dev, Marshal.PtrToStringAnsi(iio_device_get_debug_attr(dev, i)))); 174 175 id = Marshal.PtrToStringAnsi(iio_device_get_id(dev)); 176 177 IntPtr name_ptr = iio_device_get_name(dev); 178 if (name_ptr == IntPtr.Zero) 179 name = ""; 180 else 181 name = Marshal.PtrToStringAnsi(name_ptr); 182 } 183 184 /// <summary>Get the <see cref="iio.Channel"/> object of the specified name.</summary> 185 /// <param name="name">Name or ID of the channel to look for</param> 186 /// <exception cref="System.Exception">The IIO device with the specified 187 /// name or ID could not be found in the current context.</exception> get_channel(string name)188 public Channel get_channel(string name) 189 { 190 foreach (Channel each in channels) { 191 if (each.name.CompareTo(name) == 0 || 192 each.id.CompareTo(name) == 0) 193 return each; 194 } 195 196 throw new Exception("Channel " + name + " not found"); 197 } 198 199 /// <summary>Affect a trigger to this device.</summary> 200 /// <param name="trig">A valid instance of the <see cref="iio.Trigger"/> class.</param> 201 /// <exception cref="System.Exception">The trigger could not be set.</exception> set_trigger(Trigger trig)202 public void set_trigger(Trigger trig) 203 { 204 int err = iio_device_set_trigger(this.dev, trig == null ? IntPtr.Zero : trig.dev); 205 if (err < 0) 206 throw new Exception("Unable to set trigger: err=" + err); 207 } 208 209 /// <summary>Get the current trigger affected to this device.</summary> 210 /// <returns>An instance of the <see cref="iio.Trigger"/> class.</returns> 211 /// <exception cref="System.Exception">The instance could not be retrieved.</exception> get_trigger()212 public Trigger get_trigger() 213 { 214 IntPtr ptr = (IntPtr)0; 215 int err = iio_device_get_trigger(this.dev, ptr); 216 if (err < 0) 217 throw new Exception("Unable to get trigger: err=" + err); 218 219 ptr = Marshal.ReadIntPtr(ptr); 220 221 foreach (Trigger trig in ctx.devices) { 222 if (trig.dev == ptr) 223 return trig; 224 } 225 226 return null; 227 } 228 229 /// <summary>Get the current sample size of the device.</summary> 230 /// <remarks>The sample size varies each time channels get enabled or disabled.</remarks> 231 /// <exception cref="System.Exception">Internal error. Please report any bug.</exception> get_sample_size()232 public uint get_sample_size() 233 { 234 int ret = iio_device_get_sample_size(dev); 235 if (ret < 0) 236 throw new Exception("Internal error. Please report any bug."); 237 return (uint) ret; 238 } 239 /// <summary>Set a value to one register of this device.</summary> 240 /// <param name="addr">The address of the register concerned.</param> 241 /// <param name="value">The value that will be used for this register.</param> 242 /// <exception cref="System.Exception">The register could not be written.</exception> reg_write(uint addr, uint value)243 public void reg_write(uint addr, uint value) 244 { 245 int err = iio_device_reg_write(dev, addr, value); 246 if (err < 0) 247 throw new Exception("Unable to write register"); 248 } 249 250 /// <summary>Read the content of a register of this device.</summary> 251 /// <param name="addr">The address of the register concerned.</param> 252 /// <exception cref="System.Exception">The register could not be read.</exception> reg_read(uint addr)253 public uint reg_read(uint addr) 254 { 255 uint value = 0; 256 int err = iio_device_reg_read(dev, addr, ref value); 257 if (err < 0) 258 throw new Exception("Unable to read register"); 259 return value; 260 } 261 } 262 } 263