📄 unsafeaudiostix.cs
字号:
// Copyright (c) 2006 David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
#region Using directives
using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Gumstix;
using OpenNETCF.IO;
#endregion
namespace Gumstix.IO
{
/// <summary>
/// managed wrapper for accessing the AudioStix features
/// and functions.
/// </summary>
unsafe public class AudioStix : StreamInterfaceDriver
{
[Flags]
public enum GPIO : ushort
{
GPIO_0 = 0x0001,
GPIO_1 = 0x0002,
GPIO_2 = 0x0004,
GPIO_3 = 0x0008,
GPIO_4 = 0x0010,
GPIO_5 = 0x0020,
GPIO_6 = 0x0040,
GPIO_7 = 0x0080,
GPIO_8 = 0x0100,
GPIO_9 = 0x0200
}
public enum InOut
{
Input,
Output
}
#region Wave device IOCTL codes
private const Int32 CODE_IOCTL_WAV_MESSAGE = 3;
// read/write AC97 messages
private const Int32 WPDM_PRIVATE_WRITE_AC97 = 0x0000040A;
private const Int32 WPDM_PRIVATE_READ_AC97 = 0x0000040B;
// private const Int32 FILE_DEVICE_SOUND = 0x00000022;
private const Int32 FILE_DEVICE_SOUND = 0x0000001d;
private const Int32 FILE_ANY_ACCESS = 0x0;
private const Int32 METHOD_BUFFERED = 0x0;
private static byte[] inbuffer = new byte[20];
private static byte[] outbuffer = new byte[4];
private const Int32 IOCTL_WAV_MESSAGE =
((FILE_DEVICE_SOUND) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_WAV_MESSAGE) << 2) | (METHOD_BUFFERED);
/// <summary>
/// UCB1400 register offsets
/// </summary>
private const Int32 IODATAREGISTER = 0x5A;
private const Int32 IODIRECTIONREGISTER = 0x5C;
#endregion
#region Native interface structures
[StructLayout(LayoutKind.Sequential)]
private struct WaveParameters
{
public Int32 DeviceId;
public Int32 Message;
public Int32 User;
public Int32 Parameter1;
public Int32 Parameter2;
}
[StructLayout(LayoutKind.Sequential)]
private struct WaveParameters2
{
public Int32 DeviceId;
public Int32 Message;
public Int32 User;
public Int32 Parameter1;
public UInt16* Parameter2;
}
#endregion
#region ctor / dtor
/// <summary>
/// Provides access to I/O resident on the AudioStix board.
/// </summary>
public AudioStix() : base("WAV1:")
{
// open the driver
Open(FileAccess.ReadWrite, FileShare.ReadWrite);
}
~AudioStix()
{
// close the driver
Close();
}
#endregion
#region UCB1400 register access
private UInt16 GetUCB1400Register(Int32 registerOffset)
{
WaveParameters2 wp = new WaveParameters2();
UInt16 data;
byte[] outbuffer = new byte[4];
wp.Message = WPDM_PRIVATE_READ_AC97;
wp.Parameter1 = registerOffset;
wp.Parameter2 = &data;
this.DeviceIoControl(IOCTL_WAV_MESSAGE, SerializeToByteArray(wp), outbuffer);
if (BitConverter.ToUInt32(outbuffer, 0) != 0)
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "IOControl call failed");
}
return (data);
}
private void SetUCB1400Register(Int32 registerOffset, UInt16 Data)
{
WaveParameters wp = new WaveParameters();
byte[] outbuffer = new byte[4];
wp.Message = WPDM_PRIVATE_WRITE_AC97;
wp.Parameter1 = registerOffset;
wp.Parameter2 = Convert.ToInt32(Data);
this.DeviceIoControl(IOCTL_WAV_MESSAGE, SerializeToByteArray(wp), outbuffer);
if (BitConverter.ToUInt32(outbuffer, 0) != 0)
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "IOControl call failed");
}
}
#endregion
#region GPIO bit manipulation
/// <summary>
/// Sets up the GPIO direction.
/// </summary>
/// <param name="gpio">
/// The GPIO(s) enum flags
/// </param>
/// <param name="inout">
/// Input/Output
/// </param>
public void SetGPIODirection(GPIO gpio, InOut inout)
{
lock (typeof(AudioStix))
{
switch (inout)
{
case InOut.Input:
SetUCB1400Register(IODIRECTIONREGISTER, (UInt16)(GetUCB1400Register(IODIRECTIONREGISTER) & (UInt16)(~(UInt16)gpio)));
break;
case InOut.Output:
SetUCB1400Register(IODIRECTIONREGISTER, (UInt16)(GetUCB1400Register(IODIRECTIONREGISTER) | (UInt16)gpio));
break;
}
}
}
public UInt16 GetGPIODirection()
{
lock (typeof(AudioStix))
{
return GetUCB1400Register(IODIRECTIONREGISTER);
}
}
/// <summary>
/// Sets a GPIO output bit or bits
/// </summary>
/// <param name="gpio">
/// The GPIO(s) enum flags
/// </param>
public void BitSet(GPIO gpio)
{
lock (typeof(AudioStix))
{
SetUCB1400Register(IODATAREGISTER, (UInt16)(GetUCB1400Register(IODATAREGISTER) | (UInt16)gpio));
}
}
/// <summary>
/// Clears a GPIO output bit or bits
/// </summary>
/// <param name="gpio">
/// The GPIO(s) enum flags
/// </param>
public void BitClear(GPIO gpio)
{
lock (typeof(AudioStix))
{
SetUCB1400Register(IODATAREGISTER, (UInt16)(GetUCB1400Register(IODATAREGISTER) & (UInt16)(~(UInt16)gpio)));
}
}
/// <summary>
/// Test a GPIO input bit
/// </summary>
/// <param name="gpio">
/// GPIO(s) to test
/// </param>
/// <returns>
/// Returns true if any of the selected GPIOs is high, false if 0
/// </returns>
public bool BitTest(GPIO gpio)
{
UInt16 bits;
lock (typeof(AudioStix))
{
bits = (UInt16)(GetUCB1400Register(IODATAREGISTER) & (UInt16)gpio);
}
return (bits != 0);
}
#endregion
#region P/Invokes and helpers
/// <summary>
/// Byte array serializer
/// </summary>
/// <param name="anything"></param>
/// <returns></returns>
private static byte[] SerializeToByteArray(object anything)
{
int rawsize = Marshal.SizeOf(anything);
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(anything, buffer, false);
byte[] rawdatas = new byte[rawsize];
Marshal.Copy(buffer, rawdatas, 0, rawsize);
Marshal.FreeHGlobal(buffer);
return rawdatas;
}
/// <summary>
/// De-serializer from byte array
/// </summary>
/// <param name="rawdatas"></param>
/// <param name="anytype"></param>
/// <returns></returns>
private static object DeserializeFromByteArray(byte[] rawdatas, Type anytype)
{
int rawsize = Marshal.SizeOf(anytype);
if (rawsize > rawdatas.Length)
return null;
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(rawdatas, 0, buffer, rawsize);
object retobj = Marshal.PtrToStructure(buffer, anytype);
Marshal.FreeHGlobal(buffer);
return retobj;
}
//[DllImport("coredll.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
//internal static extern int DeviceIoControl(
// IntPtr hDevice,
// uint dwIoControlCode,
// byte[] lpInBuffer,
// int nInBufferSize,
// byte[] lpOutBuffer,
// int nOutBufferSize,
// ref int lpBytesReturned,
// IntPtr lpOverlapped);
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -