blob: 1697f6ef45c3d54795399eeb22f2f42eb3aea341 [file] [log] [blame]
/*
* 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);
}
}
}