repo time

Dependencies:   mbed MAX14720 MAX30205 USBDevice

Committer:
darienf
Date:
Tue Apr 06 06:41:40 2021 +0000
Revision:
20:6d2af70c92ab
another repo

Who changed what in which revision?

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