You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
8.5 KiB

5 years ago
  1. /*******************************************************************************
  2. *
  3. * FindAppUART.cpp - PC command line utility for enumerating MSP430 EVM's
  4. * Application UARTs.
  5. *
  6. * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * Neither the name of Texas Instruments Incorporated nor the names of
  21. * its contributors may be used to endorse or promote products derived
  22. * from this software without specific prior written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. ******************************************************************************/
  37. //------------------------------------------------------------------------------
  38. // Desc: PC command line utility for enumerating MSP430 EVM's Application UARTs.
  39. // The application returns the COM port number of the first UART that is
  40. // found. If this is successful the error code is set to '0'. In case of
  41. // the UART string could not be determined '1' is returned.
  42. //
  43. // The code was developed with the Express Edition of Visual C++ 2008
  44. // http://www.microsoft.com/express/
  45. //
  46. // Ver.: 0.1 (February 2011)
  47. // - Alpha version
  48. //
  49. // Auth: Andreas Dannenberg
  50. // MSP430 Applications
  51. // Texas Instruments, Inc.
  52. //------------------------------------------------------------------------------
  53. // Windows Header Files
  54. #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff
  55. // from Windows headers
  56. #include <windows.h>
  57. #include <tchar.h>
  58. #include <shellapi.h>
  59. #include <setupapi.h> // "setupapi.lib" must be linked
  60. // to the project
  61. // C Runtime Header Files
  62. #include <stdlib.h>
  63. #include <malloc.h>
  64. #include <memory.h>
  65. //------------------------------------------------------------------------------
  66. // DWORD WINAPI EnumComPorts(DWORD dwIndex, LPTSTR lptszName,
  67. // DWORD dwNumOfElements)
  68. //
  69. // User-mode code fragment to identify attached VCP COMnn port[s] with a
  70. // specific device instance ID based on USB VID and PID and returns the COMnn
  71. // port that the OS embeds into the device instance ID. When called with
  72. // dwIndex = 0, the function will enumerate all COMPORT class devices and
  73. // return the name of the first one that was found. Subsequent calls using an
  74. // incremented dwIndex parameter can be performed until ERROR_NO_MORE_ITEMS
  75. // is returned.
  76. //
  77. // IN: dwIndex COMPORT class device # 0, 1, 2, ... to check
  78. // dwNumOfElements The size of the lptszName buffer
  79. // OUT: lptszName COMnn name of given device #
  80. // return() ERROR_SUCCESS - lpszName is valid
  81. // ERROR_NO_MORE_ITEMS - End of device list reached
  82. //------------------------------------------------------------------------------
  83. DWORD WINAPI EnumComPorts(DWORD dwIndex, LPTSTR lptszName, DWORD dwNumOfElements)
  84. {
  85. HDEVINFO hDevInfo;
  86. SP_DEVINFO_DATA DeviceInfoData;
  87. DWORD i;
  88. TCHAR *pcParse;
  89. // Create a HDEVINFO with all present devices
  90. hDevInfo = SetupDiGetClassDevs(
  91. NULL,
  92. 0, // Enumerator
  93. 0,
  94. DIGCF_PRESENT | DIGCF_ALLCLASSES);
  95. if (INVALID_HANDLE_VALUE == hDevInfo)
  96. {
  97. return GetLastError();
  98. }
  99. // Enumerate through all devices in set
  100. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  101. for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++)
  102. {
  103. LPTSTR buffer = NULL;
  104. DWORD buffersize = 0;
  105. // Get the device instance ID that is associated with the device information element
  106. while (!SetupDiGetDeviceInstanceId(
  107. hDevInfo,
  108. &DeviceInfoData,
  109. buffer,
  110. buffersize,
  111. &buffersize))
  112. {
  113. if (buffer)
  114. {
  115. LocalFree(buffer);
  116. }
  117. if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
  118. {
  119. // Change the buffer size. Double the size to avoid problems on
  120. // W2K MBCS systems per KB 888609.
  121. buffer = (LPTSTR)LocalAlloc(LPTR, buffersize * 2);
  122. }
  123. else
  124. {
  125. // Error: could not get device instance ID
  126. // Cleanup and return error code
  127. SetupDiDestroyDeviceInfoList(hDevInfo);
  128. return GetLastError();
  129. }
  130. }
  131. if (buffer)
  132. {
  133. // Look for the "Application UART" of common MSP430 EVMs. The application UART
  134. // has an USB VID of 0x0451 (Texas Instruments) and an PID of 0xF432.
  135. const TCHAR testval[] = _T("USB\\VID_0451&PID_F432&MI_00");
  136. if (NULL != _tcsstr(buffer, testval))
  137. {
  138. TCHAR szFriendlyName[MAX_PATH];
  139. if (SetupDiGetDeviceRegistryProperty(
  140. hDevInfo,
  141. &DeviceInfoData,
  142. SPDRP_FRIENDLYNAME,
  143. NULL,
  144. (PBYTE)szFriendlyName,
  145. sizeof(szFriendlyName) - 1,
  146. NULL))
  147. {
  148. // Check if we have reached the dwIndex-th element, if not keep looking
  149. if (dwIndex == 0)
  150. {
  151. // Find pointer to "COM" substring (secure)
  152. szFriendlyName[sizeof(szFriendlyName) - 1] = 0x00;
  153. pcParse = _tcsstr(szFriendlyName, _T("COM"));
  154. if (pcParse != NULL)
  155. {
  156. // Zero-terminate COM port string after last digit
  157. if (!isdigit(pcParse[4])) {
  158. pcParse[4] = 0;
  159. }
  160. else if (!isdigit(pcParse[5])) {
  161. pcParse[5] = 0;
  162. }
  163. else {
  164. pcParse[6] = 0;
  165. }
  166. // Pass string to the return parameter
  167. _tcscpy_s(lptszName, dwNumOfElements, pcParse);
  168. // Cleanup
  169. SetupDiDestroyDeviceInfoList(hDevInfo);
  170. return ERROR_SUCCESS;
  171. }
  172. }
  173. else
  174. {
  175. dwIndex--;
  176. }
  177. }
  178. }
  179. }
  180. }
  181. // Cleanup
  182. SetupDiDestroyDeviceInfoList(hDevInfo);
  183. return ERROR_NO_MORE_ITEMS;
  184. }
  185. //------------------------------------------------------------------------------
  186. // Main application entry point. Simply return the first Application UART
  187. // COM port that was found to STDOUT.
  188. //------------------------------------------------------------------------------
  189. int _tmain(int argc, _TCHAR* argv[])
  190. {
  191. TCHAR szDeviceName[MAX_PATH];
  192. DWORD dwReturnValue;
  193. dwReturnValue = EnumComPorts(0, szDeviceName, _countof(szDeviceName));
  194. if (dwReturnValue == ERROR_SUCCESS) {
  195. _ftprintf_s(stdout, _T("%s\r\n"), szDeviceName);
  196. return 0;
  197. }
  198. return 1;
  199. }