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.IOBuffer"/> class: 29 /// The class used for all I/O operations.</summary> 30 public class IOBuffer : IDisposable 31 { 32 private bool circular_buffer_pushed; 33 34 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_device_create_buffer(IntPtr dev, uint samples_count, [MarshalAs(UnmanagedType.I1)] bool circular)35 private static extern IntPtr iio_device_create_buffer(IntPtr dev, uint samples_count, 36 [MarshalAs(UnmanagedType.I1)] bool circular); 37 38 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_buffer_destroy(IntPtr buf)39 private static extern void iio_buffer_destroy(IntPtr buf); 40 41 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_buffer_refill(IntPtr buf)42 private static extern int iio_buffer_refill(IntPtr buf); 43 44 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_buffer_push_partial(IntPtr buf, uint samples_count)45 private static extern int iio_buffer_push_partial(IntPtr buf, uint samples_count); 46 47 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_buffer_start(IntPtr buf)48 private static extern IntPtr iio_buffer_start(IntPtr buf); 49 50 [DllImport("libiio.dll", CallingConvention = CallingConvention.Cdecl)] iio_buffer_end(IntPtr buf)51 private static extern IntPtr iio_buffer_end(IntPtr buf); 52 53 internal IntPtr buf; 54 55 /// <summary>The size of this buffer, in samples.</summary> 56 public readonly uint samples_count; 57 58 /// <summary>If <c>true</c>, the buffer is circular.</summary> 59 public readonly bool circular; 60 61 /// <summary>Initializes a new instance of the <see cref="iio.IOBuffer"/> class.</summary> 62 /// <param name="dev">The <see cref="iio.Device"/> object that represents the device 63 /// where the I/O operations will be performed.</param> 64 /// <param name="samples_count">The size of the buffer, in samples.</param> 65 /// <param name="circular">If set to <c>true</c>, the buffer is circular.</param> 66 /// <exception cref="System.Exception">The buffer could not be created.</exception> IOBuffer(Device dev, uint samples_count, bool circular = false)67 public IOBuffer(Device dev, uint samples_count, bool circular = false) 68 { 69 this.samples_count = samples_count; 70 this.circular = circular; 71 this.circular_buffer_pushed = false; 72 73 buf = iio_device_create_buffer(dev.dev, samples_count, circular); 74 if (buf == IntPtr.Zero) 75 throw new Exception("Unable to create buffer"); 76 } 77 ~IOBuffer()78 ~IOBuffer() 79 { 80 if (buf != IntPtr.Zero) 81 Dispose(false); 82 } 83 84 /// <summary>Fetch a new set of samples from the hardware.</summary> 85 /// <exception cref="System.Exception">The buffer could not be refilled.</exception> refill()86 public void refill() 87 { 88 int err = iio_buffer_refill(this.buf); 89 if (err < 0) 90 throw new Exception("Unable to refill buffer: err=" + err); 91 } 92 93 /// <summary>Submit the samples contained in this buffer to the hardware.</summary> 94 /// <exception cref="System.Exception">The buffer could not be pushed.</exception> push(uint samples_count)95 public void push(uint samples_count) 96 { 97 if (circular && circular_buffer_pushed) 98 throw new Exception("Circular buffer already pushed\n"); 99 100 int err = iio_buffer_push_partial(this.buf, samples_count); 101 if (err < 0) 102 throw new Exception("Unable to push buffer: err=" + err); 103 circular_buffer_pushed = true; 104 } 105 push()106 public void push() 107 { 108 push(this.samples_count); 109 } 110 111 /// <summary>Releases all resource used by the <see cref="iio.IOBuffer"/> object.</summary> 112 /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="iio.IOBuffer"/>. The 113 /// <see cref="Dispose"/> method leaves the <see cref="iio.IOBuffer"/> in an unusable state. After calling 114 /// <see cref="Dispose"/>, you must release all references to the <see cref="iio.IOBuffer"/> so the garbage 115 /// collector can reclaim the memory that the <see cref="iio.IOBuffer"/> was occupying.</remarks> Dispose()116 public void Dispose() 117 { 118 Dispose(true); 119 } 120 Dispose(bool clean)121 private void Dispose(bool clean) 122 { 123 if (buf != IntPtr.Zero) 124 { 125 if (clean) 126 GC.SuppressFinalize(this); 127 iio_buffer_destroy(buf); 128 buf = IntPtr.Zero; 129 } 130 } 131 132 /// <summary>Copy the given array of samples inside the <see cref="iio.IOBuffer"/> object.</summary> 133 /// <param name="array">A <c>byte</c> array containing the samples that should be written.</param> 134 /// <remarks>The number of samples written will not exceed the size of the buffer.</remarks> fill(byte[] array)135 public void fill(byte[] array) 136 { 137 int length = (int) iio_buffer_end(buf) - (int) iio_buffer_start(buf); 138 if (length > array.Length) 139 length = array.Length; 140 Marshal.Copy(array, 0, iio_buffer_start(buf), length); 141 } 142 } 143 } 144