• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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