annotate USBLib/Communication/LibUsb0/LibUsbDevice.cs @ 67:2d16447eff12

Simplified USB communication code, added functions to abort pipe transfers
author Ivo Smits <Ivo@UCIS.nl>
date Wed, 16 Oct 2013 01:11:49 +0200
parents 053cc617af54
children d467cd38b34e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 using System;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using System.ComponentModel;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 using System.Runtime.InteropServices;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Threading;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using Microsoft.Win32.SafeHandles;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6 using UCIS.USBLib.Internal.Windows;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 namespace UCIS.USBLib.Communication.LibUsb {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 public class LibUsb0Device : UsbInterface, IUsbDevice {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 public string DeviceFilename { get; private set; }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 public IUsbDeviceRegistry Registry { get; private set; }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 private SafeFileHandle DeviceHandle;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 public LibUsb0Device(String path, LibUsb0Registry registry) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 DeviceFilename = path;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 this.Registry = registry;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 DeviceHandle = Kernel32.CreateFile(DeviceFilename,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 NativeFileAccess.SPECIAL,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 NativeFileShare.NONE,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 IntPtr.Zero,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21 NativeFileMode.OPEN_EXISTING,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 NativeFileFlag.FILE_FLAG_OVERLAPPED,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 IntPtr.Zero);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 if (DeviceHandle.IsInvalid || DeviceHandle.IsClosed) throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not open device");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 public override void Close() {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 if (DeviceHandle != null) DeviceHandle.Close();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30 public override Byte Configuration {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 get { return base.Configuration; }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 set {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 ControlWrite(
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 UsbControlRequestType.EndpointOut | UsbControlRequestType.TypeStandard | UsbControlRequestType.RecipDevice,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 (byte)UsbStandardRequest.SetConfiguration,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36 value,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 0, null, 0, 0);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41 public void ClaimInterface(int interfaceID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 req.Iface.ID = interfaceID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 DeviceIoControl(DeviceHandle, LibUsbIoCtl.CLAIM_INTERFACE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 public void ReleaseInterface(int interfaceID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 req.Iface.ID = interfaceID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RELEASE_INTERFACE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 public void SetAltInterface(int interfaceID, int alternateID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57 req.Iface.ID = interfaceID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 req.Iface.AlternateID = alternateID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 DeviceIoControl(DeviceHandle, LibUsbIoCtl.SET_INTERFACE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 public void ResetDevice() {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_DEVICE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 public unsafe override int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 req.Descriptor.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 req.Descriptor.LangID = langId;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 req.Descriptor.Recipient = (byte)UsbEndpointDirection.EndpointIn & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 req.Descriptor.Type = descriptorType;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 fixed (Byte* b = buffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 DeviceIoControl(DeviceHandle, LibUsbIoCtl.GET_DESCRIPTOR, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 }
67
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
83 public override int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
84 if ((requestType & UsbControlRequestType.EndpointMask) == UsbControlRequestType.EndpointIn)
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
85 return ControlRead(requestType, request, value, index, buffer, offset, length);
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
86 else
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
87 return ControlWrite(requestType, request, value, index, buffer, offset, length);
46
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
88 }
67
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
89 public unsafe int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90 if (buffer == null) buffer = new Byte[0];
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 int code;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 PrepareControlTransfer(requestType, request, value, index, length, ref req, out code);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96 fixed (Byte* b = buffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 DeviceIoControl(DeviceHandle, code, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
99 return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
100 }
67
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
101 public unsafe int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 Byte[] inbuffer = new Byte[length + LibUsbRequest.Size];
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 if (length > 0) Buffer.BlockCopy(buffer, offset, inbuffer, LibUsbRequest.Size, length);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104 int code;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 fixed (Byte* inbufferp = inbuffer)
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 PrepareControlTransfer(requestType, request, value, index, length, ref *((LibUsbRequest*)inbufferp), out code);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 DeviceIoControl(DeviceHandle, code, inbuffer, length + LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 return length;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 //ret -= LibUsbRequest.Size;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 //if (ret <= 0) return 0;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 //return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 void PrepareControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, int length, ref LibUsbRequest req, out int code) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 code = LibUsbIoCtl.CONTROL_TRANSFER;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 req.Control.RequestType = (Byte)requestType;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 req.Control.Request = request;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 req.Control.Value = (ushort)value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120 req.Control.Index = (ushort)index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 req.Control.Length = (ushort)length;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 switch ((UsbControlRequestType)((int)requestType & (0x03 << 5))) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 case UsbControlRequestType.TypeStandard:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 switch ((UsbStandardRequest)request) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 case UsbStandardRequest.GetStatus:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 req.Status.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 req.Status.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 code = LibUsbIoCtl.GET_STATUS;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 case UsbStandardRequest.ClearFeature:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 req.Feature.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 req.Feature.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 req.Feature.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 code = LibUsbIoCtl.CLEAR_FEATURE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 case UsbStandardRequest.SetFeature:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 req.Feature.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 req.Feature.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 req.Feature.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 code = LibUsbIoCtl.SET_FEATURE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 case UsbStandardRequest.GetDescriptor:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 req.Descriptor.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 req.Descriptor.Type = (value >> 8) & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 req.Descriptor.Index = value & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 req.Descriptor.LangID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 code = LibUsbIoCtl.GET_DESCRIPTOR;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 case UsbStandardRequest.SetDescriptor:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 req.Descriptor.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 req.Descriptor.Type = (value >> 8) & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 req.Descriptor.Index = value & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 req.Descriptor.LangID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 code = LibUsbIoCtl.SET_DESCRIPTOR;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 case UsbStandardRequest.GetConfiguration:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 code = LibUsbIoCtl.GET_CONFIGURATION;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159 case UsbStandardRequest.SetConfiguration:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160 req.Config.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 code = LibUsbIoCtl.SET_CONFIGURATION;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 case UsbStandardRequest.GetInterface:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164 req.Iface.ID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 code = LibUsbIoCtl.GET_INTERFACE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 case UsbStandardRequest.SetInterface:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 req.Iface.ID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 req.Iface.AlternateID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170 code = LibUsbIoCtl.SET_INTERFACE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 default:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 throw new ArgumentException(String.Format("Invalid request: 0x{0:X8}", request));
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 case UsbControlRequestType.TypeVendor:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 case UsbControlRequestType.TypeClass:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 req.Vendor.Type = ((byte)requestType >> 5) & 0x03;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 req.Vendor.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 req.Vendor.Request = (int)request;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 req.Vendor.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 req.Vendor.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 code = ((byte)requestType & 0x80) != 0 ? LibUsbIoCtl.VENDOR_READ : LibUsbIoCtl.VENDOR_WRITE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185 case UsbControlRequestType.TypeReserved:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 default:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 throw new ArgumentException(String.Format("Invalid or unsupported request type: 0x{0:X8}", requestType));
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
188 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190
67
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
191 public override int PipeTransfer(Byte epnum, Byte[] buffer, int offset, int length) {
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
192 return PipeTransfer(epnum, (epnum & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointOut, false, buffer, offset, length, 0);
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
193 }
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
194
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195 unsafe int PipeTransfer(Byte epnum, Boolean write, Boolean isochronous, Byte[] buffer, int offset, int length, int packetsize) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
196 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 req.Endpoint.ID = epnum;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 req.Endpoint.PacketSize = packetsize;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 fixed (Byte* b = buffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 if (write) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203 int cltCode = isochronous ? LibUsbIoCtl.ISOCHRONOUS_WRITE : LibUsbIoCtl.INTERRUPT_OR_BULK_WRITE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
204 int transfered = 0;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
205 while (length > 0) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
207 DeviceIoControl(DeviceHandle, cltCode, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), Math.Min(Int16.MaxValue, length), out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 if (ret <= 0) throw new System.IO.EndOfStreamException();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209 length -= ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 offset += ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 transfered += ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
213 return transfered;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
214 } else {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215 int cltCode = isochronous ? LibUsbIoCtl.ISOCHRONOUS_READ : LibUsbIoCtl.INTERRUPT_OR_BULK_READ;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
217 DeviceIoControl(DeviceHandle, cltCode, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), Math.Min(UInt16.MaxValue, length), out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
218 return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
219 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
220 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
221 }
67
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
222 public override void PipeReset(byte pipeID) {
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
223 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
224 req.Endpoint.ID = pipeID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
225 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
226 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
227 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
228 }
67
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
229 public override void PipeAbort(byte pipeID) {
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
230 LibUsbRequest req = new LibUsbRequest();
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
231 req.Endpoint.ID = pipeID;
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
232 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
233 int ret;
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
234 DeviceIoControl(DeviceHandle, LibUsbIoCtl.ABORT_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret);
2d16447eff12 Simplified USB communication code, added functions to abort pipe transfers
Ivo Smits <Ivo@UCIS.nl>
parents: 46
diff changeset
235 }
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
236
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
237 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
238 fixed (LibUsbRequest* InBufferPtr = &InBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
239 fixed (Byte* OutBufferPtr = OutBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
240 DeviceIoControl(hDevice, IoControlCode, (IntPtr)InBufferPtr, nInBufferSize, (IntPtr)OutBufferPtr, nOutBufferSize, out pBytesReturned);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
241 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
242 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
243 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
244 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, Byte[] InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
245 fixed (Byte* InBufferPtr = InBuffer, OutBufferPtr = OutBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
246 DeviceIoControl(hDevice, IoControlCode, (IntPtr)InBufferPtr, nInBufferSize, (IntPtr)OutBufferPtr, nOutBufferSize, out pBytesReturned);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
247 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
248 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
249 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
250 fixed (LibUsbRequest* InBufferPtr = &InBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
251 DeviceIoControl(hDevice, IoControlCode, (IntPtr)InBufferPtr, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
252 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
253 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
254 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, IntPtr InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
255 using (ManualResetEvent evt = new ManualResetEvent(false)) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
256 NativeOverlapped overlapped = new NativeOverlapped();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
257 overlapped.EventHandle = evt.SafeWaitHandle.DangerousGetHandle();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
258 if (Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, &overlapped))
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
259 return;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
260 int err = Marshal.GetLastWin32Error();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
261 if (err != 997) throw new Win32Exception(err);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
262 evt.WaitOne();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
263 if (!Kernel32.GetOverlappedResult(hDevice, &overlapped, out pBytesReturned, false))
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
264 throw new Win32Exception(Marshal.GetLastWin32Error());
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
265 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
266 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
267 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
268 }