This is the latest working repository used in our demo video for the Maxim to display temperature readings on Bluetooth

Dependencies:   USBDevice

Committer:
darienf
Date:
Sat Apr 10 03:05:42 2021 +0000
Revision:
3:36de8b9e4b1a
ayoooo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
darienf 3:36de8b9e4b1a 1 using System;
darienf 3:36de8b9e4b1a 2 using System.Collections;
darienf 3:36de8b9e4b1a 3 using System.Threading;
darienf 3:36de8b9e4b1a 4 using System.IO;
darienf 3:36de8b9e4b1a 5 using System.Runtime.InteropServices;
darienf 3:36de8b9e4b1a 6 using System.Windows.Forms;
darienf 3:36de8b9e4b1a 7 using Microsoft.Win32.SafeHandles;
darienf 3:36de8b9e4b1a 8
darienf 3:36de8b9e4b1a 9 //------------------------------------------------------------------------------------------
darienf 3:36de8b9e4b1a 10 // OS24EVK-59 split into HeartRateApp EXE and MAX30101 DLL.
darienf 3:36de8b9e4b1a 11 // Moved all MAX30101 DLL classes into namespace Maxim.MAX30101GUI
darienf 3:36de8b9e4b1a 12 // Moved all HeartRateApp GUI classes into namespace Maxim.MAX30101
darienf 3:36de8b9e4b1a 13 // OS24EVK-59 Create separate project that builds Maxim.MAX30101GUI DLL library
darienf 3:36de8b9e4b1a 14
darienf 3:36de8b9e4b1a 15 // OS24EVK-59 moved class HID into namespace Maxim.MAX30101 instead of namespace HeartRateApp
darienf 3:36de8b9e4b1a 16 namespace Maxim.MAX30101
darienf 3:36de8b9e4b1a 17 {
darienf 3:36de8b9e4b1a 18 #pragma warning disable 1574
darienf 3:36de8b9e4b1a 19 /// <summary>
darienf 3:36de8b9e4b1a 20 /// USB Human Interface Device functions to connect to EV kit without requiring a custom device driver
darienf 3:36de8b9e4b1a 21 /// </summary>
darienf 3:36de8b9e4b1a 22 #pragma warning restore 1574
darienf 3:36de8b9e4b1a 23 public class HID
darienf 3:36de8b9e4b1a 24 {
darienf 3:36de8b9e4b1a 25 private IntPtr EventObject;
darienf 3:36de8b9e4b1a 26 private System.Threading.NativeOverlapped managedOverlapped;
darienf 3:36de8b9e4b1a 27 private IntPtr nonManagedOverlapped;
darienf 3:36de8b9e4b1a 28 private IntPtr nonManagedBuffer;
darienf 3:36de8b9e4b1a 29 public SafeFileHandle writeHandle;
darienf 3:36de8b9e4b1a 30 public ArrayList writeHandleArray = new ArrayList();
darienf 3:36de8b9e4b1a 31 public SafeFileHandle readHandle;
darienf 3:36de8b9e4b1a 32 public ArrayList readHandleArray = new ArrayList();
darienf 3:36de8b9e4b1a 33 public ArrayList desiredHIDPathNameArray = new ArrayList();
darienf 3:36de8b9e4b1a 34 public String deviceID = System.String.Format("Vid_{0:x4}&Pid_{1:x4}", support.DEFAULT_VENDOR_ID, support.DEFAULT_PRODUCT_ID);
darienf 3:36de8b9e4b1a 35
darienf 3:36de8b9e4b1a 36 private bool explicit_report_id = true;
darienf 3:36de8b9e4b1a 37 private const byte DEFAULT_REPORT_ID = 0;
darienf 3:36de8b9e4b1a 38 private const byte SHORT_REPORT_ID = 1;
darienf 3:36de8b9e4b1a 39 public const byte HID_REPORT_ID_1 = 1; // MAX30101 optical data, 3 bytes per channel, up to 3 channels per sample
darienf 3:36de8b9e4b1a 40 public const byte HID_REPORT_ID_2 = 2; // LIS2DH accelerometer data, 2 bytes per channel, 3 channels per sample
darienf 3:36de8b9e4b1a 41 public const byte HID_REPORT_ID_3 = 3; // reserved
darienf 3:36de8b9e4b1a 42 private const byte USB_OVERFLOW = 8;
darienf 3:36de8b9e4b1a 43 private const byte USB_WRITE_ERROR = 4;
darienf 3:36de8b9e4b1a 44 private const byte USB_READ_ERROR = 2;
darienf 3:36de8b9e4b1a 45 public const byte I2C_NACK_ERROR = 1;
darienf 3:36de8b9e4b1a 46 private const byte API_FAIL = 0; //API functions return non-0 upon success, to easily denote 'true' for C programs
darienf 3:36de8b9e4b1a 47 private const byte I2C_SUCCESS = 3; //we'll also use a non-0 value to denote success, since returning a '0' would lead to trouble when mixed with API's returns.
darienf 3:36de8b9e4b1a 48 private const byte GP_SUCCESS = 3;
darienf 3:36de8b9e4b1a 49 private const byte GP_FAIL = 0;
darienf 3:36de8b9e4b1a 50 private const byte REPORT_SIZE = 64;
darienf 3:36de8b9e4b1a 51
darienf 3:36de8b9e4b1a 52 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] before FlushQueue()
darienf 3:36de8b9e4b1a 53 // mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 54 // mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 55 public static Mutex mutexGuardIOBuf = new Mutex();
darienf 3:36de8b9e4b1a 56 // TODO1: OS24EVK-57 2015-04-01 myHID.readHID2() needs to return result into IOBuf. But IOBuf = new byte[64], do we replace with IOBuf = new byte[128]? Does this affect readHID()?
darienf 3:36de8b9e4b1a 57 public byte[] IOBuf = new byte[REPORT_SIZE];
darienf 3:36de8b9e4b1a 58
darienf 3:36de8b9e4b1a 59 private const int IOtimeout = 10000;
darienf 3:36de8b9e4b1a 60
darienf 3:36de8b9e4b1a 61 // API declarations relating to device management (SetupDixxx and
darienf 3:36de8b9e4b1a 62 // RegisterDeviceNotification functions).
darienf 3:36de8b9e4b1a 63
darienf 3:36de8b9e4b1a 64 // from dbt.h
darienf 3:36de8b9e4b1a 65
darienf 3:36de8b9e4b1a 66 internal const Int32 DBT_DEVNODES_CHANGED = 7;
darienf 3:36de8b9e4b1a 67 internal const Int32 DBT_DEVICEARRIVAL = 0X8000;
darienf 3:36de8b9e4b1a 68 internal const Int32 DBT_DEVICEREMOVECOMPLETE = 0X8004;
darienf 3:36de8b9e4b1a 69 internal const Int32 DBT_DEVTYP_DEVICEINTERFACE = 5;
darienf 3:36de8b9e4b1a 70 internal const Int32 DBT_DEVTYP_HANDLE = 6;
darienf 3:36de8b9e4b1a 71 internal const Int32 DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 4;
darienf 3:36de8b9e4b1a 72 internal const Int32 DEVICE_NOTIFY_SERVICE_HANDLE = 1;
darienf 3:36de8b9e4b1a 73 internal const Int32 DEVICE_NOTIFY_WINDOW_HANDLE = 0;
darienf 3:36de8b9e4b1a 74 internal const Int32 WM_DEVICECHANGE = 0X219;
darienf 3:36de8b9e4b1a 75 internal const Int32 SPDRP_HARDWAREID = 1;
darienf 3:36de8b9e4b1a 76
darienf 3:36de8b9e4b1a 77 // from setupapi.h
darienf 3:36de8b9e4b1a 78
darienf 3:36de8b9e4b1a 79 internal const Int32 DIGCF_PRESENT = 2;
darienf 3:36de8b9e4b1a 80 internal const Int32 DIGCF_DEVICEINTERFACE = 0X10;
darienf 3:36de8b9e4b1a 81
darienf 3:36de8b9e4b1a 82 // Two declarations for the DEV_BROADCAST_DEVICEINTERFACE structure.
darienf 3:36de8b9e4b1a 83
darienf 3:36de8b9e4b1a 84 // Use this one in the call to RegisterDeviceNotification() and
darienf 3:36de8b9e4b1a 85 // in checking dbch_devicetype in a DEV_BROADCAST_HDR structure:
darienf 3:36de8b9e4b1a 86
darienf 3:36de8b9e4b1a 87 [StructLayout(LayoutKind.Sequential)]
darienf 3:36de8b9e4b1a 88 internal class DEV_BROADCAST_DEVICEINTERFACE
darienf 3:36de8b9e4b1a 89 {
darienf 3:36de8b9e4b1a 90 internal Int32 dbcc_size;
darienf 3:36de8b9e4b1a 91 internal Int32 dbcc_devicetype;
darienf 3:36de8b9e4b1a 92 internal Int32 dbcc_reserved;
darienf 3:36de8b9e4b1a 93 internal Guid dbcc_classguid;
darienf 3:36de8b9e4b1a 94 internal Int16 dbcc_name;
darienf 3:36de8b9e4b1a 95 }
darienf 3:36de8b9e4b1a 96
darienf 3:36de8b9e4b1a 97 // Use this to read the dbcc_name String and classguid:
darienf 3:36de8b9e4b1a 98
darienf 3:36de8b9e4b1a 99 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 100 internal class DEV_BROADCAST_DEVICEINTERFACE_1
darienf 3:36de8b9e4b1a 101 {
darienf 3:36de8b9e4b1a 102 internal Int32 dbcc_size;
darienf 3:36de8b9e4b1a 103 internal Int32 dbcc_devicetype;
darienf 3:36de8b9e4b1a 104 internal Int32 dbcc_reserved;
darienf 3:36de8b9e4b1a 105 [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 16)]
darienf 3:36de8b9e4b1a 106 internal Byte[] dbcc_classguid;
darienf 3:36de8b9e4b1a 107 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
darienf 3:36de8b9e4b1a 108 internal Char[] dbcc_name;
darienf 3:36de8b9e4b1a 109 }
darienf 3:36de8b9e4b1a 110
darienf 3:36de8b9e4b1a 111 [StructLayout(LayoutKind.Sequential)]
darienf 3:36de8b9e4b1a 112 internal class DEV_BROADCAST_HDR
darienf 3:36de8b9e4b1a 113 {
darienf 3:36de8b9e4b1a 114 internal Int32 dbch_size;
darienf 3:36de8b9e4b1a 115 internal Int32 dbch_devicetype;
darienf 3:36de8b9e4b1a 116 internal Int32 dbch_reserved;
darienf 3:36de8b9e4b1a 117 }
darienf 3:36de8b9e4b1a 118
darienf 3:36de8b9e4b1a 119 internal struct SP_DEVICE_INTERFACE_DATA
darienf 3:36de8b9e4b1a 120 {
darienf 3:36de8b9e4b1a 121 internal Int32 cbSize;
darienf 3:36de8b9e4b1a 122 internal System.Guid InterfaceClassGuid;
darienf 3:36de8b9e4b1a 123 internal Int32 Flags;
darienf 3:36de8b9e4b1a 124 internal IntPtr Reserved;
darienf 3:36de8b9e4b1a 125 }
darienf 3:36de8b9e4b1a 126
darienf 3:36de8b9e4b1a 127 //[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 128 //internal struct SP_DEVICE_INTERFACE_DETAIL_DATA
darienf 3:36de8b9e4b1a 129 //{
darienf 3:36de8b9e4b1a 130 // internal Int32 cbSize;
darienf 3:36de8b9e4b1a 131 // //internal String DevicePath;
darienf 3:36de8b9e4b1a 132 // internal Char[] DevicePath;
darienf 3:36de8b9e4b1a 133 //}
darienf 3:36de8b9e4b1a 134
darienf 3:36de8b9e4b1a 135 // warning CS0649: Field 'Maxim.MAX30101.HID.SP_DEVINFO_DATA.cbSize' is never assigned to, and will always have its default value 0
darienf 3:36de8b9e4b1a 136 #pragma warning disable 0649
darienf 3:36de8b9e4b1a 137 internal struct SP_DEVINFO_DATA
darienf 3:36de8b9e4b1a 138 {
darienf 3:36de8b9e4b1a 139 internal Int32 cbSize;
darienf 3:36de8b9e4b1a 140 internal System.Guid ClassGuid;
darienf 3:36de8b9e4b1a 141 internal Int32 DevInst;
darienf 3:36de8b9e4b1a 142 internal Int32 Reserved;
darienf 3:36de8b9e4b1a 143 }
darienf 3:36de8b9e4b1a 144 #pragma warning restore 0649
darienf 3:36de8b9e4b1a 145
darienf 3:36de8b9e4b1a 146 //HDEVINFO SetupDiGetClassDevs(const GUID *ClassGuid, PCTSTR Enumerator, HWND hwndParent, DWORD Flags);
darienf 3:36de8b9e4b1a 147 [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 148 internal static extern IntPtr SetupDiGetClassDevs(ref System.Guid ClassGuid, IntPtr Enumerator, IntPtr hwndParent, Int32 Flags);
darienf 3:36de8b9e4b1a 149
darienf 3:36de8b9e4b1a 150 //BOOL SetupDiDestroyDeviceInfoList(HDEVINFO DeviceInfoSet);
darienf 3:36de8b9e4b1a 151 [DllImport("setupapi.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 152 internal static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
darienf 3:36de8b9e4b1a 153
darienf 3:36de8b9e4b1a 154 //BOOL SetupDiEnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
darienf 3:36de8b9e4b1a 155 [DllImport("setupapi.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 156 internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
darienf 3:36de8b9e4b1a 157 [DllImport("setupapi.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 158 // required to pass DeviceInfoData=null
darienf 3:36de8b9e4b1a 159 internal static extern Boolean SetupDiEnumDeviceInterfaces(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, ref System.Guid InterfaceClassGuid, Int32 MemberIndex, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
darienf 3:36de8b9e4b1a 160
darienf 3:36de8b9e4b1a 161 //BOOL SetupDiGetDeviceInterfaceDetail(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData);
darienf 3:36de8b9e4b1a 162 //[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 163 //internal extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData);
darienf 3:36de8b9e4b1a 164 //[DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 165 //// required to pass DeviceInfoData=null
darienf 3:36de8b9e4b1a 166 //internal extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, ref SP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
darienf 3:36de8b9e4b1a 167 // cannot get SP_DEVICE_INTERFACE_DETAIL_DATA's DevicePath field to work properly, so use IntPtr instead of ref SP_DEVICE_INTERFACE_DATA
darienf 3:36de8b9e4b1a 168 [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 169 // required to pass DeviceInterfaceDetailData=null
darienf 3:36de8b9e4b1a 170 internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData);
darienf 3:36de8b9e4b1a 171 [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 172 // required to pass DeviceInterfaceDetailData=null, DeviceInfoData=null
darienf 3:36de8b9e4b1a 173 internal static extern Boolean SetupDiGetDeviceInterfaceDetail(IntPtr DeviceInfoSet, ref SP_DEVICE_INTERFACE_DATA DeviceInterfaceData, IntPtr DeviceInterfaceDetailData, Int32 DeviceInterfaceDetailDataSize, ref Int32 RequiredSize, IntPtr DeviceInfoData);
darienf 3:36de8b9e4b1a 174
darienf 3:36de8b9e4b1a 175 //BOOL SetupDiEnumDeviceInfo(HDEVINFO DeviceInfoSet, DWORD MemberIndex, PSP_DEVINFO_DATA DeviceInfoData);
darienf 3:36de8b9e4b1a 176 [DllImport("setupapi.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 177 internal static extern Boolean SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, Int32 MemberIndex, ref SP_DEVINFO_DATA DevInfoData);
darienf 3:36de8b9e4b1a 178
darienf 3:36de8b9e4b1a 179 //BOOL SetupDiGetDeviceRegistryProperty(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize);
darienf 3:36de8b9e4b1a 180 [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
darienf 3:36de8b9e4b1a 181 internal static extern Boolean SetupDiGetDeviceRegistryProperty(IntPtr DeviceInfoSet, ref SP_DEVINFO_DATA DevInfoData, Int32 Property, IntPtr PropertyRegDataType, IntPtr PropertyBuffer, Int32 PropertyBufferSize, ref Int32 RequiredSize);
darienf 3:36de8b9e4b1a 182
darienf 3:36de8b9e4b1a 183 [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
darienf 3:36de8b9e4b1a 184 internal static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, Int32 Flags);
darienf 3:36de8b9e4b1a 185
darienf 3:36de8b9e4b1a 186 [DllImport("user32.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 187 internal static extern Boolean UnregisterDeviceNotification(IntPtr Handle);
darienf 3:36de8b9e4b1a 188
darienf 3:36de8b9e4b1a 189 // API declarations for HID communications.
darienf 3:36de8b9e4b1a 190
darienf 3:36de8b9e4b1a 191 // from hidpi.h
darienf 3:36de8b9e4b1a 192 // Typedef enum defines a set of integer constants for HidP_Report_Type
darienf 3:36de8b9e4b1a 193
darienf 3:36de8b9e4b1a 194 internal const Int16 HidP_Input = 0;
darienf 3:36de8b9e4b1a 195 internal const Int16 HidP_Output = 1;
darienf 3:36de8b9e4b1a 196 internal const Int16 HidP_Feature = 2;
darienf 3:36de8b9e4b1a 197
darienf 3:36de8b9e4b1a 198 [StructLayout(LayoutKind.Sequential)]
darienf 3:36de8b9e4b1a 199 internal struct HIDD_ATTRIBUTES
darienf 3:36de8b9e4b1a 200 {
darienf 3:36de8b9e4b1a 201 internal Int32 Size;
darienf 3:36de8b9e4b1a 202 internal UInt16 VendorID;
darienf 3:36de8b9e4b1a 203 internal UInt16 ProductID;
darienf 3:36de8b9e4b1a 204 internal UInt16 VersionNumber;
darienf 3:36de8b9e4b1a 205 }
darienf 3:36de8b9e4b1a 206
darienf 3:36de8b9e4b1a 207 [DllImport("hid.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 208 internal static extern Boolean HidD_FlushQueue(SafeFileHandle HidDeviceObject);
darienf 3:36de8b9e4b1a 209
darienf 3:36de8b9e4b1a 210 [DllImport("hid.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 211 internal static extern Boolean HidD_GetAttributes(SafeFileHandle HidDeviceObject, ref HIDD_ATTRIBUTES Attributes);
darienf 3:36de8b9e4b1a 212
darienf 3:36de8b9e4b1a 213 [DllImport("hid.dll", SetLastError = true)]
darienf 3:36de8b9e4b1a 214 internal static extern void HidD_GetHidGuid(ref System.Guid HidGuid);
darienf 3:36de8b9e4b1a 215
darienf 3:36de8b9e4b1a 216 public void getHidGuid(ref System.Guid hidGuid)
darienf 3:36de8b9e4b1a 217 {
darienf 3:36de8b9e4b1a 218 DebugMessage = string.Format("{0} entered", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 219 #if DEBUG
darienf 3:36de8b9e4b1a 220 HidD_GetHidGuid(ref hidGuid);
darienf 3:36de8b9e4b1a 221 #else
darienf 3:36de8b9e4b1a 222 try
darienf 3:36de8b9e4b1a 223 {
darienf 3:36de8b9e4b1a 224 HidD_GetHidGuid(ref hidGuid);
darienf 3:36de8b9e4b1a 225 }
darienf 3:36de8b9e4b1a 226 catch (Exception ex)
darienf 3:36de8b9e4b1a 227 {
darienf 3:36de8b9e4b1a 228 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 229 }
darienf 3:36de8b9e4b1a 230 #endif
darienf 3:36de8b9e4b1a 231 DebugMessage = string.Format("{0} exited", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 232 }
darienf 3:36de8b9e4b1a 233
darienf 3:36de8b9e4b1a 234 public string DebugMessage;
darienf 3:36de8b9e4b1a 235 //public void TraceMessage(string message,
darienf 3:36de8b9e4b1a 236 //[System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
darienf 3:36de8b9e4b1a 237 //[System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
darienf 3:36de8b9e4b1a 238 //[System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
darienf 3:36de8b9e4b1a 239 //{
darienf 3:36de8b9e4b1a 240 // Console.WriteLine("message: " + message);
darienf 3:36de8b9e4b1a 241 // Console.WriteLine("member name: " + memberName);
darienf 3:36de8b9e4b1a 242 // Console.WriteLine("source file path: " + sourceFilePath);
darienf 3:36de8b9e4b1a 243 // Console.WriteLine("source line number: " + sourceLineNumber);
darienf 3:36de8b9e4b1a 244 //}
darienf 3:36de8b9e4b1a 245
darienf 3:36de8b9e4b1a 246 /// <summary>
darienf 3:36de8b9e4b1a 247 /// FindDesiredHIDPathNamesFromGuid() only appends to desiredHIDPathNameArray.
darienf 3:36de8b9e4b1a 248 /// Desired HIDs that have been removed from the system are removed from desiredHIDPathNameArray in openHIDhandles
darienf 3:36de8b9e4b1a 249 /// </summary>
darienf 3:36de8b9e4b1a 250 /// <param name="myGuid"></param>
darienf 3:36de8b9e4b1a 251 private void FindDesiredHIDPathNamesFromGuid(System.Guid myGuid)
darienf 3:36de8b9e4b1a 252 {
darienf 3:36de8b9e4b1a 253 DebugMessage = string.Format("{0} entered", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 254 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 255 // But I never see this kind of exception thrown from within the C# GUI.
darienf 3:36de8b9e4b1a 256 // HID.findHIDs() still raises the exception in Matlab,
darienf 3:36de8b9e4b1a 257 // Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 258 //
darienf 3:36de8b9e4b1a 259 // % Required: connect to MAX30101EVKIT hardware
darienf 3:36de8b9e4b1a 260 // fprintf('Connecting to MAX30101EVKIT hardware...\n');
darienf 3:36de8b9e4b1a 261 // for trial=0:2000
darienf 3:36de8b9e4b1a 262 // try
darienf 3:36de8b9e4b1a 263 // %pause(1) % delay at least 1 second
darienf 3:36de8b9e4b1a 264 // myMAX30101.myHID.findHIDs();
darienf 3:36de8b9e4b1a 265 // % Sometimes we get Error using MAX30101Example
darienf 3:36de8b9e4b1a 266 // % If this happens, try clearing the workspace and run again.
darienf 3:36de8b9e4b1a 267 // % Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 268 // % FindDesiredHIDPathNamesFromGuid
darienf 3:36de8b9e4b1a 269 // % findHIDs
darienf 3:36de8b9e4b1a 270 // % Source: MAX30101
darienf 3:36de8b9e4b1a 271 // % HelpLink:
darienf 3:36de8b9e4b1a 272 // if (myMAX30101.myHID.isConnected())
darienf 3:36de8b9e4b1a 273 // break
darienf 3:36de8b9e4b1a 274 // end
darienf 3:36de8b9e4b1a 275 // catch me
darienf 3:36de8b9e4b1a 276 // % disp(me)
darienf 3:36de8b9e4b1a 277 // end
darienf 3:36de8b9e4b1a 278 // end
darienf 3:36de8b9e4b1a 279 //
darienf 3:36de8b9e4b1a 280 // If matlab does successfully connect to USB, it is able to get
darienf 3:36de8b9e4b1a 281 // streaming data through the PartialArrayIntAvailable event
darienf 3:36de8b9e4b1a 282 // handler -- even though it can't understand
darienf 3:36de8b9e4b1a 283 // System.Collections.ArrayList data, it does at least understand
darienf 3:36de8b9e4b1a 284 // Array<System.Int32> or int[] data.
darienf 3:36de8b9e4b1a 285 //
darienf 3:36de8b9e4b1a 286 Int32 memberIndex = 0;
darienf 3:36de8b9e4b1a 287 Int32 bufferSize = 0;
darienf 3:36de8b9e4b1a 288 IntPtr deviceInfoSet = new System.IntPtr();
darienf 3:36de8b9e4b1a 289 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
darienf 3:36de8b9e4b1a 290 IntPtr deviceInterfaceDetailDataBuffer = IntPtr.Zero;
darienf 3:36de8b9e4b1a 291
darienf 3:36de8b9e4b1a 292 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 293 // diagnostic: trying to avoid "Arithmetic overflow" from matlab. Limit the number of HID devices to be checked.
darienf 3:36de8b9e4b1a 294 const int memberIndexLimit = 100;
darienf 3:36de8b9e4b1a 295
darienf 3:36de8b9e4b1a 296 #if DEBUG
darienf 3:36de8b9e4b1a 297 #else
darienf 3:36de8b9e4b1a 298 try
darienf 3:36de8b9e4b1a 299 {
darienf 3:36de8b9e4b1a 300 #endif
darienf 3:36de8b9e4b1a 301 DebugMessage = string.Format("{0} first deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 302 deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
darienf 3:36de8b9e4b1a 303
darienf 3:36de8b9e4b1a 304 memberIndex = 0;
darienf 3:36de8b9e4b1a 305
darienf 3:36de8b9e4b1a 306 // The cbSize element of the DeviceInterfaceData structure must be set to the structure's size in bytes.
darienf 3:36de8b9e4b1a 307 // The size is 28 bytes for 32-bit code and 32 bits for 64-bit code.
darienf 3:36de8b9e4b1a 308 DeviceInterfaceData.cbSize = Marshal.SizeOf(DeviceInterfaceData);
darienf 3:36de8b9e4b1a 309
darienf 3:36de8b9e4b1a 310 while (memberIndex < memberIndexLimit)
darienf 3:36de8b9e4b1a 311 {
darienf 3:36de8b9e4b1a 312 // Begin with memberIndex = 0 and increment through the device information set until no more devices are available.
darienf 3:36de8b9e4b1a 313 DebugMessage = string.Format("{0} memberIndex={1} first SetupDiEnumDeviceInterfaces ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 314 if (!SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref myGuid, memberIndex, ref DeviceInterfaceData))
darienf 3:36de8b9e4b1a 315 {
darienf 3:36de8b9e4b1a 316 break;
darienf 3:36de8b9e4b1a 317 }
darienf 3:36de8b9e4b1a 318
darienf 3:36de8b9e4b1a 319 DebugMessage = string.Format("{0} memberIndex={1} first SetupDiGetDeviceInterfaceDetail ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 320 SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero);
darienf 3:36de8b9e4b1a 321 //tempLastError = GetLastError();
darienf 3:36de8b9e4b1a 322 //if (tempLastError != ERROR_INSUFFICIENT_BUFFER) // ERROR_INSUFFICIENT_BUFFER is expected on this first call
darienf 3:36de8b9e4b1a 323 // break;
darienf 3:36de8b9e4b1a 324 //FIXME add error check
darienf 3:36de8b9e4b1a 325
darienf 3:36de8b9e4b1a 326 // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
darienf 3:36de8b9e4b1a 327 DebugMessage = string.Format("{0} memberIndex={1} Marshal.AllocHGlobal(bufferSize) ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 328 deviceInterfaceDetailDataBuffer = Marshal.AllocHGlobal(bufferSize);
darienf 3:36de8b9e4b1a 329 // Returns a System.IntPtr pointer to the newly allocated global heap memory.
darienf 3:36de8b9e4b1a 330 // This memory must be released using the Marshal.FreeHGlobal method.
darienf 3:36de8b9e4b1a 331 // Marshal.AllocHGlobal(numBytes) could throw OutOfMemoryException ?
darienf 3:36de8b9e4b1a 332
darienf 3:36de8b9e4b1a 333 // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems.
darienf 3:36de8b9e4b1a 334 DebugMessage = string.Format("{0} memberIndex={1} Marshal.WriteInt32 ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 335 Marshal.WriteInt32(deviceInterfaceDetailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
darienf 3:36de8b9e4b1a 336
darienf 3:36de8b9e4b1a 337 // Call SetupDiGetDeviceInterfaceDetail again.
darienf 3:36de8b9e4b1a 338 // This time, pass a pointer to DetailDataBuffer and the returned required buffer size.
darienf 3:36de8b9e4b1a 339 DebugMessage = string.Format("{0} memberIndex={1} second SetupDiGetDeviceInterfaceDetail ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 340 if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, deviceInterfaceDetailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero))
darienf 3:36de8b9e4b1a 341 break;
darienf 3:36de8b9e4b1a 342
darienf 3:36de8b9e4b1a 343 // Skip over cbsize (4 bytes) to get the address of the devicePathName.
darienf 3:36de8b9e4b1a 344 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message
darienf 3:36de8b9e4b1a 345 DebugMessage = string.Format("{0} memberIndex={1} IntPtr pDevicePathName = IntPtr.Add(deviceInterfaceDetailDataBuffer, 4); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 346 IntPtr pDevicePathName = IntPtr.Add(deviceInterfaceDetailDataBuffer, 4);
darienf 3:36de8b9e4b1a 347 // DebugMessage = string.Format("{0} memberIndex={1} new IntPtr(deviceInterfaceDetailDataBuffer.ToInt32() + 4); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 348 // BAD CODE. IntPtr pDevicePathName = new IntPtr(deviceInterfaceDetailDataBuffer.ToInt32() + 4);
darienf 3:36de8b9e4b1a 349 // BAD CODE. assumes the pointer is a 32-bit address, intermittently fails from 64-bit matlab client.
darienf 3:36de8b9e4b1a 350
darienf 3:36de8b9e4b1a 351 // Get the String containing the devicePathName.
darienf 3:36de8b9e4b1a 352 DebugMessage = string.Format("{0} memberIndex={1} Marshal.PtrToStringAuto(pDevicePathName); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 353 string tempPathName = Marshal.PtrToStringAuto(pDevicePathName);
darienf 3:36de8b9e4b1a 354
darienf 3:36de8b9e4b1a 355 // match any device pathname that contains deviceID (case-insensitive match) "Vid_{0:x4}&Pid_{1:x4}"
darienf 3:36de8b9e4b1a 356 DebugMessage = string.Format("{0} memberIndex={1} if (tempPathName.ToLower().IndexOf(deviceID.ToLower()) != -1) ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 357 if (tempPathName.ToLower().IndexOf(deviceID.ToLower()) != -1)
darienf 3:36de8b9e4b1a 358 {
darienf 3:36de8b9e4b1a 359 DebugMessage = string.Format("{0} memberIndex={1} desiredHIDPathNameArray.Add(tempPathName); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 360 desiredHIDPathNameArray.Add(tempPathName);
darienf 3:36de8b9e4b1a 361 }
darienf 3:36de8b9e4b1a 362
darienf 3:36de8b9e4b1a 363 DebugMessage = string.Format("{0} memberIndex={1} memberIndex = memberIndex + 1; ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 364
darienf 3:36de8b9e4b1a 365 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message
darienf 3:36de8b9e4b1a 366 // why didn't they call Marshal.FreeHGlobal here, inside the while loop? Isn't this a memory leak?
darienf 3:36de8b9e4b1a 367 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 368 if (deviceInterfaceDetailDataBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 369 {
darienf 3:36de8b9e4b1a 370 Marshal.FreeHGlobal(deviceInterfaceDetailDataBuffer);
darienf 3:36de8b9e4b1a 371 deviceInterfaceDetailDataBuffer = IntPtr.Zero;
darienf 3:36de8b9e4b1a 372 }
darienf 3:36de8b9e4b1a 373
darienf 3:36de8b9e4b1a 374 memberIndex = memberIndex + 1;
darienf 3:36de8b9e4b1a 375 }
darienf 3:36de8b9e4b1a 376 #if DEBUG
darienf 3:36de8b9e4b1a 377 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 378 if (deviceInterfaceDetailDataBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 379 Marshal.FreeHGlobal(deviceInterfaceDetailDataBuffer);
darienf 3:36de8b9e4b1a 380
darienf 3:36de8b9e4b1a 381 if (deviceInfoSet != IntPtr.Zero)
darienf 3:36de8b9e4b1a 382 SetupDiDestroyDeviceInfoList(deviceInfoSet);
darienf 3:36de8b9e4b1a 383 #else
darienf 3:36de8b9e4b1a 384 }
darienf 3:36de8b9e4b1a 385 catch (Exception ex)
darienf 3:36de8b9e4b1a 386 {
darienf 3:36de8b9e4b1a 387 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 388 }
darienf 3:36de8b9e4b1a 389 finally
darienf 3:36de8b9e4b1a 390 {
darienf 3:36de8b9e4b1a 391 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 392 if (deviceInterfaceDetailDataBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 393 Marshal.FreeHGlobal(deviceInterfaceDetailDataBuffer);
darienf 3:36de8b9e4b1a 394
darienf 3:36de8b9e4b1a 395 if (deviceInfoSet != IntPtr.Zero)
darienf 3:36de8b9e4b1a 396 SetupDiDestroyDeviceInfoList(deviceInfoSet);
darienf 3:36de8b9e4b1a 397 }
darienf 3:36de8b9e4b1a 398 #endif
darienf 3:36de8b9e4b1a 399 DebugMessage = string.Format("{0} exited", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 400 }
darienf 3:36de8b9e4b1a 401
darienf 3:36de8b9e4b1a 402 private void FindAllHIDPathNamesFromGuid(System.Guid myGuid, ArrayList allHIDPathNameArray)
darienf 3:36de8b9e4b1a 403 {
darienf 3:36de8b9e4b1a 404 DebugMessage = string.Format("{0} entered", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 405 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 406 // But I never see this kind of exception thrown from within the C# GUI.
darienf 3:36de8b9e4b1a 407 // HID.findHIDs() still raises the exception in Matlab,
darienf 3:36de8b9e4b1a 408 // Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 409 Int32 memberIndex = 0;
darienf 3:36de8b9e4b1a 410 Int32 bufferSize = 0;
darienf 3:36de8b9e4b1a 411 IntPtr deviceInfoSet = new System.IntPtr();
darienf 3:36de8b9e4b1a 412 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
darienf 3:36de8b9e4b1a 413 IntPtr deviceInterfaceDetailDataBuffer = IntPtr.Zero;
darienf 3:36de8b9e4b1a 414
darienf 3:36de8b9e4b1a 415 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 416 // diagnostic: trying to avoid "Arithmetic overflow" from matlab. Limit the number of HID devices to be checked.
darienf 3:36de8b9e4b1a 417 const int memberIndexLimit = 100;
darienf 3:36de8b9e4b1a 418
darienf 3:36de8b9e4b1a 419
darienf 3:36de8b9e4b1a 420 #if DEBUG
darienf 3:36de8b9e4b1a 421 #else
darienf 3:36de8b9e4b1a 422 try
darienf 3:36de8b9e4b1a 423 {
darienf 3:36de8b9e4b1a 424 #endif
darienf 3:36de8b9e4b1a 425 DebugMessage = string.Format("{0} first deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 426 deviceInfoSet = SetupDiGetClassDevs(ref myGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
darienf 3:36de8b9e4b1a 427
darienf 3:36de8b9e4b1a 428 memberIndex = 0;
darienf 3:36de8b9e4b1a 429
darienf 3:36de8b9e4b1a 430 // The cbSize element of the DeviceInterfaceData structure must be set to the structure's size in bytes.
darienf 3:36de8b9e4b1a 431 // The size is 28 bytes for 32-bit code and 32 bits for 64-bit code.
darienf 3:36de8b9e4b1a 432 DeviceInterfaceData.cbSize = Marshal.SizeOf(DeviceInterfaceData);
darienf 3:36de8b9e4b1a 433
darienf 3:36de8b9e4b1a 434 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 435 while (memberIndex < memberIndexLimit)
darienf 3:36de8b9e4b1a 436 {
darienf 3:36de8b9e4b1a 437 DebugMessage = string.Format("{0} memberIndex={1} first SetupDiEnumDeviceInterfaces ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 438 if (!SetupDiEnumDeviceInterfaces(deviceInfoSet, IntPtr.Zero, ref myGuid, memberIndex, ref DeviceInterfaceData))
darienf 3:36de8b9e4b1a 439 {
darienf 3:36de8b9e4b1a 440 break;
darienf 3:36de8b9e4b1a 441 }
darienf 3:36de8b9e4b1a 442
darienf 3:36de8b9e4b1a 443 DebugMessage = string.Format("{0} memberIndex={1} first SetupDiGetDeviceInterfaceDetail ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 444 SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, IntPtr.Zero, 0, ref bufferSize, IntPtr.Zero);
darienf 3:36de8b9e4b1a 445
darienf 3:36de8b9e4b1a 446 // Allocate memory for the SP_DEVICE_INTERFACE_DETAIL_DATA structure using the returned buffer size.
darienf 3:36de8b9e4b1a 447 DebugMessage = string.Format("{0} memberIndex={1} Marshal.AllocHGlobal(bufferSize) ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 448 deviceInterfaceDetailDataBuffer = Marshal.AllocHGlobal(bufferSize);
darienf 3:36de8b9e4b1a 449
darienf 3:36de8b9e4b1a 450 // Store cbSize in the first bytes of the array. The number of bytes varies with 32- and 64-bit systems.
darienf 3:36de8b9e4b1a 451 DebugMessage = string.Format("{0} memberIndex={1} Marshal.WriteInt32 ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 452 Marshal.WriteInt32(deviceInterfaceDetailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);
darienf 3:36de8b9e4b1a 453
darienf 3:36de8b9e4b1a 454 // Call SetupDiGetDeviceInterfaceDetail again.
darienf 3:36de8b9e4b1a 455 // This time, pass a pointer to deviceInterfaceDetailDataBuffer and the returned required buffer size.
darienf 3:36de8b9e4b1a 456 DebugMessage = string.Format("{0} memberIndex={1} second SetupDiGetDeviceInterfaceDetail ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 457 if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, ref DeviceInterfaceData, deviceInterfaceDetailDataBuffer, bufferSize, ref bufferSize, IntPtr.Zero))
darienf 3:36de8b9e4b1a 458 break;
darienf 3:36de8b9e4b1a 459
darienf 3:36de8b9e4b1a 460 // Skip over cbsize (4 bytes) to get the address of the devicePathName.
darienf 3:36de8b9e4b1a 461 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message
darienf 3:36de8b9e4b1a 462 DebugMessage = string.Format("{0} memberIndex={1} IntPtr pDevicePathName = IntPtr.Add(deviceInterfaceDetailDataBuffer, 4); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 463 // example: IntPtr right way to add an offset (portable to 64-bit clients)
darienf 3:36de8b9e4b1a 464 IntPtr pDevicePathName = IntPtr.Add(deviceInterfaceDetailDataBuffer, 4);
darienf 3:36de8b9e4b1a 465 // DebugMessage = string.Format("{0} memberIndex={1} IntPtr pDevicePathName = new IntPtr(deviceInterfaceDetailDataBuffer.ToInt32() + 4); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 466 // BAD CODE. IntPtr pDevicePathName = new IntPtr(deviceInterfaceDetailDataBuffer.ToInt32() + 4);
darienf 3:36de8b9e4b1a 467 // BAD CODE. assumes the pointer is a 32-bit address, intermittently fails from 64-bit matlab client.
darienf 3:36de8b9e4b1a 468
darienf 3:36de8b9e4b1a 469 // Get the String containing the devicePathName.
darienf 3:36de8b9e4b1a 470 DebugMessage = string.Format("{0} memberIndex={1} Marshal.PtrToStringAuto(pDevicePathName); ", System.Reflection.MethodInfo.GetCurrentMethod().Name, memberIndex);
darienf 3:36de8b9e4b1a 471 allHIDPathNameArray.Add(Marshal.PtrToStringAuto(pDevicePathName));
darienf 3:36de8b9e4b1a 472
darienf 3:36de8b9e4b1a 473 // VERIFY: https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message
darienf 3:36de8b9e4b1a 474 // why didn't they call Marshal.FreeHGlobal here, inside the while loop? Isn't this a memory leak?
darienf 3:36de8b9e4b1a 475 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 476 if (deviceInterfaceDetailDataBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 477 {
darienf 3:36de8b9e4b1a 478 Marshal.FreeHGlobal(deviceInterfaceDetailDataBuffer);
darienf 3:36de8b9e4b1a 479 deviceInterfaceDetailDataBuffer = IntPtr.Zero;
darienf 3:36de8b9e4b1a 480 }
darienf 3:36de8b9e4b1a 481
darienf 3:36de8b9e4b1a 482 memberIndex = memberIndex + 1;
darienf 3:36de8b9e4b1a 483 }
darienf 3:36de8b9e4b1a 484 #if DEBUG
darienf 3:36de8b9e4b1a 485 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 486 if (deviceInterfaceDetailDataBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 487 Marshal.FreeHGlobal(deviceInterfaceDetailDataBuffer);
darienf 3:36de8b9e4b1a 488
darienf 3:36de8b9e4b1a 489 if (deviceInfoSet != IntPtr.Zero)
darienf 3:36de8b9e4b1a 490 SetupDiDestroyDeviceInfoList(deviceInfoSet);
darienf 3:36de8b9e4b1a 491 #else
darienf 3:36de8b9e4b1a 492 }
darienf 3:36de8b9e4b1a 493 catch (Exception ex)
darienf 3:36de8b9e4b1a 494 {
darienf 3:36de8b9e4b1a 495 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 496 }
darienf 3:36de8b9e4b1a 497 finally
darienf 3:36de8b9e4b1a 498 {
darienf 3:36de8b9e4b1a 499 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 500 if (deviceInterfaceDetailDataBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 501 Marshal.FreeHGlobal(deviceInterfaceDetailDataBuffer);
darienf 3:36de8b9e4b1a 502
darienf 3:36de8b9e4b1a 503 if (deviceInfoSet != IntPtr.Zero)
darienf 3:36de8b9e4b1a 504 SetupDiDestroyDeviceInfoList(deviceInfoSet);
darienf 3:36de8b9e4b1a 505 }
darienf 3:36de8b9e4b1a 506 #endif
darienf 3:36de8b9e4b1a 507 DebugMessage = string.Format("{0} exited", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 508 }
darienf 3:36de8b9e4b1a 509
darienf 3:36de8b9e4b1a 510 public bool isConnected()
darienf 3:36de8b9e4b1a 511 {
darienf 3:36de8b9e4b1a 512 try
darienf 3:36de8b9e4b1a 513 {
darienf 3:36de8b9e4b1a 514 return desiredHIDPathNameArray.Count != 0 ? true : false;
darienf 3:36de8b9e4b1a 515 }
darienf 3:36de8b9e4b1a 516 catch (Exception ex)
darienf 3:36de8b9e4b1a 517 {
darienf 3:36de8b9e4b1a 518 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 519 }
darienf 3:36de8b9e4b1a 520 }
darienf 3:36de8b9e4b1a 521
darienf 3:36de8b9e4b1a 522
darienf 3:36de8b9e4b1a 523 /// <summary>
darienf 3:36de8b9e4b1a 524 /// Called when a WM_DEVICECHANGE message has arrived,
darienf 3:36de8b9e4b1a 525 /// indicating that a device has been attached or removed.
darienf 3:36de8b9e4b1a 526 ///
darienf 3:36de8b9e4b1a 527 /// </summary>
darienf 3:36de8b9e4b1a 528 /// <param name="m"> a message with information about the device </param>
darienf 3:36de8b9e4b1a 529 /// <returns>true on HID device arrival or remove complete</returns>
darienf 3:36de8b9e4b1a 530 public bool HandleWMDeviceChangeMessage(Message m)
darienf 3:36de8b9e4b1a 531 {
darienf 3:36de8b9e4b1a 532 // Example code:
darienf 3:36de8b9e4b1a 533 //
darienf 3:36de8b9e4b1a 534 // <code>
darienf 3:36de8b9e4b1a 535 // protected override void WndProc(ref Message m)
darienf 3:36de8b9e4b1a 536 // {
darienf 3:36de8b9e4b1a 537 // if (myHID != null)
darienf 3:36de8b9e4b1a 538 // {
darienf 3:36de8b9e4b1a 539 // if (myHID.HandleWMDeviceChangeMessage(m) /* m.Msg == HID.WM_DEVICECHANGE */ )
darienf 3:36de8b9e4b1a 540 // {
darienf 3:36de8b9e4b1a 541 // // optional: handle newly arrived connection or surprise disconnect
darienf 3:36de8b9e4b1a 542 // }
darienf 3:36de8b9e4b1a 543 // }
darienf 3:36de8b9e4b1a 544 // // Let the base form process the message.
darienf 3:36de8b9e4b1a 545 // base.WndProc(ref m);
darienf 3:36de8b9e4b1a 546 // }
darienf 3:36de8b9e4b1a 547 // </code>
darienf 3:36de8b9e4b1a 548 //
darienf 3:36de8b9e4b1a 549 // https://jira.maxim-ic.com/browse/OS24EVK-59 WndProc if HID.WM_DEVICECHANGE do HID.OnDeviceChange(Message m)
darienf 3:36de8b9e4b1a 550 try
darienf 3:36de8b9e4b1a 551 {
darienf 3:36de8b9e4b1a 552 if (m.Msg == HID.WM_DEVICECHANGE)
darienf 3:36de8b9e4b1a 553 {
darienf 3:36de8b9e4b1a 554 //if ((int)m.WParam == HID.DBT_DEVNODES_CHANGED) //this always occurs when any USB device is attached/detached. Use this if not registering for device notifications.
darienf 3:36de8b9e4b1a 555 if (
darienf 3:36de8b9e4b1a 556 ( m.WParam.ToInt32() == HID.DBT_DEVICEARRIVAL
darienf 3:36de8b9e4b1a 557 || m.WParam.ToInt32() == HID.DBT_DEVICEREMOVECOMPLETE
darienf 3:36de8b9e4b1a 558 )
darienf 3:36de8b9e4b1a 559 &&
darienf 3:36de8b9e4b1a 560 (m.LParam.ToInt32() != 0)
darienf 3:36de8b9e4b1a 561 &&
darienf 3:36de8b9e4b1a 562 DeviceIDMatch(m)
darienf 3:36de8b9e4b1a 563 )
darienf 3:36de8b9e4b1a 564 {
darienf 3:36de8b9e4b1a 565 closeHIDhandles();
darienf 3:36de8b9e4b1a 566 findHIDs();
darienf 3:36de8b9e4b1a 567 // cboEVB_init();
darienf 3:36de8b9e4b1a 568 return true;
darienf 3:36de8b9e4b1a 569 }
darienf 3:36de8b9e4b1a 570 }
darienf 3:36de8b9e4b1a 571 return false;
darienf 3:36de8b9e4b1a 572 }
darienf 3:36de8b9e4b1a 573 catch (Exception ex)
darienf 3:36de8b9e4b1a 574 {
darienf 3:36de8b9e4b1a 575 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 576 }
darienf 3:36de8b9e4b1a 577 }
darienf 3:36de8b9e4b1a 578
darienf 3:36de8b9e4b1a 579 /// <summary>
darienf 3:36de8b9e4b1a 580 /// findHIDs() called upon startup or if a desired HID has been inserted or removed
darienf 3:36de8b9e4b1a 581 /// </summary>
darienf 3:36de8b9e4b1a 582 public void findHIDs()
darienf 3:36de8b9e4b1a 583 {
darienf 3:36de8b9e4b1a 584 DebugMessage = string.Format("{0} entered", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 585 ArrayList allHIDPathNameArray = new ArrayList();
darienf 3:36de8b9e4b1a 586 System.Guid hidGuid = new System.Guid();
darienf 3:36de8b9e4b1a 587
darienf 3:36de8b9e4b1a 588 // https://jira.maxim-ic.com/browse/OS24EVK-59 (intermittent) Matlab Exception Message: Arithmetic operation resulted in an overflow.
darienf 3:36de8b9e4b1a 589 #if DEBUG
darienf 3:36de8b9e4b1a 590 #else
darienf 3:36de8b9e4b1a 591 try
darienf 3:36de8b9e4b1a 592 {
darienf 3:36de8b9e4b1a 593 #endif
darienf 3:36de8b9e4b1a 594 HidD_GetHidGuid(ref hidGuid);
darienf 3:36de8b9e4b1a 595 // FindDesiredHIDPathNamesFromGuid() builds desiredHIDPathNameArray which is a list of all desired HIDs in the system
darienf 3:36de8b9e4b1a 596 // desiredHIDPathNameArray is a global list and is used to maintain the order of desired HIDs in the selection list.
darienf 3:36de8b9e4b1a 597 // USB ports have different priorities, and the user could have attached the first desired HID to a lower priority port.
darienf 3:36de8b9e4b1a 598 // Hence, when another desired HID is attached to a higher priority port, it will come earlier in allHIDPathNameArray, but it will be maintained in the same attachment order in desiredHIDPathNameArray.
darienf 3:36de8b9e4b1a 599 // Note that desiredHIDPathNameArray is only appended to or deleted from; it is never recreated in whole.
darienf 3:36de8b9e4b1a 600 // FIXME desiredHIDPathNameArray will get duplicate pathnames for desired HIDs that were already attached, but these will be removed by openHIDhandles() since they're in allHIDPathNameArray only once.
darienf 3:36de8b9e4b1a 601 // These duplicates pathnames are appended after the initial list, so they won't affect order.
darienf 3:36de8b9e4b1a 602 FindDesiredHIDPathNamesFromGuid(hidGuid);
darienf 3:36de8b9e4b1a 603 // FindAllHIDPathNamesFromGuid() builds allHIDPathNameArray which is a list of all HIDs in the system. It is recreated every time a desired HID is attached or removed.
darienf 3:36de8b9e4b1a 604 FindAllHIDPathNamesFromGuid(hidGuid, allHIDPathNameArray);
darienf 3:36de8b9e4b1a 605 // openHIDhandles() gets handles for all desired HIDs
darienf 3:36de8b9e4b1a 606 // openHIDhandles() loops through all attached HIDs and checks for a match of each item in desiredHIDPathNameArray. This maintains the attachement order.
darienf 3:36de8b9e4b1a 607 // If a previously attached HID has been removed, it won't be found in allHIDPathNameArray and it will be removed from desiredHIDPathNameArray.
darienf 3:36de8b9e4b1a 608 openHIDhandles(allHIDPathNameArray);
darienf 3:36de8b9e4b1a 609 if (desiredHIDPathNameArray.Count != 0)
darienf 3:36de8b9e4b1a 610 {
darienf 3:36de8b9e4b1a 611 prepareForOverlappedTransfer();
darienf 3:36de8b9e4b1a 612 }
darienf 3:36de8b9e4b1a 613 #if DEBUG
darienf 3:36de8b9e4b1a 614 #else
darienf 3:36de8b9e4b1a 615 }
darienf 3:36de8b9e4b1a 616 catch (Exception ex)
darienf 3:36de8b9e4b1a 617 {
darienf 3:36de8b9e4b1a 618 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 619 }
darienf 3:36de8b9e4b1a 620 #endif
darienf 3:36de8b9e4b1a 621 DebugMessage = string.Format("{0} exited", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 622 }
darienf 3:36de8b9e4b1a 623
darienf 3:36de8b9e4b1a 624 private void openHIDhandles(ArrayList allHIDPathNameArray)
darienf 3:36de8b9e4b1a 625 {
darienf 3:36de8b9e4b1a 626 DebugMessage = string.Format("{0} entered", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 627 int desiredHIDPathNameArrayCounter;
darienf 3:36de8b9e4b1a 628 int allHIDPathNameArrayCounter;
darienf 3:36de8b9e4b1a 629 bool found_installed_device;
darienf 3:36de8b9e4b1a 630 try
darienf 3:36de8b9e4b1a 631 {
darienf 3:36de8b9e4b1a 632 desiredHIDPathNameArrayCounter = 0;
darienf 3:36de8b9e4b1a 633 while (desiredHIDPathNameArrayCounter < desiredHIDPathNameArray.Count) // count will change if a previously installed device has been removed, so don't use a for loop
darienf 3:36de8b9e4b1a 634 {
darienf 3:36de8b9e4b1a 635 found_installed_device = false;
darienf 3:36de8b9e4b1a 636 allHIDPathNameArrayCounter = 0;
darienf 3:36de8b9e4b1a 637 while (allHIDPathNameArrayCounter < allHIDPathNameArray.Count)
darienf 3:36de8b9e4b1a 638 {
darienf 3:36de8b9e4b1a 639 if ((string)allHIDPathNameArray[allHIDPathNameArrayCounter] == (string)desiredHIDPathNameArray[desiredHIDPathNameArrayCounter])
darienf 3:36de8b9e4b1a 640 {
darienf 3:36de8b9e4b1a 641 writeHandle = FileIO.CreateFile((string)desiredHIDPathNameArray[desiredHIDPathNameArrayCounter], FileIO.GENERIC_READ | FileIO.GENERIC_WRITE, FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, 0, 0);
darienf 3:36de8b9e4b1a 642 if (!(writeHandle.IsInvalid))
darienf 3:36de8b9e4b1a 643 {
darienf 3:36de8b9e4b1a 644 readHandle = FileIO.CreateFile((string)desiredHIDPathNameArray[desiredHIDPathNameArrayCounter], FileIO.GENERIC_READ | FileIO.GENERIC_WRITE, FileIO.FILE_SHARE_READ | FileIO.FILE_SHARE_WRITE, IntPtr.Zero, FileIO.OPEN_EXISTING, FileIO.FILE_FLAG_OVERLAPPED, 0);
darienf 3:36de8b9e4b1a 645 if (!(readHandle.IsInvalid))
darienf 3:36de8b9e4b1a 646 {
darienf 3:36de8b9e4b1a 647 writeHandleArray.Add(writeHandle);
darienf 3:36de8b9e4b1a 648 readHandleArray.Add(readHandle);
darienf 3:36de8b9e4b1a 649 allHIDPathNameArray.RemoveAt(allHIDPathNameArrayCounter); // remove it so we don't repeatedly add it when we check for new devices (after we finish checking for previously installed devices)
darienf 3:36de8b9e4b1a 650 found_installed_device = true;
darienf 3:36de8b9e4b1a 651 }
darienf 3:36de8b9e4b1a 652 else
darienf 3:36de8b9e4b1a 653 {
darienf 3:36de8b9e4b1a 654 writeHandle.Close();
darienf 3:36de8b9e4b1a 655 writeHandle = null;
darienf 3:36de8b9e4b1a 656 readHandle = null;
darienf 3:36de8b9e4b1a 657 }
darienf 3:36de8b9e4b1a 658 }
darienf 3:36de8b9e4b1a 659 else
darienf 3:36de8b9e4b1a 660 {
darienf 3:36de8b9e4b1a 661 writeHandle = null;
darienf 3:36de8b9e4b1a 662 readHandle = null;
darienf 3:36de8b9e4b1a 663 }
darienf 3:36de8b9e4b1a 664 break;
darienf 3:36de8b9e4b1a 665 }
darienf 3:36de8b9e4b1a 666 allHIDPathNameArrayCounter++;
darienf 3:36de8b9e4b1a 667 }
darienf 3:36de8b9e4b1a 668 if (found_installed_device == false) // no match in all allHIDPathNameArray elements; the device has been removed so remove its pathname from desiredHIDPathNameArray. Don't use counter at max count to check if not found, since max count can change.
darienf 3:36de8b9e4b1a 669 desiredHIDPathNameArray.RemoveAt(desiredHIDPathNameArrayCounter); // decrements count by 1; don't increment desiredHIDPathNameArrayCounter
darienf 3:36de8b9e4b1a 670 else
darienf 3:36de8b9e4b1a 671 desiredHIDPathNameArrayCounter++;
darienf 3:36de8b9e4b1a 672 }
darienf 3:36de8b9e4b1a 673 }
darienf 3:36de8b9e4b1a 674 catch (Exception ex)
darienf 3:36de8b9e4b1a 675 {
darienf 3:36de8b9e4b1a 676 DebugMessage = string.Format("{0} exception {1}", System.Reflection.MethodInfo.GetCurrentMethod().Name, ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 677 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 678 }
darienf 3:36de8b9e4b1a 679 DebugMessage = string.Format("{0} exited", System.Reflection.MethodInfo.GetCurrentMethod().Name);
darienf 3:36de8b9e4b1a 680 }
darienf 3:36de8b9e4b1a 681
darienf 3:36de8b9e4b1a 682 public void closeHIDhandles()
darienf 3:36de8b9e4b1a 683 {
darienf 3:36de8b9e4b1a 684 try
darienf 3:36de8b9e4b1a 685 {
darienf 3:36de8b9e4b1a 686 if (desiredHIDPathNameArray.Count != 0)
darienf 3:36de8b9e4b1a 687 {
darienf 3:36de8b9e4b1a 688 foreach (Object obj in writeHandleArray)
darienf 3:36de8b9e4b1a 689 ((SafeFileHandle)obj).Close();
darienf 3:36de8b9e4b1a 690 writeHandleArray.Clear();
darienf 3:36de8b9e4b1a 691 writeHandle = null;
darienf 3:36de8b9e4b1a 692 foreach (Object obj in readHandleArray)
darienf 3:36de8b9e4b1a 693 ((SafeFileHandle)obj).Close();
darienf 3:36de8b9e4b1a 694 readHandleArray.Clear();
darienf 3:36de8b9e4b1a 695 readHandle = null;
darienf 3:36de8b9e4b1a 696 }
darienf 3:36de8b9e4b1a 697 }
darienf 3:36de8b9e4b1a 698 catch (Exception ex)
darienf 3:36de8b9e4b1a 699 {
darienf 3:36de8b9e4b1a 700 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 701 }
darienf 3:36de8b9e4b1a 702 }
darienf 3:36de8b9e4b1a 703
darienf 3:36de8b9e4b1a 704 private void prepareForOverlappedTransfer()
darienf 3:36de8b9e4b1a 705 {
darienf 3:36de8b9e4b1a 706 try
darienf 3:36de8b9e4b1a 707 {
darienf 3:36de8b9e4b1a 708 EventObject = FileIO.CreateEvent(IntPtr.Zero, false, false, String.Empty);
darienf 3:36de8b9e4b1a 709 managedOverlapped.OffsetLow = 0;
darienf 3:36de8b9e4b1a 710 managedOverlapped.OffsetHigh = 0;
darienf 3:36de8b9e4b1a 711 managedOverlapped.EventHandle = EventObject; // HIDOverlapped is the overlapped structure used in ReadFile; EventObject will be signaled upon completion of ReadFile
darienf 3:36de8b9e4b1a 712 nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(managedOverlapped));
darienf 3:36de8b9e4b1a 713 Marshal.StructureToPtr(managedOverlapped, nonManagedOverlapped, false);
darienf 3:36de8b9e4b1a 714
darienf 3:36de8b9e4b1a 715 nonManagedBuffer = Marshal.AllocHGlobal(REPORT_SIZE);
darienf 3:36de8b9e4b1a 716 }
darienf 3:36de8b9e4b1a 717 catch (Exception ex)
darienf 3:36de8b9e4b1a 718 {
darienf 3:36de8b9e4b1a 719 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 720 }
darienf 3:36de8b9e4b1a 721 }
darienf 3:36de8b9e4b1a 722
darienf 3:36de8b9e4b1a 723 public void FlushQueue()
darienf 3:36de8b9e4b1a 724 {
darienf 3:36de8b9e4b1a 725 try
darienf 3:36de8b9e4b1a 726 {
darienf 3:36de8b9e4b1a 727 if (writeHandle == null)
darienf 3:36de8b9e4b1a 728 {
darienf 3:36de8b9e4b1a 729 return;
darienf 3:36de8b9e4b1a 730 }
darienf 3:36de8b9e4b1a 731 if (readHandle == null)
darienf 3:36de8b9e4b1a 732 {
darienf 3:36de8b9e4b1a 733 return;
darienf 3:36de8b9e4b1a 734 }
darienf 3:36de8b9e4b1a 735
darienf 3:36de8b9e4b1a 736 HidD_FlushQueue(writeHandle);
darienf 3:36de8b9e4b1a 737 HidD_FlushQueue(readHandle);
darienf 3:36de8b9e4b1a 738 }
darienf 3:36de8b9e4b1a 739 catch
darienf 3:36de8b9e4b1a 740 {
darienf 3:36de8b9e4b1a 741 throw new Exception(new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 742 }
darienf 3:36de8b9e4b1a 743 }
darienf 3:36de8b9e4b1a 744
darienf 3:36de8b9e4b1a 745 public void writeReadHID()
darienf 3:36de8b9e4b1a 746 {
darienf 3:36de8b9e4b1a 747 try
darienf 3:36de8b9e4b1a 748 {
darienf 3:36de8b9e4b1a 749 if (writeHandle == null)
darienf 3:36de8b9e4b1a 750 {
darienf 3:36de8b9e4b1a 751 return;
darienf 3:36de8b9e4b1a 752 }
darienf 3:36de8b9e4b1a 753 if (readHandle == null)
darienf 3:36de8b9e4b1a 754 {
darienf 3:36de8b9e4b1a 755 return;
darienf 3:36de8b9e4b1a 756 }
darienf 3:36de8b9e4b1a 757
darienf 3:36de8b9e4b1a 758 writeHID();
darienf 3:36de8b9e4b1a 759 readHID();
darienf 3:36de8b9e4b1a 760 }
darienf 3:36de8b9e4b1a 761 catch (Exception ex)
darienf 3:36de8b9e4b1a 762 {
darienf 3:36de8b9e4b1a 763 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 764 }
darienf 3:36de8b9e4b1a 765 }
darienf 3:36de8b9e4b1a 766
darienf 3:36de8b9e4b1a 767 public void writeHID()
darienf 3:36de8b9e4b1a 768 {
darienf 3:36de8b9e4b1a 769 if (writeHandle == null)
darienf 3:36de8b9e4b1a 770 {
darienf 3:36de8b9e4b1a 771 return;
darienf 3:36de8b9e4b1a 772 }
darienf 3:36de8b9e4b1a 773 if (readHandle == null)
darienf 3:36de8b9e4b1a 774 {
darienf 3:36de8b9e4b1a 775 return;
darienf 3:36de8b9e4b1a 776 }
darienf 3:36de8b9e4b1a 777
darienf 3:36de8b9e4b1a 778 int BytesSucceed;
darienf 3:36de8b9e4b1a 779 bool api_status;
darienf 3:36de8b9e4b1a 780
darienf 3:36de8b9e4b1a 781 try
darienf 3:36de8b9e4b1a 782 {
darienf 3:36de8b9e4b1a 783 BytesSucceed = 0;
darienf 3:36de8b9e4b1a 784 Marshal.Copy(IOBuf, 0, nonManagedBuffer, REPORT_SIZE);
darienf 3:36de8b9e4b1a 785 api_status = FileIO.WriteFile(writeHandle, nonManagedBuffer, REPORT_SIZE, ref BytesSucceed, IntPtr.Zero);
darienf 3:36de8b9e4b1a 786 //endpoint in interrupt at uC occurs after this WriteFile call since the in data is ready and the host takes it; endpoint in interrupt does not occur after ReadFile call
darienf 3:36de8b9e4b1a 787
darienf 3:36de8b9e4b1a 788 if (api_status == false)
darienf 3:36de8b9e4b1a 789 {
darienf 3:36de8b9e4b1a 790 //MessageBox.Show(Err.LastDllError);
darienf 3:36de8b9e4b1a 791 throw new Exception(support.ResultOfAPICall("API WriteFile error"));
darienf 3:36de8b9e4b1a 792 }
darienf 3:36de8b9e4b1a 793 }
darienf 3:36de8b9e4b1a 794 catch (Exception ex)
darienf 3:36de8b9e4b1a 795 {
darienf 3:36de8b9e4b1a 796 throw new Exception(ex.Message + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 797 }
darienf 3:36de8b9e4b1a 798 }
darienf 3:36de8b9e4b1a 799
darienf 3:36de8b9e4b1a 800 public void readHID()
darienf 3:36de8b9e4b1a 801 {
darienf 3:36de8b9e4b1a 802 if (writeHandle == null)
darienf 3:36de8b9e4b1a 803 {
darienf 3:36de8b9e4b1a 804 return;
darienf 3:36de8b9e4b1a 805 }
darienf 3:36de8b9e4b1a 806 if (readHandle == null)
darienf 3:36de8b9e4b1a 807 {
darienf 3:36de8b9e4b1a 808 return;
darienf 3:36de8b9e4b1a 809 }
darienf 3:36de8b9e4b1a 810
darienf 3:36de8b9e4b1a 811 int BytesSucceed;
darienf 3:36de8b9e4b1a 812 bool api_status;
darienf 3:36de8b9e4b1a 813 int status;
darienf 3:36de8b9e4b1a 814
darienf 3:36de8b9e4b1a 815 try
darienf 3:36de8b9e4b1a 816 {
darienf 3:36de8b9e4b1a 817 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 818
darienf 3:36de8b9e4b1a 819 BytesSucceed = 0;
darienf 3:36de8b9e4b1a 820
darienf 3:36de8b9e4b1a 821 api_status = FileIO.ReadFile(readHandle, nonManagedBuffer, REPORT_SIZE, ref BytesSucceed, nonManagedOverlapped);
darienf 3:36de8b9e4b1a 822
darienf 3:36de8b9e4b1a 823 if (api_status == false)
darienf 3:36de8b9e4b1a 824 {
darienf 3:36de8b9e4b1a 825 //MsgBox(Err.LastDllError)
darienf 3:36de8b9e4b1a 826 status = FileIO.WaitForSingleObject(EventObject, IOtimeout);
darienf 3:36de8b9e4b1a 827
darienf 3:36de8b9e4b1a 828 if (status != FileIO.WAIT_OBJECT_0)
darienf 3:36de8b9e4b1a 829 {
darienf 3:36de8b9e4b1a 830 api_status = FileIO.CancelIo(readHandle);
darienf 3:36de8b9e4b1a 831 throw new Exception(support.ResultOfAPICall("API ReadFile error"));
darienf 3:36de8b9e4b1a 832 }
darienf 3:36de8b9e4b1a 833 FileIO.GetOverlappedResult(readHandle, nonManagedOverlapped, ref BytesSucceed, false);
darienf 3:36de8b9e4b1a 834 }
darienf 3:36de8b9e4b1a 835
darienf 3:36de8b9e4b1a 836 // TODO1: OS24EVK-57 2015-04-01 myHID.readHID2() needs to return result into IOBuf. But IOBuf = new byte[64], do we replace with IOBuf = new byte[128]? Does this affect readHID()?
darienf 3:36de8b9e4b1a 837 if (BytesSucceed > IOBuf.Length)
darienf 3:36de8b9e4b1a 838 {
darienf 3:36de8b9e4b1a 839 IOBuf = new byte[BytesSucceed];
darienf 3:36de8b9e4b1a 840 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 841 }
darienf 3:36de8b9e4b1a 842 Marshal.Copy(nonManagedBuffer, IOBuf, 0, BytesSucceed);
darienf 3:36de8b9e4b1a 843 }
darienf 3:36de8b9e4b1a 844 catch (Exception ex)
darienf 3:36de8b9e4b1a 845 {
darienf 3:36de8b9e4b1a 846 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 847 }
darienf 3:36de8b9e4b1a 848 }
darienf 3:36de8b9e4b1a 849
darienf 3:36de8b9e4b1a 850 public void readHID2() // this function is for testing multiple report read on a single ReadFile()
darienf 3:36de8b9e4b1a 851 {
darienf 3:36de8b9e4b1a 852 if (writeHandle == null)
darienf 3:36de8b9e4b1a 853 {
darienf 3:36de8b9e4b1a 854 return;
darienf 3:36de8b9e4b1a 855 }
darienf 3:36de8b9e4b1a 856 if (readHandle == null)
darienf 3:36de8b9e4b1a 857 {
darienf 3:36de8b9e4b1a 858 return;
darienf 3:36de8b9e4b1a 859 }
darienf 3:36de8b9e4b1a 860
darienf 3:36de8b9e4b1a 861 int BytesSucceed;
darienf 3:36de8b9e4b1a 862 bool api_status;
darienf 3:36de8b9e4b1a 863 int status;
darienf 3:36de8b9e4b1a 864
darienf 3:36de8b9e4b1a 865 try
darienf 3:36de8b9e4b1a 866 {
darienf 3:36de8b9e4b1a 867 int size = 128;
darienf 3:36de8b9e4b1a 868 //byte[] buf = new byte[size];
darienf 3:36de8b9e4b1a 869 IntPtr nonManagedBuf = Marshal.AllocHGlobal(size);
darienf 3:36de8b9e4b1a 870 //Array.Clear(buf, 0, size);
darienf 3:36de8b9e4b1a 871
darienf 3:36de8b9e4b1a 872 BytesSucceed = 0;
darienf 3:36de8b9e4b1a 873
darienf 3:36de8b9e4b1a 874 api_status = FileIO.ReadFile(readHandle, nonManagedBuf, size, ref BytesSucceed, nonManagedOverlapped);
darienf 3:36de8b9e4b1a 875
darienf 3:36de8b9e4b1a 876 if (api_status == false)
darienf 3:36de8b9e4b1a 877 {
darienf 3:36de8b9e4b1a 878 //MsgBox(Err.LastDllError)
darienf 3:36de8b9e4b1a 879 status = FileIO.WaitForSingleObject(EventObject, IOtimeout);
darienf 3:36de8b9e4b1a 880
darienf 3:36de8b9e4b1a 881 if (status != FileIO.WAIT_OBJECT_0)
darienf 3:36de8b9e4b1a 882 {
darienf 3:36de8b9e4b1a 883 api_status = FileIO.CancelIo(readHandle);
darienf 3:36de8b9e4b1a 884 throw new Exception(support.ResultOfAPICall("API ReadFile error"));
darienf 3:36de8b9e4b1a 885 }
darienf 3:36de8b9e4b1a 886 FileIO.GetOverlappedResult(readHandle, nonManagedOverlapped, ref BytesSucceed, false);
darienf 3:36de8b9e4b1a 887 }
darienf 3:36de8b9e4b1a 888
darienf 3:36de8b9e4b1a 889 // TODO1: OS24EVK-57 2015-04-01 myHID.readHID2() needs to return result into IOBuf. But IOBuf = new byte[64], do we replace with IOBuf = new byte[128]? Does this affect readHID()?
darienf 3:36de8b9e4b1a 890 if (BytesSucceed > IOBuf.Length)
darienf 3:36de8b9e4b1a 891 {
darienf 3:36de8b9e4b1a 892 IOBuf = new byte[BytesSucceed];
darienf 3:36de8b9e4b1a 893 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 894 }
darienf 3:36de8b9e4b1a 895 Marshal.Copy(nonManagedBuf, IOBuf, 0, BytesSucceed);
darienf 3:36de8b9e4b1a 896
darienf 3:36de8b9e4b1a 897 if (nonManagedBuf != IntPtr.Zero)
darienf 3:36de8b9e4b1a 898 Marshal.FreeHGlobal(nonManagedBuffer);
darienf 3:36de8b9e4b1a 899 }
darienf 3:36de8b9e4b1a 900 catch (Exception ex)
darienf 3:36de8b9e4b1a 901 {
darienf 3:36de8b9e4b1a 902 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 903 }
darienf 3:36de8b9e4b1a 904 }
darienf 3:36de8b9e4b1a 905 public void freeHeap()
darienf 3:36de8b9e4b1a 906 {
darienf 3:36de8b9e4b1a 907 try
darienf 3:36de8b9e4b1a 908 {
darienf 3:36de8b9e4b1a 909 if (nonManagedBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 910 Marshal.FreeHGlobal(nonManagedBuffer);
darienf 3:36de8b9e4b1a 911 if (nonManagedOverlapped != IntPtr.Zero)
darienf 3:36de8b9e4b1a 912 Marshal.FreeHGlobal(nonManagedOverlapped);
darienf 3:36de8b9e4b1a 913 }
darienf 3:36de8b9e4b1a 914 catch (Exception ex)
darienf 3:36de8b9e4b1a 915 {
darienf 3:36de8b9e4b1a 916 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 917 }
darienf 3:36de8b9e4b1a 918 }
darienf 3:36de8b9e4b1a 919
darienf 3:36de8b9e4b1a 920 /// <summary>
darienf 3:36de8b9e4b1a 921 /// Requests to receive a notification when a device is attached or removed.
darienf 3:36de8b9e4b1a 922 /// </summary>
darienf 3:36de8b9e4b1a 923 ///
darienf 3:36de8b9e4b1a 924 /// <param name="formHandle"> handle to the window that will receive device events. </param>
darienf 3:36de8b9e4b1a 925 /// <param name="classGuid"> device interface GUID. </param>
darienf 3:36de8b9e4b1a 926 /// <param name="deviceNotificationHandle"> returned device notification handle. </param>
darienf 3:36de8b9e4b1a 927 ///
darienf 3:36de8b9e4b1a 928 /// <returns>
darienf 3:36de8b9e4b1a 929 /// True on success.
darienf 3:36de8b9e4b1a 930 /// </returns>
darienf 3:36de8b9e4b1a 931 ///
darienf 3:36de8b9e4b1a 932 public Boolean RegisterForDeviceNotifications(IntPtr formHandle, Guid classGuid, ref IntPtr deviceNotificationHandle)
darienf 3:36de8b9e4b1a 933 {
darienf 3:36de8b9e4b1a 934 DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE();
darienf 3:36de8b9e4b1a 935 IntPtr devBroadcastDeviceInterfaceBuffer = IntPtr.Zero;
darienf 3:36de8b9e4b1a 936 Int32 size = 0;
darienf 3:36de8b9e4b1a 937
darienf 3:36de8b9e4b1a 938 try
darienf 3:36de8b9e4b1a 939 {
darienf 3:36de8b9e4b1a 940 size = Marshal.SizeOf(devBroadcastDeviceInterface);
darienf 3:36de8b9e4b1a 941 devBroadcastDeviceInterface.dbcc_size = size;
darienf 3:36de8b9e4b1a 942 devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
darienf 3:36de8b9e4b1a 943 devBroadcastDeviceInterface.dbcc_reserved = 0;
darienf 3:36de8b9e4b1a 944 devBroadcastDeviceInterface.dbcc_classguid = classGuid;
darienf 3:36de8b9e4b1a 945
darienf 3:36de8b9e4b1a 946 // Allocate memory for the buffer that holds the DEV_BROADCAST_DEVICEINTERFACE structure.
darienf 3:36de8b9e4b1a 947 devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size);
darienf 3:36de8b9e4b1a 948
darienf 3:36de8b9e4b1a 949 // Copy the DEV_BROADCAST_DEVICEINTERFACE structure to the buffer.
darienf 3:36de8b9e4b1a 950 // Set fDeleteOld True to prevent memory leaks.
darienf 3:36de8b9e4b1a 951 Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true);
darienf 3:36de8b9e4b1a 952
darienf 3:36de8b9e4b1a 953 // ***
darienf 3:36de8b9e4b1a 954 // API function
darienf 3:36de8b9e4b1a 955
darienf 3:36de8b9e4b1a 956 // summary
darienf 3:36de8b9e4b1a 957 // Request to receive notification messages when a device in an interface class
darienf 3:36de8b9e4b1a 958 // is attached or removed.
darienf 3:36de8b9e4b1a 959
darienf 3:36de8b9e4b1a 960 // parameters
darienf 3:36de8b9e4b1a 961 // Handle to the window that will receive device events.
darienf 3:36de8b9e4b1a 962 // Pointer to a DEV_BROADCAST_DEVICEINTERFACE to specify the type of
darienf 3:36de8b9e4b1a 963 // device to send notifications for.
darienf 3:36de8b9e4b1a 964 // DEVICE_NOTIFY_WINDOW_HANDLE indicates the handle is a window handle.
darienf 3:36de8b9e4b1a 965
darienf 3:36de8b9e4b1a 966 // Returns
darienf 3:36de8b9e4b1a 967 // Device notification handle or NULL on failure.
darienf 3:36de8b9e4b1a 968 // ***
darienf 3:36de8b9e4b1a 969
darienf 3:36de8b9e4b1a 970 deviceNotificationHandle = RegisterDeviceNotification(formHandle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE);
darienf 3:36de8b9e4b1a 971
darienf 3:36de8b9e4b1a 972 // Marshal data from the unmanaged block devBroadcastDeviceInterfaceBuffer to the managed object devBroadcastDeviceInterface
darienf 3:36de8b9e4b1a 973 // why?
darienf 3:36de8b9e4b1a 974 Marshal.PtrToStructure(devBroadcastDeviceInterfaceBuffer, devBroadcastDeviceInterface);
darienf 3:36de8b9e4b1a 975
darienf 3:36de8b9e4b1a 976 return deviceNotificationHandle.ToInt32() == IntPtr.Zero.ToInt32() ? false : true;
darienf 3:36de8b9e4b1a 977 }
darienf 3:36de8b9e4b1a 978 catch (Exception ex)
darienf 3:36de8b9e4b1a 979 {
darienf 3:36de8b9e4b1a 980 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 981 }
darienf 3:36de8b9e4b1a 982 finally
darienf 3:36de8b9e4b1a 983 {
darienf 3:36de8b9e4b1a 984 // Free the memory allocated previously by AllocHGlobal.
darienf 3:36de8b9e4b1a 985 if (devBroadcastDeviceInterfaceBuffer != IntPtr.Zero)
darienf 3:36de8b9e4b1a 986 Marshal.FreeHGlobal(devBroadcastDeviceInterfaceBuffer);
darienf 3:36de8b9e4b1a 987 }
darienf 3:36de8b9e4b1a 988 }
darienf 3:36de8b9e4b1a 989
darienf 3:36de8b9e4b1a 990 /// <summary>
darienf 3:36de8b9e4b1a 991 /// Requests to stop receiving notification messages when a device in an
darienf 3:36de8b9e4b1a 992 /// interface class is attached or removed.
darienf 3:36de8b9e4b1a 993 /// </summary>
darienf 3:36de8b9e4b1a 994 ///
darienf 3:36de8b9e4b1a 995 /// <param name="deviceNotificationHandle"> handle returned previously by
darienf 3:36de8b9e4b1a 996 /// RegisterDeviceNotification. </param>
darienf 3:36de8b9e4b1a 997
darienf 3:36de8b9e4b1a 998 public void StopReceivingDeviceNotifications(IntPtr deviceNotificationHandle)
darienf 3:36de8b9e4b1a 999 {
darienf 3:36de8b9e4b1a 1000 try
darienf 3:36de8b9e4b1a 1001 {
darienf 3:36de8b9e4b1a 1002 UnregisterDeviceNotification(deviceNotificationHandle);
darienf 3:36de8b9e4b1a 1003 }
darienf 3:36de8b9e4b1a 1004 catch (Exception ex)
darienf 3:36de8b9e4b1a 1005 {
darienf 3:36de8b9e4b1a 1006 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1007 }
darienf 3:36de8b9e4b1a 1008 }
darienf 3:36de8b9e4b1a 1009
darienf 3:36de8b9e4b1a 1010 public Boolean DeviceIDMatch(Message m)
darienf 3:36de8b9e4b1a 1011 {
darienf 3:36de8b9e4b1a 1012 Int32 stringSize;
darienf 3:36de8b9e4b1a 1013
darienf 3:36de8b9e4b1a 1014 try
darienf 3:36de8b9e4b1a 1015 {
darienf 3:36de8b9e4b1a 1016 DEV_BROADCAST_HDR devBroadcastHeader = new DEV_BROADCAST_HDR();
darienf 3:36de8b9e4b1a 1017 DEV_BROADCAST_DEVICEINTERFACE_1 devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE_1();
darienf 3:36de8b9e4b1a 1018
darienf 3:36de8b9e4b1a 1019 // The LParam parameter of Message is a pointer to a DEV_BROADCAST_HDR structure.
darienf 3:36de8b9e4b1a 1020 Marshal.PtrToStructure(m.LParam, devBroadcastHeader);
darienf 3:36de8b9e4b1a 1021 if ((devBroadcastHeader.dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
darienf 3:36de8b9e4b1a 1022 {
darienf 3:36de8b9e4b1a 1023 // The dbch_devicetype parameter indicates that the event applies to a device interface.
darienf 3:36de8b9e4b1a 1024 // So the structure in LParam is actually a DEV_BROADCAST_INTERFACE structure,
darienf 3:36de8b9e4b1a 1025 // which begins with a DEV_BROADCAST_HDR.
darienf 3:36de8b9e4b1a 1026
darienf 3:36de8b9e4b1a 1027 // Obtain the number of characters in dbch_name by subtracting the 32 bytes
darienf 3:36de8b9e4b1a 1028 // in the strucutre that are not part of dbch_name and dividing by 2 because there are
darienf 3:36de8b9e4b1a 1029 // 2 bytes per character.
darienf 3:36de8b9e4b1a 1030
darienf 3:36de8b9e4b1a 1031 stringSize = System.Convert.ToInt32((devBroadcastHeader.dbch_size - 32) / 2);
darienf 3:36de8b9e4b1a 1032
darienf 3:36de8b9e4b1a 1033 // The dbcc_name parameter of devBroadcastDeviceInterface contains the device name.
darienf 3:36de8b9e4b1a 1034 // Trim dbcc_name to match the size of the String.
darienf 3:36de8b9e4b1a 1035
darienf 3:36de8b9e4b1a 1036 devBroadcastDeviceInterface.dbcc_name = new Char[stringSize + 1];
darienf 3:36de8b9e4b1a 1037
darienf 3:36de8b9e4b1a 1038 // Marshal data from the unmanaged block pointed to by m.LParam
darienf 3:36de8b9e4b1a 1039 // to the managed object devBroadcastDeviceInterface.
darienf 3:36de8b9e4b1a 1040
darienf 3:36de8b9e4b1a 1041 Marshal.PtrToStructure(m.LParam, devBroadcastDeviceInterface);
darienf 3:36de8b9e4b1a 1042
darienf 3:36de8b9e4b1a 1043 // Store the device name in a String.
darienf 3:36de8b9e4b1a 1044
darienf 3:36de8b9e4b1a 1045 String DeviceNameString = new String(devBroadcastDeviceInterface.dbcc_name, 0, stringSize);
darienf 3:36de8b9e4b1a 1046
darienf 3:36de8b9e4b1a 1047 // Compare the name of the newly attached device with the name of the device
darienf 3:36de8b9e4b1a 1048 // the application is accessing (deviceID).
darienf 3:36de8b9e4b1a 1049 // Set ignorecase True.
darienf 3:36de8b9e4b1a 1050
darienf 3:36de8b9e4b1a 1051 return (DeviceNameString.ToLower().IndexOf(deviceID.ToLower()) == -1) ? false : true;
darienf 3:36de8b9e4b1a 1052 }
darienf 3:36de8b9e4b1a 1053 else
darienf 3:36de8b9e4b1a 1054 return false;
darienf 3:36de8b9e4b1a 1055 }
darienf 3:36de8b9e4b1a 1056 catch (Exception ex)
darienf 3:36de8b9e4b1a 1057 {
darienf 3:36de8b9e4b1a 1058 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1059 }
darienf 3:36de8b9e4b1a 1060 }
darienf 3:36de8b9e4b1a 1061
darienf 3:36de8b9e4b1a 1062 public void reportID()
darienf 3:36de8b9e4b1a 1063 {
darienf 3:36de8b9e4b1a 1064 try
darienf 3:36de8b9e4b1a 1065 {
darienf 3:36de8b9e4b1a 1066 if (explicit_report_id)
darienf 3:36de8b9e4b1a 1067 IOBuf[0] = SHORT_REPORT_ID; // explicit out report ID in HID's descriptor
darienf 3:36de8b9e4b1a 1068 else
darienf 3:36de8b9e4b1a 1069 IOBuf[0] = DEFAULT_REPORT_ID; // default report ID; this byte is dropped in transfer, so we don't really waste a byte transmitting it
darienf 3:36de8b9e4b1a 1070 }
darienf 3:36de8b9e4b1a 1071 catch (Exception ex)
darienf 3:36de8b9e4b1a 1072 {
darienf 3:36de8b9e4b1a 1073 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1074 }
darienf 3:36de8b9e4b1a 1075 }
darienf 3:36de8b9e4b1a 1076
darienf 3:36de8b9e4b1a 1077 public int readI2C(byte deviceAddress, byte numDataBytes, byte numRegBytes, byte[] readData, byte[] reg, bool ignoreNACK = false)
darienf 3:36de8b9e4b1a 1078 {
darienf 3:36de8b9e4b1a 1079 //readData is passed back to caller with the read data
darienf 3:36de8b9e4b1a 1080 int status;
darienf 3:36de8b9e4b1a 1081 int i;
darienf 3:36de8b9e4b1a 1082
darienf 3:36de8b9e4b1a 1083 try
darienf 3:36de8b9e4b1a 1084 {
darienf 3:36de8b9e4b1a 1085 if (numDataBytes > REPORT_SIZE - 2) {
darienf 3:36de8b9e4b1a 1086 throw new Exception("USB buffer overflow");
darienf 3:36de8b9e4b1a 1087 }
darienf 3:36de8b9e4b1a 1088
darienf 3:36de8b9e4b1a 1089 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in readI2C
darienf 3:36de8b9e4b1a 1090 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1091 FlushQueue();
darienf 3:36de8b9e4b1a 1092 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1093
darienf 3:36de8b9e4b1a 1094 reportID();
darienf 3:36de8b9e4b1a 1095 IOBuf[1] = 6; // I2C transaction -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1096 IOBuf[2] = (byte)(deviceAddress | 1); // set read bit
darienf 3:36de8b9e4b1a 1097 IOBuf[3] = numDataBytes;
darienf 3:36de8b9e4b1a 1098 IOBuf[4] = numRegBytes;
darienf 3:36de8b9e4b1a 1099 // TODO1: OS24EVK-57 HID readI2C no validation that numRegBytes == reg.Length ?
darienf 3:36de8b9e4b1a 1100 for (i = 0; i < numRegBytes; i++) {
darienf 3:36de8b9e4b1a 1101 IOBuf[i + 5] = reg[i];
darienf 3:36de8b9e4b1a 1102 }
darienf 3:36de8b9e4b1a 1103
darienf 3:36de8b9e4b1a 1104 writeHID();
darienf 3:36de8b9e4b1a 1105 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1106
darienf 3:36de8b9e4b1a 1107 status = checkNACK();
darienf 3:36de8b9e4b1a 1108
darienf 3:36de8b9e4b1a 1109 // checkNACK also reads the data, assuming NACK didn't occur
darienf 3:36de8b9e4b1a 1110 if (status == I2C_NACK_ERROR && ignoreNACK == false) {
darienf 3:36de8b9e4b1a 1111 throw new Exception("invalid I2C address");
darienf 3:36de8b9e4b1a 1112 }
darienf 3:36de8b9e4b1a 1113
darienf 3:36de8b9e4b1a 1114 for (i = 0; i < numDataBytes; i++) {
darienf 3:36de8b9e4b1a 1115 readData[i] = IOBuf[i + 2];
darienf 3:36de8b9e4b1a 1116 }
darienf 3:36de8b9e4b1a 1117
darienf 3:36de8b9e4b1a 1118 return status; // the caller will not need the return value if an exception is thrown
darienf 3:36de8b9e4b1a 1119 }
darienf 3:36de8b9e4b1a 1120 catch (Exception ex)
darienf 3:36de8b9e4b1a 1121 {
darienf 3:36de8b9e4b1a 1122 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1123 }
darienf 3:36de8b9e4b1a 1124 }
darienf 3:36de8b9e4b1a 1125
darienf 3:36de8b9e4b1a 1126 public void writeI2C(byte deviceAddress, byte numDataBytes, byte numRegBytes, byte[] data, byte[] reg, bool ignoreNACK = false)
darienf 3:36de8b9e4b1a 1127 {
darienf 3:36de8b9e4b1a 1128 int i;
darienf 3:36de8b9e4b1a 1129
darienf 3:36de8b9e4b1a 1130 try
darienf 3:36de8b9e4b1a 1131 {
darienf 3:36de8b9e4b1a 1132 if (numDataBytes > REPORT_SIZE - 5) {
darienf 3:36de8b9e4b1a 1133 throw new Exception("USB buffer overflow");
darienf 3:36de8b9e4b1a 1134 }
darienf 3:36de8b9e4b1a 1135
darienf 3:36de8b9e4b1a 1136 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in writeI2C
darienf 3:36de8b9e4b1a 1137 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1138 FlushQueue();
darienf 3:36de8b9e4b1a 1139 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1140
darienf 3:36de8b9e4b1a 1141 //send data to tell uC to do I2C read from slave
darienf 3:36de8b9e4b1a 1142 reportID();
darienf 3:36de8b9e4b1a 1143 IOBuf[1] = 6; // I2C transaction -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1144 IOBuf[2] = deviceAddress;
darienf 3:36de8b9e4b1a 1145 IOBuf[3] = numDataBytes;
darienf 3:36de8b9e4b1a 1146 IOBuf[4] = numRegBytes;
darienf 3:36de8b9e4b1a 1147 for (i = 0; i < numRegBytes; i++) {
darienf 3:36de8b9e4b1a 1148 IOBuf[i + 5] = reg[i];
darienf 3:36de8b9e4b1a 1149 }
darienf 3:36de8b9e4b1a 1150 for (i = 0; i < numDataBytes; i++) {
darienf 3:36de8b9e4b1a 1151 IOBuf[i + 5 + numRegBytes] = data[i];
darienf 3:36de8b9e4b1a 1152 }
darienf 3:36de8b9e4b1a 1153
darienf 3:36de8b9e4b1a 1154 writeHID();
darienf 3:36de8b9e4b1a 1155 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1156
darienf 3:36de8b9e4b1a 1157 if (checkNACK() == I2C_NACK_ERROR && ignoreNACK == false) {
darienf 3:36de8b9e4b1a 1158 throw new Exception("invalid I2C address");
darienf 3:36de8b9e4b1a 1159 }
darienf 3:36de8b9e4b1a 1160 }
darienf 3:36de8b9e4b1a 1161 catch (Exception ex)
darienf 3:36de8b9e4b1a 1162 {
darienf 3:36de8b9e4b1a 1163 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1164 }
darienf 3:36de8b9e4b1a 1165 }
darienf 3:36de8b9e4b1a 1166
darienf 3:36de8b9e4b1a 1167 private int checkNACK()
darienf 3:36de8b9e4b1a 1168 {
darienf 3:36de8b9e4b1a 1169 // Check if I2C write was really succesful or a NACK occurred, since this is independent of USB success
darienf 3:36de8b9e4b1a 1170 // This function also reads all the data from the report. If NACK occured, the data is invalid.
darienf 3:36de8b9e4b1a 1171 try
darienf 3:36de8b9e4b1a 1172 {
darienf 3:36de8b9e4b1a 1173 readHID();
darienf 3:36de8b9e4b1a 1174 return (IOBuf[1] == 0 ? I2C_SUCCESS : I2C_NACK_ERROR); // the caller will not need the return value if an exception is thrown
darienf 3:36de8b9e4b1a 1175 }
darienf 3:36de8b9e4b1a 1176 catch (Exception ex)
darienf 3:36de8b9e4b1a 1177 {
darienf 3:36de8b9e4b1a 1178 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1179 }
darienf 3:36de8b9e4b1a 1180 }
darienf 3:36de8b9e4b1a 1181
darienf 3:36de8b9e4b1a 1182 // only allows 2 byte data
darienf 3:36de8b9e4b1a 1183 public void setBitI2C(byte deviceAddress, int reg, byte range, int data, bool ignoreNACK = false)
darienf 3:36de8b9e4b1a 1184 {
darienf 3:36de8b9e4b1a 1185 int i;
darienf 3:36de8b9e4b1a 1186
darienf 3:36de8b9e4b1a 1187 try
darienf 3:36de8b9e4b1a 1188 {
darienf 3:36de8b9e4b1a 1189 int LSb = range & 0xF;
darienf 3:36de8b9e4b1a 1190 int MSb = (range & 0xF0) >> 4;
darienf 3:36de8b9e4b1a 1191 if (MSb < LSb)
darienf 3:36de8b9e4b1a 1192 throw new Exception("invalid bit range");
darienf 3:36de8b9e4b1a 1193 //if (numDataBytes > REPORT_SIZE - 5)
darienf 3:36de8b9e4b1a 1194 // throw new Exception("USB buffer overflow");
darienf 3:36de8b9e4b1a 1195
darienf 3:36de8b9e4b1a 1196 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in setBitI2C
darienf 3:36de8b9e4b1a 1197 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1198 FlushQueue();
darienf 3:36de8b9e4b1a 1199
darienf 3:36de8b9e4b1a 1200 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1201
darienf 3:36de8b9e4b1a 1202 //send data to tell uC to do I2C read from slave
darienf 3:36de8b9e4b1a 1203 reportID();
darienf 3:36de8b9e4b1a 1204 IOBuf[1] = 6; // I2C transaction -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1205 IOBuf[2] = deviceAddress;
darienf 3:36de8b9e4b1a 1206 byte numDataBytes = (byte)(MSb > 7 ? 2 : 1);
darienf 3:36de8b9e4b1a 1207 IOBuf[3] = numDataBytes;
darienf 3:36de8b9e4b1a 1208 byte numRegBytes = (byte)Math.Ceiling(reg / 255.0);
darienf 3:36de8b9e4b1a 1209 IOBuf[4] = numRegBytes;
darienf 3:36de8b9e4b1a 1210 for (i = 0; i < numRegBytes; i++)
darienf 3:36de8b9e4b1a 1211 IOBuf[i + 5] = (byte)((reg>>(8*i)) & 0xFF);
darienf 3:36de8b9e4b1a 1212 //for (i = 0; i < numDataBytes; i++)
darienf 3:36de8b9e4b1a 1213 // IOBuf[i + 5 + numRegBytes] = data[i];
darienf 3:36de8b9e4b1a 1214
darienf 3:36de8b9e4b1a 1215 writeHID();
darienf 3:36de8b9e4b1a 1216 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1217
darienf 3:36de8b9e4b1a 1218 if (checkNACK() == I2C_NACK_ERROR && ignoreNACK == false)
darienf 3:36de8b9e4b1a 1219 throw new Exception("invalid I2C address");
darienf 3:36de8b9e4b1a 1220 }
darienf 3:36de8b9e4b1a 1221 catch (Exception ex)
darienf 3:36de8b9e4b1a 1222 {
darienf 3:36de8b9e4b1a 1223 throw new Exception(ex.Message + Environment.NewLine + new System.Diagnostics.StackFrame().GetMethod().Name);
darienf 3:36de8b9e4b1a 1224 }
darienf 3:36de8b9e4b1a 1225 }
darienf 3:36de8b9e4b1a 1226
darienf 3:36de8b9e4b1a 1227 /// <summary>
darienf 3:36de8b9e4b1a 1228 /// <para>Firmware command code 0 IN = Firmware version</para>
darienf 3:36de8b9e4b1a 1229 ///
darienf 3:36de8b9e4b1a 1230 /// </summary>
darienf 3:36de8b9e4b1a 1231 /// <param name="VerMajor"></param>
darienf 3:36de8b9e4b1a 1232 /// <param name="VerMinor"></param>
darienf 3:36de8b9e4b1a 1233 /// <param name="verYearHundreds"></param>
darienf 3:36de8b9e4b1a 1234 /// <param name="verYear"></param>
darienf 3:36de8b9e4b1a 1235 /// <param name="verMonth"></param>
darienf 3:36de8b9e4b1a 1236 /// <param name="verDay"></param>
darienf 3:36de8b9e4b1a 1237 public void FirmwareVersion(out byte VerMajor, out byte VerMinor, out byte verYearHundreds, out byte verYear, out byte verMonth, out byte verDay)
darienf 3:36de8b9e4b1a 1238 {
darienf 3:36de8b9e4b1a 1239 if (FirmwareINT0Enabled != 0)
darienf 3:36de8b9e4b1a 1240 {
darienf 3:36de8b9e4b1a 1241 // firmware is busy streaming out HID reports,
darienf 3:36de8b9e4b1a 1242 // so return a previously retrieved firmware version.
darienf 3:36de8b9e4b1a 1243 VerMajor = _VerMajor;
darienf 3:36de8b9e4b1a 1244 VerMinor = _VerMinor;
darienf 3:36de8b9e4b1a 1245 verYearHundreds = _verYearHundreds;
darienf 3:36de8b9e4b1a 1246 verYear = _verYear;
darienf 3:36de8b9e4b1a 1247 verMonth = _verMonth;
darienf 3:36de8b9e4b1a 1248 verDay = _verDay;
darienf 3:36de8b9e4b1a 1249 return;
darienf 3:36de8b9e4b1a 1250 }
darienf 3:36de8b9e4b1a 1251 // https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers
darienf 3:36de8b9e4b1a 1252 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in FirmwareVersion
darienf 3:36de8b9e4b1a 1253 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1254 FlushQueue();
darienf 3:36de8b9e4b1a 1255 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1256 reportID();
darienf 3:36de8b9e4b1a 1257 IOBuf[1] = 0; // Firmware version -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1258 writeReadHID();
darienf 3:36de8b9e4b1a 1259 VerMajor = IOBuf[2];
darienf 3:36de8b9e4b1a 1260 VerMinor = IOBuf[3];
darienf 3:36de8b9e4b1a 1261 verYearHundreds = IOBuf[4];
darienf 3:36de8b9e4b1a 1262 verYear = IOBuf[5];
darienf 3:36de8b9e4b1a 1263 verMonth = IOBuf[6];
darienf 3:36de8b9e4b1a 1264 verDay = IOBuf[7];
darienf 3:36de8b9e4b1a 1265 //
darienf 3:36de8b9e4b1a 1266 // save the recently read values
darienf 3:36de8b9e4b1a 1267 _VerMajor = VerMajor;
darienf 3:36de8b9e4b1a 1268 _VerMinor = VerMinor;
darienf 3:36de8b9e4b1a 1269 _verYearHundreds = verYearHundreds;
darienf 3:36de8b9e4b1a 1270 _verYear = verYear;
darienf 3:36de8b9e4b1a 1271 _verMonth = verMonth;
darienf 3:36de8b9e4b1a 1272 _verDay = verDay;
darienf 3:36de8b9e4b1a 1273 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1274 }
darienf 3:36de8b9e4b1a 1275 private byte _VerMajor = 0;
darienf 3:36de8b9e4b1a 1276 private byte _VerMinor = 0;
darienf 3:36de8b9e4b1a 1277 private byte _verYearHundreds = 0;
darienf 3:36de8b9e4b1a 1278 private byte _verYear = 0;
darienf 3:36de8b9e4b1a 1279 private byte _verMonth = 0;
darienf 3:36de8b9e4b1a 1280 private byte _verDay = 0;
darienf 3:36de8b9e4b1a 1281
darienf 3:36de8b9e4b1a 1282 /// <summary>
darienf 3:36de8b9e4b1a 1283 /// <para>Firmware command code 1 OUT = LED (C51F321 P2.2=red, P2.1=green) </para>
darienf 3:36de8b9e4b1a 1284 ///
darienf 3:36de8b9e4b1a 1285 /// </summary>
darienf 3:36de8b9e4b1a 1286 /// <param name="xxxxxxP22P21">0x02=P2.2 Red, 0x01=P2.1 Green</param>
darienf 3:36de8b9e4b1a 1287 public void LEDSet(byte xxxxxxP22P21)
darienf 3:36de8b9e4b1a 1288 {
darienf 3:36de8b9e4b1a 1289 // https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers LEDSet(byte xxxxxxP22P21)
darienf 3:36de8b9e4b1a 1290 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in LEDSet
darienf 3:36de8b9e4b1a 1291 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1292 FlushQueue();
darienf 3:36de8b9e4b1a 1293 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1294 reportID();
darienf 3:36de8b9e4b1a 1295 IOBuf[1] = 1; // case (1): //LED (C51F321 P2.2=red, P2.1=green) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1296 IOBuf[2] = 0; // case (0): // write
darienf 3:36de8b9e4b1a 1297 IOBuf[3] = xxxxxxP22P21;
darienf 3:36de8b9e4b1a 1298 // Led2 = IO_BUFFER.Ptr[2+gOffset] & 1; // sbit Led2 = P2^1;
darienf 3:36de8b9e4b1a 1299 // Led1 = (IO_BUFFER.Ptr[2+gOffset] & 2) >> 1; // sbit Led1 = P2^2;
darienf 3:36de8b9e4b1a 1300 writeHID();
darienf 3:36de8b9e4b1a 1301 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1302 }
darienf 3:36de8b9e4b1a 1303
darienf 3:36de8b9e4b1a 1304 /// <summary>
darienf 3:36de8b9e4b1a 1305 /// <para>Firmware command code 1 IN = GPIOP0Get read I/O pins P0.6, P0.7</para>
darienf 3:36de8b9e4b1a 1306 ///
darienf 3:36de8b9e4b1a 1307 /// </summary>
darienf 3:36de8b9e4b1a 1308 /// <param name="xxxxxxP06P07"></param>
darienf 3:36de8b9e4b1a 1309 public void GPIOP0Get(out byte xxxxxxP06P07)
darienf 3:36de8b9e4b1a 1310 {
darienf 3:36de8b9e4b1a 1311 // todo: verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers GPIOP0Get(out byte xxxxxxP06P07)
darienf 3:36de8b9e4b1a 1312 // https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: Rename LEDGet(out byte xxxxxxP06P07) to GPIOP0Get(out byte xxxxxxP06P07)
darienf 3:36de8b9e4b1a 1313 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in GPIOP0Get
darienf 3:36de8b9e4b1a 1314 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1315 FlushQueue();
darienf 3:36de8b9e4b1a 1316 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1317 reportID();
darienf 3:36de8b9e4b1a 1318 IOBuf[1] = 1; // case (1): //LED (C51F321 P2.2=red, P2.1=green) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1319 IOBuf[2] = 1; // case (1): // read
darienf 3:36de8b9e4b1a 1320 writeReadHID();
darienf 3:36de8b9e4b1a 1321 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1322 // IO_BUFFER.Ptr[0 + gOffset] = 0; // error status
darienf 3:36de8b9e4b1a 1323 // IO_BUFFER.Ptr[1 + gOffset] = ((P0 & 0x80) >> 7) + ((P0 & 0x40) >> 5);
darienf 3:36de8b9e4b1a 1324 xxxxxxP06P07 = IOBuf[2];
darienf 3:36de8b9e4b1a 1325 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1326 }
darienf 3:36de8b9e4b1a 1327
darienf 3:36de8b9e4b1a 1328 /// <summary>
darienf 3:36de8b9e4b1a 1329 /// <para>Firmware command code 2 OUT = GPIO configuration (C51F321 P1 and P2) </para>
darienf 3:36de8b9e4b1a 1330 ///
darienf 3:36de8b9e4b1a 1331 /// </summary>
darienf 3:36de8b9e4b1a 1332 /// <param name="P1MDOUT"></param>
darienf 3:36de8b9e4b1a 1333 /// <param name="P2MDOUT"></param>
darienf 3:36de8b9e4b1a 1334 /// <param name="weakPullupDisable"></param>
darienf 3:36de8b9e4b1a 1335 public void GPIOP1P2ConfigSet(byte P1MDOUT, byte P2MDOUT, byte weakPullupDisable)
darienf 3:36de8b9e4b1a 1336 {
darienf 3:36de8b9e4b1a 1337 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers GPIOP1P2ConfigSet(byte P1MDOUT, byte P2MDOUT, byte weakPullupDisable)
darienf 3:36de8b9e4b1a 1338 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in GPIOP1P2ConfigSet
darienf 3:36de8b9e4b1a 1339 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1340 FlushQueue();
darienf 3:36de8b9e4b1a 1341 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1342 reportID();
darienf 3:36de8b9e4b1a 1343 IOBuf[1] = 2; // case (2): //GPIO configuration (C51F321 P1 and P2) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1344 IOBuf[2] = 0; // case (0): // write
darienf 3:36de8b9e4b1a 1345 IOBuf[3] = P1MDOUT; // P1MDOUT = IO_BUFFER.Ptr[2+gOffset]; // P1 push-pull (1) or open-collector (0)
darienf 3:36de8b9e4b1a 1346 IOBuf[4] = P2MDOUT; // P2MDOUT = IO_BUFFER.Ptr[3 + gOffset]; // P2 push-pull (1) or open-collector (0)
darienf 3:36de8b9e4b1a 1347 IOBuf[5] = weakPullupDisable; // (IO_BUFFER.Ptr[4 + gOffset] & 1) ? (XBR1 |= 0x80) : (XBR1 &= 0x7F); // weak pull up disable (open collector only); 1 disabled, 0 enabled
darienf 3:36de8b9e4b1a 1348 writeHID();
darienf 3:36de8b9e4b1a 1349 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1350 }
darienf 3:36de8b9e4b1a 1351
darienf 3:36de8b9e4b1a 1352 /// <summary>
darienf 3:36de8b9e4b1a 1353 /// <para>Firmware command code 2 IN = GPIO configuration (C51F321 P1 and P2) </para>
darienf 3:36de8b9e4b1a 1354 ///
darienf 3:36de8b9e4b1a 1355 /// </summary>
darienf 3:36de8b9e4b1a 1356 /// <param name="P1MDOUT"></param>
darienf 3:36de8b9e4b1a 1357 /// <param name="P2MDOUT"></param>
darienf 3:36de8b9e4b1a 1358 /// <param name="weakPullupDisable"></param>
darienf 3:36de8b9e4b1a 1359 public void GPIOP1P2ConfigGet(out byte P1MDOUT, out byte P2MDOUT, out byte weakPullupDisable)
darienf 3:36de8b9e4b1a 1360 {
darienf 3:36de8b9e4b1a 1361 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers GPIOP1P2ConfigGet(out byte P1MDOUT, out byte P2MDOUT, out byte weakPullupDisable)
darienf 3:36de8b9e4b1a 1362 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in GPIOP1P2ConfigGet
darienf 3:36de8b9e4b1a 1363 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1364 FlushQueue();
darienf 3:36de8b9e4b1a 1365 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1366 reportID();
darienf 3:36de8b9e4b1a 1367 IOBuf[1] = 2; // case (2): //GPIO configuration (C51F321 P1 and P2) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1368 IOBuf[2] = 1; // case (1): // read
darienf 3:36de8b9e4b1a 1369 writeReadHID();
darienf 3:36de8b9e4b1a 1370 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1371 // IO_BUFFER.Ptr[0 + gOffset] = 0; // error status
darienf 3:36de8b9e4b1a 1372 // IO_BUFFER.Ptr[1 + gOffset] = P1MDOUT; // P1 push-pull (1) or open-collector (0)
darienf 3:36de8b9e4b1a 1373 // IO_BUFFER.Ptr[2 + gOffset] = P2MDOUT; // P2 push-pull (1) or open-collector (0)
darienf 3:36de8b9e4b1a 1374 // IO_BUFFER.Ptr[3 + gOffset] = (XBR1 & 0x80) >> 7; // weakPullupDisable
darienf 3:36de8b9e4b1a 1375 P1MDOUT = IOBuf[2];
darienf 3:36de8b9e4b1a 1376 P2MDOUT = IOBuf[3];
darienf 3:36de8b9e4b1a 1377 weakPullupDisable = IOBuf[4];
darienf 3:36de8b9e4b1a 1378 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1379 }
darienf 3:36de8b9e4b1a 1380
darienf 3:36de8b9e4b1a 1381 /// <summary>
darienf 3:36de8b9e4b1a 1382 /// <para>Firmware command code 3 OUT = GPIO value (C51F321 P1 and P2) </para>
darienf 3:36de8b9e4b1a 1383 ///
darienf 3:36de8b9e4b1a 1384 /// </summary>
darienf 3:36de8b9e4b1a 1385 /// <param name="P1"></param>
darienf 3:36de8b9e4b1a 1386 /// <param name="P2"></param>
darienf 3:36de8b9e4b1a 1387 public void GPIOP1P2Out(byte P1, byte P2)
darienf 3:36de8b9e4b1a 1388 {
darienf 3:36de8b9e4b1a 1389 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers GPIOP1P2Out(byte P1, byte P2)
darienf 3:36de8b9e4b1a 1390 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in GPIOP1P2Out
darienf 3:36de8b9e4b1a 1391 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1392 FlushQueue();
darienf 3:36de8b9e4b1a 1393 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1394 reportID();
darienf 3:36de8b9e4b1a 1395 IOBuf[1] = 3; // case (3): //GPIO value (C51F321 P1 and P2) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1396 IOBuf[2] = 0; // case (0): // write
darienf 3:36de8b9e4b1a 1397 IOBuf[3] = P1; // P1 = IO_BUFFER.Ptr[2 + gOffset]; // P1 HI (1) or LO (0); set P1==1 and P1MDOUT==1 for HI-Z
darienf 3:36de8b9e4b1a 1398 IOBuf[4] = P2; // P2 = IO_BUFFER.Ptr[3 + gOffset]; // P2 HI (1) or LO (0); set P2==1 and P1MDOUT==2 for HI-Z
darienf 3:36de8b9e4b1a 1399 writeHID();
darienf 3:36de8b9e4b1a 1400 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1401 }
darienf 3:36de8b9e4b1a 1402
darienf 3:36de8b9e4b1a 1403 /// <summary>
darienf 3:36de8b9e4b1a 1404 /// <para>Firmware command code 3 IN = GPIO value (C51F321 P1 and P2) </para>
darienf 3:36de8b9e4b1a 1405 ///
darienf 3:36de8b9e4b1a 1406 /// </summary>
darienf 3:36de8b9e4b1a 1407 /// <param name="P1"></param>
darienf 3:36de8b9e4b1a 1408 /// <param name="P2"></param>
darienf 3:36de8b9e4b1a 1409 public void GPIOP1P2In(out byte P1, out byte P2)
darienf 3:36de8b9e4b1a 1410 {
darienf 3:36de8b9e4b1a 1411 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers GPIOP1P2In(out byte P1, out byte P2)
darienf 3:36de8b9e4b1a 1412 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in GPIOP1P2In
darienf 3:36de8b9e4b1a 1413 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1414 FlushQueue();
darienf 3:36de8b9e4b1a 1415 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1416 reportID();
darienf 3:36de8b9e4b1a 1417 IOBuf[1] = 3; // case (3): //GPIO value (C51F321 P1 and P2) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1418 IOBuf[2] = 1; // case (1): // read
darienf 3:36de8b9e4b1a 1419 writeReadHID();
darienf 3:36de8b9e4b1a 1420 // temp = XBR1;
darienf 3:36de8b9e4b1a 1421 // if (IO_BUFFER.Ptr[2+gOffset] & 1) // enable weak pullups in case GP pins are open-collector and not connected to anything (which would falsely give '0')
darienf 3:36de8b9e4b1a 1422 // {
darienf 3:36de8b9e4b1a 1423 // XBR1 &= 0x7F;
darienf 3:36de8b9e4b1a 1424 // Timer0_Init(HALFMS);
darienf 3:36de8b9e4b1a 1425 // T0_Wait(2);
darienf 3:36de8b9e4b1a 1426 // }
darienf 3:36de8b9e4b1a 1427 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1428 // IO_BUFFER.Ptr[0+gOffset] = 0; // error status
darienf 3:36de8b9e4b1a 1429 // IO_BUFFER.Ptr[1+gOffset] = P1; // P1 HI (1) or LO (0)
darienf 3:36de8b9e4b1a 1430 // IO_BUFFER.Ptr[2+gOffset] = P2; // P2 HI (1) or LO (0)
darienf 3:36de8b9e4b1a 1431 // XBR1 = temp;
darienf 3:36de8b9e4b1a 1432 // SendPacket(); // no need to check for internal call since only the GUI will request a read through this function
darienf 3:36de8b9e4b1a 1433 P1 = IOBuf[2];
darienf 3:36de8b9e4b1a 1434 P2 = IOBuf[3];
darienf 3:36de8b9e4b1a 1435 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1436 }
darienf 3:36de8b9e4b1a 1437
darienf 3:36de8b9e4b1a 1438 /// <summary>
darienf 3:36de8b9e4b1a 1439 /// <para>Firmware command code 4 OUT = I2C configuration </para>
darienf 3:36de8b9e4b1a 1440 /// (IO_BUFFER.Ptr[3+gOffset] &amp; 1) ? (SMB0CF |= 0x10) : (SMB0CF &amp;= 0xEF)
darienf 3:36de8b9e4b1a 1441 /// </summary>
darienf 3:36de8b9e4b1a 1442 /// <param name="gI2Cflags">bit0 == 1: repeated start</param>
darienf 3:36de8b9e4b1a 1443 /// <param name="EXTHOLD">set EXTHOLD bit (SMBus setup / hold time extension)</param>
darienf 3:36de8b9e4b1a 1444 /// <param name="ClearSDAbyTogglingSCL">clear SDA by toggling SCL</param>
darienf 3:36de8b9e4b1a 1445 public void I2CConfigSet(byte gI2Cflags, byte EXTHOLD, byte ClearSDAbyTogglingSCL)
darienf 3:36de8b9e4b1a 1446 {
darienf 3:36de8b9e4b1a 1447 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers I2CConfigSet(byte gI2Cflags, byte EXTHOLD, byte ClearSDAbyTogglingSCL)
darienf 3:36de8b9e4b1a 1448 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in I2CConfigSet
darienf 3:36de8b9e4b1a 1449 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1450 FlushQueue();
darienf 3:36de8b9e4b1a 1451 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1452 reportID();
darienf 3:36de8b9e4b1a 1453 IOBuf[1] = 4; // case (4): //I2C configuration -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1454 IOBuf[2] = 0; // case (0): // write
darienf 3:36de8b9e4b1a 1455 IOBuf[3] = gI2Cflags; // gI2Cflags = IO_BUFFER.Ptr[2+gOffset];
darienf 3:36de8b9e4b1a 1456 // // bit0 == 1: repeated start (versus stop/start) after write before read (applies to random read only)
darienf 3:36de8b9e4b1a 1457 // // bit1 == 1: start random read with a write, but end the write right away without sending reg address (emulate Jungo dongle for debug purposes)
darienf 3:36de8b9e4b1a 1458 // // bit2 == 1: repeat transaction if slave NACKs (suggest not to use this)
darienf 3:36de8b9e4b1a 1459 // // all flags are OR'd
darienf 3:36de8b9e4b1a 1460 IOBuf[4] = EXTHOLD; // (IO_BUFFER.Ptr[3+gOffset] & 1) ? (SMB0CF |= 0x10) : (SMB0CF &= 0xEF); // set EXTHOLD bit (SMBus setup / hold time extension)
darienf 3:36de8b9e4b1a 1461 IOBuf[5] = ClearSDAbyTogglingSCL; // if (IO_BUFFER.Ptr[4+gOffset] & 1) // clear SDA by toggling SCL
darienf 3:36de8b9e4b1a 1462 // {s
darienf 3:36de8b9e4b1a 1463 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1464 // IO_BUFFER.Ptr[0+gOffset] = 0; // transaction error status
darienf 3:36de8b9e4b1a 1465 // IO_BUFFER.Ptr[1+gOffset] = clearSDA(); // clearSDA error status
darienf 3:36de8b9e4b1a 1466 // SendPacket(); // send status of clearing SDA to host
darienf 3:36de8b9e4b1a 1467 // }
darienf 3:36de8b9e4b1a 1468 writeHID();
darienf 3:36de8b9e4b1a 1469 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1470 }
darienf 3:36de8b9e4b1a 1471
darienf 3:36de8b9e4b1a 1472 /// <summary>
darienf 3:36de8b9e4b1a 1473 /// <para>Firmware command code 4 IN = I2C configuration </para>
darienf 3:36de8b9e4b1a 1474 /// (IO_BUFFER.Ptr[3+gOffset] &amp; 1) ? (SMB0CF |= 0x10) : (SMB0CF &amp;= 0xEF)
darienf 3:36de8b9e4b1a 1475 /// </summary>
darienf 3:36de8b9e4b1a 1476 /// <param name="gI2Cflags">bit0 == 1: repeated start</param>
darienf 3:36de8b9e4b1a 1477 /// <param name="EXTHOLD">SMB0CF &amp; 0x10</param>
darienf 3:36de8b9e4b1a 1478 public void I2CConfigGet(out byte gI2Cflags, out byte EXTHOLD)
darienf 3:36de8b9e4b1a 1479 {
darienf 3:36de8b9e4b1a 1480 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers I2CConfigGet(out byte gI2Cflags, out byte EXTHOLD)
darienf 3:36de8b9e4b1a 1481 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in I2CConfigGet
darienf 3:36de8b9e4b1a 1482 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1483 FlushQueue();
darienf 3:36de8b9e4b1a 1484 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1485 reportID();
darienf 3:36de8b9e4b1a 1486 IOBuf[1] = 4; // case (4): //I2C configuration -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1487 IOBuf[2] = 1; // case (1): // read
darienf 3:36de8b9e4b1a 1488 writeReadHID();
darienf 3:36de8b9e4b1a 1489 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1490 // IO_BUFFER.Ptr[0+gOffset] = 0; // error status
darienf 3:36de8b9e4b1a 1491 // IO_BUFFER.Ptr[1+gOffset] = gI2Cflags;
darienf 3:36de8b9e4b1a 1492 // IO_BUFFER.Ptr[2+gOffset] = (SMB0CF & 0x10) >> 4; // EXTHOLD
darienf 3:36de8b9e4b1a 1493 gI2Cflags = IOBuf[2];
darienf 3:36de8b9e4b1a 1494 EXTHOLD = IOBuf[3];
darienf 3:36de8b9e4b1a 1495 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1496 }
darienf 3:36de8b9e4b1a 1497
darienf 3:36de8b9e4b1a 1498 /// <summary>
darienf 3:36de8b9e4b1a 1499 /// <para>Firmware command code 5 OUT = I2C clock rate (number of counts to overflow) </para>
darienf 3:36de8b9e4b1a 1500 /// <para>SCL_kHz = TimerClockMHz * 1000 / ReloadTH1</para>
darienf 3:36de8b9e4b1a 1501 /// </summary>
darienf 3:36de8b9e4b1a 1502 /// <param name="ReloadTH1">SMBus timer's count value: ReloadTH1 = (byte)(0.5 + (TimerClockMHz * 1000 / SCL_kHz))</param>
darienf 3:36de8b9e4b1a 1503 public void I2CClockSet(byte ReloadTH1)
darienf 3:36de8b9e4b1a 1504 {
darienf 3:36de8b9e4b1a 1505 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers I2CClockSet(byte ReloadTH1)
darienf 3:36de8b9e4b1a 1506 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in I2CClockSet
darienf 3:36de8b9e4b1a 1507 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1508 FlushQueue();
darienf 3:36de8b9e4b1a 1509 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1510 reportID();
darienf 3:36de8b9e4b1a 1511 IOBuf[1] = 5; // case (5): //I2C clock rate (number of counts to overflow) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1512 IOBuf[2] = 0; // case (0): // write
darienf 3:36de8b9e4b1a 1513 IOBuf[3] = ReloadTH1;
darienf 3:36de8b9e4b1a 1514 // gSMBusClkFreq = gTimer1ClkFreq / 3.0 / IO_BUFFER.Ptr[2+gOffset]; //GUI sends the number of counts to overflow; HID must calculate the desired SMBus clock frequency
darienf 3:36de8b9e4b1a 1515 // TR1 = 0;
darienf 3:36de8b9e4b1a 1516 // Timer1_Init();
darienf 3:36de8b9e4b1a 1517 writeHID();
darienf 3:36de8b9e4b1a 1518 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1519 }
darienf 3:36de8b9e4b1a 1520
darienf 3:36de8b9e4b1a 1521 /// <summary>
darienf 3:36de8b9e4b1a 1522 /// <para>Firmware command code 5 IN = I2C clock rate (number of counts to overflow) </para>
darienf 3:36de8b9e4b1a 1523 /// <para>SCL_kHz = TimerClockMHz * 1000 / ReloadTH1</para>
darienf 3:36de8b9e4b1a 1524 /// </summary>
darienf 3:36de8b9e4b1a 1525 /// <param name="TimerClockMHz">SMBus timer's clock frequency (in MHz); expect constant 8</param>
darienf 3:36de8b9e4b1a 1526 /// <param name="ReloadTH1">SMBus timer's count value: SCL_kHz = TimerClockMHz * 1000 / ReloadTH1</param>
darienf 3:36de8b9e4b1a 1527 public void I2CClockGet(out byte TimerClockMHz, out byte ReloadTH1)
darienf 3:36de8b9e4b1a 1528 {
darienf 3:36de8b9e4b1a 1529 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers I2CClockGet(out byte TimerClockMHz, out byte ReloadTH1)
darienf 3:36de8b9e4b1a 1530 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in I2CClockGet
darienf 3:36de8b9e4b1a 1531 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1532 FlushQueue();
darienf 3:36de8b9e4b1a 1533 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1534 reportID();
darienf 3:36de8b9e4b1a 1535 IOBuf[1] = 5; // case (5): //I2C clock rate (number of counts to overflow) -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1536 IOBuf[2] = 1; // case (1): // read
darienf 3:36de8b9e4b1a 1537 writeReadHID();
darienf 3:36de8b9e4b1a 1538 // case (1): // read -- myHID.I2CClockGet(out TimerClockMHz, out ReloadTH1)
darienf 3:36de8b9e4b1a 1539 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1540 // IO_BUFFER.Ptr[0+gOffset] = 0; // error status
darienf 3:36de8b9e4b1a 1541 // IO_BUFFER.Ptr[1+gOffset] = gTimer1ClkFreq / 1000000 / 3; //return the SMBus timer's clock frequency (in MHz)
darienf 3:36de8b9e4b1a 1542 // IO_BUFFER.Ptr[2+gOffset] = 256-TH1; //and return the SMBus timer's count value in order to calculate the SMBus clock frequency; TH1 is the reload value that gets loaded into TL0 upon overflow; the reload value is 256-TH1 since (0)-TH1 gives the proper number of counts to overflow
darienf 3:36de8b9e4b1a 1543 // SendPacket(); // no need to check for internal call since only the GUI will request a read through this function
darienf 3:36de8b9e4b1a 1544 // break;
darienf 3:36de8b9e4b1a 1545 TimerClockMHz = IOBuf[2];
darienf 3:36de8b9e4b1a 1546 ReloadTH1 = IOBuf[3];
darienf 3:36de8b9e4b1a 1547 // todo: OS24EVK-24 how determine SCL from TimerClockMHZ? Observed I2CClockGet() TimerClockMHz = 8 when SCL = 400kHz.
darienf 3:36de8b9e4b1a 1548 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1549 }
darienf 3:36de8b9e4b1a 1550
darienf 3:36de8b9e4b1a 1551 /// <summary>
darienf 3:36de8b9e4b1a 1552 /// <para>Firmware command code 6 OUT = I2C transaction </para>
darienf 3:36de8b9e4b1a 1553 ///
darienf 3:36de8b9e4b1a 1554 /// </summary>
darienf 3:36de8b9e4b1a 1555 /// <param name="deviceAddress">I2C device address, 8-bit left-justified (LSB=R/w bit)</param>
darienf 3:36de8b9e4b1a 1556 /// <param name="numDataBytes"></param>
darienf 3:36de8b9e4b1a 1557 /// <param name="numRegBytes"></param>
darienf 3:36de8b9e4b1a 1558 /// <param name="data"></param>
darienf 3:36de8b9e4b1a 1559 /// <param name="reg"></param>
darienf 3:36de8b9e4b1a 1560 /// <param name="ignoreNACK"></param>
darienf 3:36de8b9e4b1a 1561 public void I2CWrite(byte deviceAddress, byte numDataBytes, byte numRegBytes, byte[] data, byte[] reg, bool ignoreNACK = false)
darienf 3:36de8b9e4b1a 1562 {
darienf 3:36de8b9e4b1a 1563 // https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers
darienf 3:36de8b9e4b1a 1564 // alias of existing function
darienf 3:36de8b9e4b1a 1565 // IOBuf[1] = 6; // case (6): // I2C transaction -- HID.cs void writeI2C() readI2C() -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1566 writeI2C(deviceAddress, numDataBytes, numRegBytes, data, reg, ignoreNACK);
darienf 3:36de8b9e4b1a 1567 }
darienf 3:36de8b9e4b1a 1568
darienf 3:36de8b9e4b1a 1569 /// <summary>
darienf 3:36de8b9e4b1a 1570 /// <para>Firmware command code 6 IN = I2C transaction </para>
darienf 3:36de8b9e4b1a 1571 ///
darienf 3:36de8b9e4b1a 1572 /// </summary>
darienf 3:36de8b9e4b1a 1573 /// <param name="deviceAddress">I2C device address, 8-bit left-justified (LSB=R/w bit)</param>
darienf 3:36de8b9e4b1a 1574 /// <param name="numDataBytes"></param>
darienf 3:36de8b9e4b1a 1575 /// <param name="numRegBytes"></param>
darienf 3:36de8b9e4b1a 1576 /// <param name="readData"></param>
darienf 3:36de8b9e4b1a 1577 /// <param name="reg"></param>
darienf 3:36de8b9e4b1a 1578 /// <param name="ignoreNACK"></param>
darienf 3:36de8b9e4b1a 1579 /// <returns>status value; may be HID.I2C_NACK_ERROR if ignoreNACK parameter is true</returns>
darienf 3:36de8b9e4b1a 1580 public int I2CRead(byte deviceAddress, byte numDataBytes, byte numRegBytes, byte[] readData, byte[] reg, bool ignoreNACK = false)
darienf 3:36de8b9e4b1a 1581 {
darienf 3:36de8b9e4b1a 1582 // https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers
darienf 3:36de8b9e4b1a 1583 // alias of existing function
darienf 3:36de8b9e4b1a 1584 // IOBuf[1] = 6; // case (6): // I2C transaction -- HID.cs void writeI2C() readI2C() -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1585 return readI2C(deviceAddress, numDataBytes, numRegBytes, readData, reg, ignoreNACK);
darienf 3:36de8b9e4b1a 1586 }
darienf 3:36de8b9e4b1a 1587
darienf 3:36de8b9e4b1a 1588 /// <summary>
darienf 3:36de8b9e4b1a 1589 /// <para>Firmware command code 7 OUT = SPI config </para>
darienf 3:36de8b9e4b1a 1590 /// ((SPI0CFG &amp; 0x30) &gt;&gt; 4) + (SPI0CN &amp; 4)
darienf 3:36de8b9e4b1a 1591 /// </summary>
darienf 3:36de8b9e4b1a 1592 /// <param name="config"></param>
darienf 3:36de8b9e4b1a 1593 public void SPIConfigSet(byte config)
darienf 3:36de8b9e4b1a 1594 {
darienf 3:36de8b9e4b1a 1595 // todo: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers SPIConfigSet(byte config)
darienf 3:36de8b9e4b1a 1596 // Although the MAX30101EVKIT firmware will accept HID SPI commands, this firmware doesn't support SPI interface.
darienf 3:36de8b9e4b1a 1597 // IOBuf[1] = 7; // case (7): // SPI config -- HID.cs void writeI2C() readI2C() -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1598 }
darienf 3:36de8b9e4b1a 1599
darienf 3:36de8b9e4b1a 1600 /// <summary>
darienf 3:36de8b9e4b1a 1601 /// <para>Firmware command code 7 IN = SPI config </para>
darienf 3:36de8b9e4b1a 1602 /// ((SPI0CFG &amp; 0x30) &gt;&gt; 4) + (SPI0CN &amp; 4)
darienf 3:36de8b9e4b1a 1603 /// </summary>
darienf 3:36de8b9e4b1a 1604 /// <param name="config"></param>
darienf 3:36de8b9e4b1a 1605 public void SPIConfigGet(out byte config)
darienf 3:36de8b9e4b1a 1606 {
darienf 3:36de8b9e4b1a 1607 // todo: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers SPIConfigGet(out byte config)
darienf 3:36de8b9e4b1a 1608 // Although the MAX30101EVKIT firmware will accept HID SPI commands, this firmware doesn't support SPI interface.
darienf 3:36de8b9e4b1a 1609 // IOBuf[1] = 7; // case (7): // SPI config -- HID.cs void writeI2C() readI2C() -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1610 config = 0;
darienf 3:36de8b9e4b1a 1611 }
darienf 3:36de8b9e4b1a 1612
darienf 3:36de8b9e4b1a 1613 /// <summary>
darienf 3:36de8b9e4b1a 1614 /// <para>Firmware command code 8 OUT = SPI clock rate </para>
darienf 3:36de8b9e4b1a 1615 /// </summary>
darienf 3:36de8b9e4b1a 1616 /// <param name="SPI0CKR"></param>
darienf 3:36de8b9e4b1a 1617 public void SPIClockSet(byte SPI0CKR)
darienf 3:36de8b9e4b1a 1618 {
darienf 3:36de8b9e4b1a 1619 // todo: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers SPIClockSet(byte SPI0CKR)
darienf 3:36de8b9e4b1a 1620 // Although the MAX30101EVKIT firmware will accept HID SPI commands, this firmware doesn't support SPI interface.
darienf 3:36de8b9e4b1a 1621 // IOBuf[1] = 8; // case (8): // SPI clock rate -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1622 }
darienf 3:36de8b9e4b1a 1623
darienf 3:36de8b9e4b1a 1624 /// <summary>
darienf 3:36de8b9e4b1a 1625 /// <para>Firmware command code 8 IN = SPI clock rate </para>
darienf 3:36de8b9e4b1a 1626 /// </summary>
darienf 3:36de8b9e4b1a 1627 /// <param name="SPI0CKR"></param>
darienf 3:36de8b9e4b1a 1628 public void SPIClockGet(out byte SPI0CKR)
darienf 3:36de8b9e4b1a 1629 {
darienf 3:36de8b9e4b1a 1630 // todo: https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers SPIClockGet(out byte SPI0CKR)
darienf 3:36de8b9e4b1a 1631 // Although the MAX30101EVKIT firmware will accept HID SPI commands, this firmware doesn't support SPI interface.
darienf 3:36de8b9e4b1a 1632 // IOBuf[1] = 8; // case (8): // SPI clock rate -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1633 SPI0CKR = 0;
darienf 3:36de8b9e4b1a 1634 }
darienf 3:36de8b9e4b1a 1635
darienf 3:36de8b9e4b1a 1636 /// <summary>
darienf 3:36de8b9e4b1a 1637 /// <para>Firmware command code 9 = SPI transaction </para>
darienf 3:36de8b9e4b1a 1638 /// </summary>
darienf 3:36de8b9e4b1a 1639 /// <param name="mosiData">SPI MOSI (Master-Out, Slave-In) data to write into slave device</param>
darienf 3:36de8b9e4b1a 1640 /// <param name="misoBuffer">SPI MISO (Master-In, Slave-Out) data buffer containing data bytes received from slave device
darienf 3:36de8b9e4b1a 1641 /// (size will be allocated same size as mosiData)</param>
darienf 3:36de8b9e4b1a 1642 public void SPITransfer(byte[] mosiData, out byte[] misoBuffer)
darienf 3:36de8b9e4b1a 1643 {
darienf 3:36de8b9e4b1a 1644 // verify: https://jira.maxim-ic.com/browse/OS24EVK-24 SPITransfer(byte[] mosiData, out byte[] misoBuffer)
darienf 3:36de8b9e4b1a 1645 // Although the MAX30101EVKIT firmware will accept HID SPI commands, this firmware doesn't support SPI interface.
darienf 3:36de8b9e4b1a 1646 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in I2CConfigSet
darienf 3:36de8b9e4b1a 1647 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1648 FlushQueue();
darienf 3:36de8b9e4b1a 1649 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1650 reportID();
darienf 3:36de8b9e4b1a 1651 // assign default out values in case of failure
darienf 3:36de8b9e4b1a 1652 int byteCount = mosiData.Length;
darienf 3:36de8b9e4b1a 1653 byte num_bytes = (byte)(byteCount & 0xFF);
darienf 3:36de8b9e4b1a 1654 misoBuffer = new byte[byteCount];
darienf 3:36de8b9e4b1a 1655 for (int byteIndex = 0; byteIndex < byteCount; byteIndex++)
darienf 3:36de8b9e4b1a 1656 {
darienf 3:36de8b9e4b1a 1657 // initial dummy data
darienf 3:36de8b9e4b1a 1658 misoBuffer[byteIndex] = 0x55;
darienf 3:36de8b9e4b1a 1659 }
darienf 3:36de8b9e4b1a 1660 IOBuf[1] = 9; // case (9): // SPI transaction -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1661 //IOBuf[8] = x; // IO_BUFFER.Ptr[7+gOffset] -- first byte of data starts on the (7 + offset) byte
darienf 3:36de8b9e4b1a 1662 for (uint byteIndex = 0; byteIndex < num_bytes; byteIndex++)
darienf 3:36de8b9e4b1a 1663 {
darienf 3:36de8b9e4b1a 1664 IOBuf[8 + byteIndex] = (byte)(mosiData[byteIndex]);
darienf 3:36de8b9e4b1a 1665 }
darienf 3:36de8b9e4b1a 1666 //switch (SPImode)
darienf 3:36de8b9e4b1a 1667 //{
darienf 3:36de8b9e4b1a 1668 // case 0:
darienf 3:36de8b9e4b1a 1669 IOBuf[2] = 0; // IO_BUFFER.Ptr[1+gOffset] -- 0 for SPI_mode0: multi-byte SPI transfer.
darienf 3:36de8b9e4b1a 1670 IOBuf[3] = 0; // IO_BUFFER.Ptr[2+gOffset] -- not used
darienf 3:36de8b9e4b1a 1671 IOBuf[4] = 0; // IO_BUFFER.Ptr[3+gOffset] -- phase_change // !=0 enable changing the clock phase. some slaves change phase between write/read
darienf 3:36de8b9e4b1a 1672 IOBuf[5] = 0; // IO_BUFFER.Ptr[4+gOffset] -- phase_change_byte // byte index where phase change should happen
darienf 3:36de8b9e4b1a 1673 IOBuf[6] = num_bytes; // IO_BUFFER.Ptr[5+gOffset] -- num_bytes
darienf 3:36de8b9e4b1a 1674 IOBuf[7] = 0; // IO_BUFFER.Ptr[6+gOffset] -- not used
darienf 3:36de8b9e4b1a 1675 // IO_BUFFER.Ptr[7+gOffset] -- first byte of data starts on the (7 + offset) byte
darienf 3:36de8b9e4b1a 1676 // SPI_mode0(IO_BUFFER.Ptr[3 + gOffset], IO_BUFFER.Ptr[4 + gOffset], IO_BUFFER.Ptr[5 + gOffset], IO_BUFFER.Ptr);
darienf 3:36de8b9e4b1a 1677 // break;
darienf 3:36de8b9e4b1a 1678 //case 1:
darienf 3:36de8b9e4b1a 1679 // IOBuf[2] = 1; // IO_BUFFER.Ptr[1+gOffset] -- 1 for SPI_mode1: two-byte SPI transfer. read flag: enable changing the clock phase on first byte and changing phase between first and second byte
darienf 3:36de8b9e4b1a 1680 // IOBuf[3] = 0; // IO_BUFFER.Ptr[2+gOffset] -- read flag
darienf 3:36de8b9e4b1a 1681 // // IO_BUFFER.Ptr[3+gOffset] -- not used
darienf 3:36de8b9e4b1a 1682 // // IO_BUFFER.Ptr[4+gOffset] -- not used
darienf 3:36de8b9e4b1a 1683 // // IO_BUFFER.Ptr[5+gOffset] -- not used; num_bytes = 2
darienf 3:36de8b9e4b1a 1684 // // IO_BUFFER.Ptr[6+gOffset] -- not used
darienf 3:36de8b9e4b1a 1685 // // IO_BUFFER.Ptr[7+gOffset] -- first byte of data starts on the (7 + offset) byte
darienf 3:36de8b9e4b1a 1686 // // SPI_mode1(temp, IO_BUFFER.Ptr);
darienf 3:36de8b9e4b1a 1687 // break;
darienf 3:36de8b9e4b1a 1688 //case 2:
darienf 3:36de8b9e4b1a 1689 // IOBuf[2] = 2; // IO_BUFFER.Ptr[1+gOffset] --2 for SPI_mode2: two-byte SPI transfer. read flag: enable changing the clock phase on first byte and sampling the LSb after the second byte read
darienf 3:36de8b9e4b1a 1690 // IOBuf[3] = 0; // IO_BUFFER.Ptr[2+gOffset] -- read flag
darienf 3:36de8b9e4b1a 1691 // // IO_BUFFER.Ptr[3+gOffset] -- not used
darienf 3:36de8b9e4b1a 1692 // // IO_BUFFER.Ptr[4+gOffset] -- not used
darienf 3:36de8b9e4b1a 1693 // // IO_BUFFER.Ptr[5+gOffset] -- not used; num_bytes = 2
darienf 3:36de8b9e4b1a 1694 // // IO_BUFFER.Ptr[6+gOffset] -- not used
darienf 3:36de8b9e4b1a 1695 // // IO_BUFFER.Ptr[7+gOffset] -- first byte of data starts on the (7 + offset) byte
darienf 3:36de8b9e4b1a 1696 // // SPI_mode2(temp, IO_BUFFER.Ptr);
darienf 3:36de8b9e4b1a 1697 // break;
darienf 3:36de8b9e4b1a 1698 //}
darienf 3:36de8b9e4b1a 1699 writeHID();
darienf 3:36de8b9e4b1a 1700 // IO_BUFFER.Ptr[0] = SHORT_REPORT_ID;
darienf 3:36de8b9e4b1a 1701 // IO_BUFFER.Ptr[0+gOffset] = 0; // error status
darienf 3:36de8b9e4b1a 1702 // IO_BUFFER.Ptr[1+gOffset] = gI2Cflags;
darienf 3:36de8b9e4b1a 1703 // IO_BUFFER.Ptr[2+gOffset] = (SMB0CF & 0x10) >> 4; // EXTHOLD
darienf 3:36de8b9e4b1a 1704 //gI2Cflags = IOBuf[2];
darienf 3:36de8b9e4b1a 1705 //EXTHOLD = IOBuf[3];
darienf 3:36de8b9e4b1a 1706 for (uint byteIndex = 0; byteIndex < byteCount; byteIndex++)
darienf 3:36de8b9e4b1a 1707 {
darienf 3:36de8b9e4b1a 1708 misoBuffer[byteIndex] = IOBuf[byteIndex + 2];
darienf 3:36de8b9e4b1a 1709 }
darienf 3:36de8b9e4b1a 1710 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1711 }
darienf 3:36de8b9e4b1a 1712
darienf 3:36de8b9e4b1a 1713 /// <summary>
darienf 3:36de8b9e4b1a 1714 /// <para>Firmware command code 23 OUT = enable INT0 (or Mock HID FIFO data diagnostic) </para>
darienf 3:36de8b9e4b1a 1715 /// <para>
darienf 3:36de8b9e4b1a 1716 /// - INT0Enable(0) disabled (EX0=0)
darienf 3:36de8b9e4b1a 1717 /// - INT0Enable(1) real hardware (EX0=1)
darienf 3:36de8b9e4b1a 1718 /// - INT0Enable(2) Mock HID x1 channel 101, 102, 103, ...
darienf 3:36de8b9e4b1a 1719 /// - INT0Enable(3) Mock HID x2 channels 101, 201, 102, 202, 103, 203, ...
darienf 3:36de8b9e4b1a 1720 /// - INT0Enable(4) Mock HID x3 channels 101, 201, 301, 102, 202, 302, 103, 203, 303, ...
darienf 3:36de8b9e4b1a 1721 /// - INT0Enable(5) Mock HID x4 channels 101, 201, 301, 401, 102, 202, 302, 402, 103, 203, 303, 403, ...
darienf 3:36de8b9e4b1a 1722 /// </para>
darienf 3:36de8b9e4b1a 1723 /// </summary>
darienf 3:36de8b9e4b1a 1724 /// <param name="EX0"></param>
darienf 3:36de8b9e4b1a 1725 public void INT0Enable(byte EX0)
darienf 3:36de8b9e4b1a 1726 {
darienf 3:36de8b9e4b1a 1727 // https://jira.maxim-ic.com/browse/OS24EVK-24 Refactor: HID report enum and wrappers
darienf 3:36de8b9e4b1a 1728 // reset report counter in the HID and enable INT0
darienf 3:36de8b9e4b1a 1729 // verify: https://jira.maxim-ic.com/browse/OS24EVK-57 mutex lock HID.IOBuf[] in INT0Enable
darienf 3:36de8b9e4b1a 1730 mutexGuardIOBuf.WaitOne(); // Wait until it is safe to enter.
darienf 3:36de8b9e4b1a 1731 FlushQueue();
darienf 3:36de8b9e4b1a 1732 Array.Clear(IOBuf, 0, IOBuf.Length);
darienf 3:36de8b9e4b1a 1733 reportID();
darienf 3:36de8b9e4b1a 1734 IOBuf[1] = 23; // enable INT0 -- see F3xx_USB0_ReportHandler.c void OUT_REPORT_HANDLER(int internalCall)
darienf 3:36de8b9e4b1a 1735 IOBuf[2] = EX0; // reportTypeFlag; // 1;
darienf 3:36de8b9e4b1a 1736 writeHID();
darienf 3:36de8b9e4b1a 1737 _firmwareINT0Enabled = EX0;
darienf 3:36de8b9e4b1a 1738 mutexGuardIOBuf.ReleaseMutex(); // Release the Mutex.
darienf 3:36de8b9e4b1a 1739 }
darienf 3:36de8b9e4b1a 1740 private byte _firmwareINT0Enabled = 0;
darienf 3:36de8b9e4b1a 1741 public byte FirmwareINT0Enabled { get { return _firmwareINT0Enabled; } }
darienf 3:36de8b9e4b1a 1742
darienf 3:36de8b9e4b1a 1743 /// <summary>
darienf 3:36de8b9e4b1a 1744 /// Search for a device attached to I2C bus,
darienf 3:36de8b9e4b1a 1745 /// given a list of poossible device addresses,
darienf 3:36de8b9e4b1a 1746 /// and a constant device ID register to test.
darienf 3:36de8b9e4b1a 1747 /// </summary>
darienf 3:36de8b9e4b1a 1748 /// <param name="I2C_DeviceAddressList_8bitLeftJustified">List of possible I2C device addresses to test. I2C device addresses are 8-bit left-justified (LSB=R/w bit)</param>
darienf 3:36de8b9e4b1a 1749 /// <param name="DeviceId_RegAddress">device register address of a constant "Device ID" register</param>
darienf 3:36de8b9e4b1a 1750 /// <param name="DeviceId_RegValue_Expect">register value of the constant "Device ID" register</param>
darienf 3:36de8b9e4b1a 1751 /// <returns>I2C device addresses, or 0 if not found</returns>
darienf 3:36de8b9e4b1a 1752 public byte SearchI2CdeviceAddressList(byte[] I2C_DeviceAddressList_8bitLeftJustified, byte DeviceId_RegAddress, byte DeviceId_RegValue_Expect)
darienf 3:36de8b9e4b1a 1753 {
darienf 3:36de8b9e4b1a 1754 // https://jira.maxim-ic.com/browse/OS24EVK-57 accelerometer support: SearchI2CdeviceAddressList optional I2C device
darienf 3:36de8b9e4b1a 1755 foreach (byte test_I2C_Address in I2C_DeviceAddressList_8bitLeftJustified)
darienf 3:36de8b9e4b1a 1756 {
darienf 3:36de8b9e4b1a 1757 //try
darienf 3:36de8b9e4b1a 1758 //{
darienf 3:36de8b9e4b1a 1759 byte[] data = new byte[2];
darienf 3:36de8b9e4b1a 1760 byte[] reg = new byte[1];
darienf 3:36de8b9e4b1a 1761 reg[0] = (byte)DeviceId_RegAddress;
darienf 3:36de8b9e4b1a 1762 // readI2C should already take care of mutex lock / unlock
darienf 3:36de8b9e4b1a 1763 // https://jira.maxim-ic.com/browse/OS24EVK-59 avoid NACK exception in SearchI2CdeviceAddressList
darienf 3:36de8b9e4b1a 1764 bool ignoreNACK = true;
darienf 3:36de8b9e4b1a 1765 int status = readI2C(test_I2C_Address, 2, 1, data, reg, ignoreNACK);
darienf 3:36de8b9e4b1a 1766 if (status == HID.I2C_NACK_ERROR)
darienf 3:36de8b9e4b1a 1767 {
darienf 3:36de8b9e4b1a 1768 continue;
darienf 3:36de8b9e4b1a 1769 }
darienf 3:36de8b9e4b1a 1770 else
darienf 3:36de8b9e4b1a 1771 {
darienf 3:36de8b9e4b1a 1772 byte DeviceId_RegValue_Actual = data[0];
darienf 3:36de8b9e4b1a 1773 if (DeviceId_RegValue_Actual == DeviceId_RegValue_Expect)
darienf 3:36de8b9e4b1a 1774 {
darienf 3:36de8b9e4b1a 1775 return test_I2C_Address;
darienf 3:36de8b9e4b1a 1776 }
darienf 3:36de8b9e4b1a 1777 }
darienf 3:36de8b9e4b1a 1778 //}
darienf 3:36de8b9e4b1a 1779 //catch (Exception)
darienf 3:36de8b9e4b1a 1780 //{
darienf 3:36de8b9e4b1a 1781 // // myHID.readI2C can throw Exception("invalid I2C address");
darienf 3:36de8b9e4b1a 1782 //}
darienf 3:36de8b9e4b1a 1783 }
darienf 3:36de8b9e4b1a 1784 return 0;
darienf 3:36de8b9e4b1a 1785 }
darienf 3:36de8b9e4b1a 1786
darienf 3:36de8b9e4b1a 1787 }
darienf 3:36de8b9e4b1a 1788 }