diff options
Diffstat (limited to 'src/bindings/csharp/IOBuffer.cs')
-rw-r--r-- | src/bindings/csharp/IOBuffer.cs | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/bindings/csharp/IOBuffer.cs b/src/bindings/csharp/IOBuffer.cs new file mode 100644 index 0000000..1697f6e --- /dev/null +++ b/src/bindings/csharp/IOBuffer.cs @@ -0,0 +1,143 @@ +/* + * libiio - Library for interfacing industrial I/O (IIO) devices + * + * Copyright (C) 2015 Analog Devices, Inc. + * Author: Paul Cercueil <paul.cercueil@analog.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace iio +{ + /// <summary><see cref="iio.IOBuffer"/> class: + /// The class used for all I/O operations.</summary> + public class IOBuffer : IDisposable + { + private bool circular_buffer_pushed; + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_device_create_buffer(IntPtr dev, uint samples_count, + [MarshalAs(UnmanagedType.I1)] bool circular); + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern void iio_buffer_destroy(IntPtr buf); + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_buffer_refill(IntPtr buf); + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern int iio_buffer_push_partial(IntPtr buf, uint samples_count); + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_buffer_start(IntPtr buf); + + [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr iio_buffer_end(IntPtr buf); + + internal IntPtr buf; + + /// <summary>The size of this buffer, in samples.</summary> + public readonly uint samples_count; + + /// <summary>If <c>true</c>, the buffer is circular.</summary> + public readonly bool circular; + + /// <summary>Initializes a new instance of the <see cref="iio.IOBuffer"/> class.</summary> + /// <param name="dev">The <see cref="iio.Device"/> object that represents the device + /// where the I/O operations will be performed.</param> + /// <param name="samples_count">The size of the buffer, in samples.</param> + /// <param name="circular">If set to <c>true</c>, the buffer is circular.</param> + /// <exception cref="System.Exception">The buffer could not be created.</exception> + public IOBuffer(Device dev, uint samples_count, bool circular = false) + { + this.samples_count = samples_count; + this.circular = circular; + this.circular_buffer_pushed = false; + + buf = iio_device_create_buffer(dev.dev, samples_count, circular); + if (buf == IntPtr.Zero) + throw new Exception("Unable to create buffer"); + } + + ~IOBuffer() + { + if (buf != IntPtr.Zero) + Dispose(false); + } + + /// <summary>Fetch a new set of samples from the hardware.</summary> + /// <exception cref="System.Exception">The buffer could not be refilled.</exception> + public void refill() + { + int err = iio_buffer_refill(this.buf); + if (err < 0) + throw new Exception("Unable to refill buffer: err=" + err); + } + + /// <summary>Submit the samples contained in this buffer to the hardware.</summary> + /// <exception cref="System.Exception">The buffer could not be pushed.</exception> + public void push(uint samples_count) + { + if (circular && circular_buffer_pushed) + throw new Exception("Circular buffer already pushed\n"); + + int err = iio_buffer_push_partial(this.buf, samples_count); + if (err < 0) + throw new Exception("Unable to push buffer: err=" + err); + circular_buffer_pushed = true; + } + + public void push() + { + push(this.samples_count); + } + + /// <summary>Releases all resource used by the <see cref="iio.IOBuffer"/> object.</summary> + /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="iio.IOBuffer"/>. The + /// <see cref="Dispose"/> method leaves the <see cref="iio.IOBuffer"/> in an unusable state. After calling + /// <see cref="Dispose"/>, you must release all references to the <see cref="iio.IOBuffer"/> so the garbage + /// collector can reclaim the memory that the <see cref="iio.IOBuffer"/> was occupying.</remarks> + public void Dispose() + { + Dispose(true); + } + + private void Dispose(bool clean) + { + if (buf != IntPtr.Zero) + { + if (clean) + GC.SuppressFinalize(this); + iio_buffer_destroy(buf); + buf = IntPtr.Zero; + } + } + + /// <summary>Copy the given array of samples inside the <see cref="iio.IOBuffer"/> object.</summary> + /// <param name="array">A <c>byte</c> array containing the samples that should be written.</param> + /// <remarks>The number of samples written will not exceed the size of the buffer.</remarks> + public void fill(byte[] array) + { + int length = (int) iio_buffer_end(buf) - (int) iio_buffer_start(buf); + if (length > array.Length) + length = array.Length; + Marshal.Copy(array, 0, iio_buffer_start(buf), length); + } + } +} |