/// <summary> /// Open the device, as needed. /// </summary> public bool Open(bool readWrite = true) { // Open, but without read/write access? if (IsOpen && readWrite && !IsOpenReadWrite) { Close(); } if (!IsOpen) { Handle = HidNativeMethods.CreateFile( Path, readWrite ? HidNativeMethods.GENERIC_READ | HidNativeMethods.GENERIC_WRITE : 0, HidNativeMethods.FILE_SHARE_READ | HidNativeMethods.FILE_SHARE_WRITE, IntPtr.Zero, HidNativeMethods.OPEN_EXISTING, 0, IntPtr.Zero); IsOpenReadWrite = readWrite; } return(IsOpen); }
/// <summary> /// Close device, as needed. /// </summary> private void Close() { if (IsOpen) { HidNativeMethods.CloseHandle(Handle); Handle = IntPtr.Zero; IsOpenReadWrite = false; } }
/// <summary> /// Write report data to the bootloader. /// </summary> private bool WriteInternal() { bool WriteDevice() { var written = Device.Open(); if (written) { uint bytesWritten = 0; written = HidNativeMethods.WriteFile(Device.Handle, Data, Device.ReportLength, ref bytesWritten, IntPtr.Zero) && bytesWritten == Device.ReportLength; } if (written) { Thread.Sleep(10); } return(written); } #if DEBUG var result = true; if (this is HidUploadReport uploadReport && uploadReport.TestOutputStream != null) { try { uploadReport.TestOutputStream.Write(Data, 0, Device.ReportLength); } catch { result = false; } }
/// <summary> /// Constructoror must be given path to device. /// </summary> public HidDevice(string path) { if (string.IsNullOrWhiteSpace(path)) { throw new TeensyException("The HID path must be specified."); } Path = path; // Get Vendor and Product IDs. if (Open(false)) { var attributes = default(HidNativeMethods.HIDD_ATTRIBUTES); attributes.Size = Marshal.SizeOf(attributes); if (HidNativeMethods.HidD_GetAttributes(Handle, ref attributes)) { // Only interested in Teensy bootloaders. if (attributes.ProductID == Constants.BootloaderId && attributes.VendorID == Constants.VendorId) { var capabilities = default(HidNativeMethods.HIDP_CAPS); var pointer = default(IntPtr); if (HidNativeMethods.HidD_GetPreparsedData(Handle, ref pointer)) { if (HidNativeMethods.HidP_GetCaps( pointer, ref capabilities) == HidNativeMethods.HIDP_STATUS_SUCCESS) { HidNativeMethods.HidD_FreePreparsedData(pointer); if (capabilities.OutputReportByteLength > 0) { ReportLength = (ushort) capabilities.OutputReportByteLength; switch (capabilities.Usage) { case 0x1B: { TeensyType = TeensyTypes.Teensy2; break; } case 0x1C: { TeensyType = TeensyTypes.Teensy2PlusPlus; break; } case 0x1D: { TeensyType = TeensyTypes.Teensy30; break; } case 0x1E: { TeensyType = TeensyTypes.Teensy31; break; } case 0x20: { TeensyType = TeensyTypes.TeensyLc; break; } case 0x21: { TeensyType = TeensyTypes.Teensy32; break; } case 0x1F: { TeensyType = TeensyTypes.Teensy35; break; } case 0x22: { TeensyType = TeensyTypes.Teensy36; break; } case 0x24: { TeensyType = TeensyTypes.Teensy40; break; } } } } } } } Close(); } }
/// <summary> /// Given a serial number, find the Teensy device that is running the /// bootloader. /// </summary> internal static HidDevice FindDevice(uint serialNumber) { var list = HidNativeMethods.GetAllDevices(serialNumber); return(list.Count > 0 ? list[0] : null); }