📄 audiostix.cs
字号:
// Copyright (c) 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.AudioStix
{
/// <summary>
/// managed wrapper for accessing the AudioStix features
/// and functions.
/// </summary>
public class IO : 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
}
public enum ADChannel : ushort
{
AD0 = 0x8012,
AD1 = 0x8016,
AD2 = 0x801A,
AD3 = 0x801C
}
#region Wave device IOCTL codes
private const Int32 CODE_IOCTL_WAV_WRITE_AC97 = 0x800;
private const Int32 CODE_IOCTL_WAV_READ_AC97 = 0x801;
// 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 = 0x0000001d;
private const Int32 FILE_ANY_ACCESS = 0x0;
private const Int32 METHOD_BUFFERED = 0x0;
private const Int32 IOCTL_WAV_WRITE_AC97 =
((FILE_DEVICE_SOUND) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_WAV_WRITE_AC97) << 2) | (METHOD_BUFFERED);
private const Int32 IOCTL_WAV_READ_AC97 =
((FILE_DEVICE_SOUND) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((CODE_IOCTL_WAV_READ_AC97) << 2) | (METHOD_BUFFERED);
/// <summary>
/// UCB1400 register offsets
/// </summary>
private const Int32 IODATAREGISTER = 0x5A;
private const Int32 IODIRECTIONREGISTER = 0x5C;
private const Int32 ADCONTROLREGISTER = 0x66;
private const Int32 ADDATAREGISTER = 0x68;
private const Int32 FEATURE2REGISTER = 0x6C;
/// <summary>
/// ADC filter bit in feature 2 register
/// </summary>
private const UInt16 FILTERBIT = 0x1000;
/// <summary>
/// Convert start bit ADC control register
/// </summary>
private const UInt16 CONVERT = 0x0080;
/// <summary>
/// Convert conmplete in ADC data register
/// </summary>
private const UInt16 CONVERTCOMPLETE = 0x8000;
#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;
}
#endregion
#region ctor / dtor
/// <summary>
/// Provides access to I/O resident on the AudioStix board.
/// </summary>
public IO() : base("WAV1:")
{
// open the driver
Open(FileAccess.ReadWrite, FileShare.ReadWrite);
}
~IO()
{
// close the driver
Close();
}
#endregion
#region UCB1400 register access
private UInt16 GetUCB1400Register(Int32 registerOffset)
{
byte[] outbuffer = new byte[2];
WaveParameters wp = new WaveParameters();
wp.Message = WPDM_PRIVATE_READ_AC97;
wp.Parameter1 = registerOffset;
wp.Parameter2 = 0;
this.DeviceIoControl(IOCTL_WAV_READ_AC97, SerializeToByteArray(wp), outbuffer);
return ((UInt16)DeserializeFromByteArray(outbuffer, typeof(UInt16)));
}
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_WRITE_AC97, SerializeToByteArray(wp), outbuffer);
}
#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(IO))
{
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(IO))
{
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(IO))
{
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(IO))
{
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(IO))
{
bits = (UInt16)(GetUCB1400Register(IODATAREGISTER) & (UInt16)gpio);
}
return (bits != 0);
}
#endregion
#region A/D control
public void SetAdChannel(ADChannel channel)
{
lock (typeof(IO))
{
SetUCB1400Register(FEATURE2REGISTER, (UInt16)(GetUCB1400Register(FEATURE2REGISTER) | FILTERBIT));
SetUCB1400Register(ADCONTROLREGISTER, (UInt16)channel);
}
}
public UInt16 ConvertAd()
{
UInt16 result;
lock (typeof(IO))
{
SetUCB1400Register(ADCONTROLREGISTER, (UInt16)(GetUCB1400Register(ADCONTROLREGISTER) | CONVERT));
do
{
result = GetUCB1400Register(ADDATAREGISTER);
} while ((result & CONVERTCOMPLETE) != CONVERTCOMPLETE);
}
return ((UInt16)(result & ~CONVERTCOMPLETE));
}
#endregion
#region P/Invoke 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;
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -