📄 tusb3410demo.cpp
字号:
//------------------------------------------------------------------------------
// Name: TUSB3410Demo.cpp
// Func: PC demo application for establishing a serial connection with the
// MSP430-TUSB3410 Reference Design board. The program is part of the
// "MSP430 USB Connectivity using TUSB3410" application note (SLAA276).
// The demo scans all system COM class devices for the TUSB3410 virtual
// COM port (VCP) with the hardware ID as configured in the Windows INF
// driver files. If found, the VCP is opened with a baud rate of 460,800.
// The lower nibble of a received character is output to the console.
// Also, on press or release of the keys 1, 2, 3, and 4, a byte is
// transmitted back to MSP430 demo board containing the updated button
// state. The program is end by pressing <ESC>.
// Ver.: 1.00
// Date: November 2005
// Auth: Andreas Dannenberg
// MSP430/TMS470 Applications
// Texas Instruments Inc.
// Rem.: - File can be build as a console application with any common Win32
// compiler such as Borland C++ or Microsoft Visual C++
// - To successful build this project, the library file 'setupapi.lib'
// has to be linked to the project
//------------------------------------------------------------------------------
// Standard C header files
#include <stdlib.h>
#include <stdio.h>
// Windows header files
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <setupapi.h> // Link library setupapi.lib to the project
//------------------------------------------------------------------------------
// Misc definitions
//------------------------------------------------------------------------------
#define ERROR_WRONG_COM 0xe0000000 // Custom error code, bit 29 is set
#define MAX_COM_SEARCH_INDEX 100 // Max COM # to check
//------------------------------------------------------------------------------
// Globals
//------------------------------------------------------------------------------
HANDLE hCom;
OVERLAPPED OverlappedIn = { 0, 0, 0, 0, 0 };
OVERLAPPED OverlappedOut = { 0, 0, 0, 0, 0 };
BYTE COMBuffer[10];
//------------------------------------------------------------------------------
// Define a GUID as a constant located in this module, instead of as an
// external reference to the constant located in another module.
// (extract from guiddef.h)
//------------------------------------------------------------------------------
#define DECLSPEC_SELECTANY __declspec(selectany)
#undef DEFINE_GUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
EXTERN_C const GUID DECLSPEC_SELECTANY name \
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
//------------------------------------------------------------------------------
// Define the GUID for the COM PORT CLASS of interface. This GUID is used
// by EnumComPorts() to enumerate all existing COM port devices.
//------------------------------------------------------------------------------
DEFINE_GUID(GUID_CLASS_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0,
0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73);
//------------------------------------------------------------------------------
// DWORD WINAPI EnumComPorts(DWORD dwIndex, LPTSTR lpszName)
//
// User-mode code fragment to identify which COMnn port[s] are attached
// to the Texas Instrument UMP (the TUSB3410 or the TUSB5052).
// It checks the hardware ID of the virtual COM port (hard-coded in the
// TI driver INF files) and returns the COMnn port which the OS embeds in
// the "Friendly Name". When called with dwIndex = 0, the function will
// enumerate all COMPORT class devices and return the name of the first
// one that was found. Subsequent calls using an incremented dwIndex
// parameter can be performed until ERROR_NO_MORE_ITEMS is returned.
//
// The TUSB3410 driver includes the ability to customize the "Friendly Name"
// before the "(COMnn)", and the HWID after the "umpport\". The search string
// can be modified here.
// further.
//
// IN: dwIndex CCOMPORT class device # 0, 1, 2, ... to check
// OUT: lpszName COMnn name of given device #
// return() ERROR_SUCCESS - lpszName is valid
// ERROR_WRONG_COM - A COM port was found, but is
// not the one we are looking for
// ERROR_NO_MORE_ITEMS - End of device list reached.
//------------------------------------------------------------------------------
DWORD WINAPI EnumComPorts(DWORD dwIndex, LPTSTR lpszName)
{
const TCHAR szHardwareIDUmp[] = "umpport\\VID_0451_BEEF_com";
static HDEVINFO g_hdi = INVALID_HANDLE_VALUE; // Setup API enum handle
SP_DEVICE_INTERFACE_DATA did;
SP_DEVINFO_DATA devinfo;
PSP_DEVICE_INTERFACE_DETAIL_DATA pidd;
DWORD dwNeeded = 0;
TCHAR szHardwareID[60];
TCHAR szFriendlyName[60];
PTCHAR pcParse;
lpszName[0] = 0; // Default to empty string
// Open new enumeration if needed
if (dwIndex == 0)
{
// Close open device interface enum set if any
if (g_hdi != INVALID_HANDLE_VALUE)
SetupDiDestroyDeviceInfoList(g_hdi);
// Enumerate all devices present (DIGCF_PRESENT)
g_hdi = (HDEVINFO)SetupDiGetClassDevs((CONST LPGUID)&GUID_CLASS_COMPORT,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (g_hdi == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
}
// Get next device interface data ('dwIndex')
did.cbSize = sizeof(did);
if (!SetupDiEnumDeviceInterfaces(g_hdi, NULL,
(CONST LPGUID)&GUID_CLASS_COMPORT, dwIndex, &did))
{
return GetLastError();
}
// Get interface detail data size
// (Note: function returns ERROR_INSUFFICIENT_BUFFER, and sets the
// parameter dwNeeded accordingly)
if (!SetupDiGetDeviceInterfaceDetail(g_hdi, &did, NULL, 0, &dwNeeded, NULL))
{
// Ignore ERROR_INSUFFICIENT_BUFFER
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return GetLastError();
}
// Allocate the buffer for interface details
pidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)calloc(dwNeeded, 1);
if (pidd == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
pidd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
devinfo.cbSize = sizeof(devinfo);
// Get interface details
if (!SetupDiGetDeviceInterfaceDetail(g_hdi,
&did, pidd, dwNeeded, NULL, &devinfo))
{
return GetLastError();
}
// Free allocated memory
free(pidd);
// Read out hardware ID from registry
if (!SetupDiGetDeviceRegistryProperty(
g_hdi,
&devinfo,
SPDRP_HARDWAREID,
NULL,
(unsigned char *)szHardwareID,
sizeof(szHardwareID) - 1,
NULL))
{
// Ignore ERROR_INSUFFICIENT_BUFFER
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return GetLastError();
}
// Compare hardware ID, exit if mismatch
if (strstr(szHardwareID, szHardwareIDUmp) == NULL)
{
return ERROR_WRONG_COM;
}
// Read out friendly name from registry
if (!SetupDiGetDeviceRegistryProperty(
g_hdi,
&devinfo,
SPDRP_FRIENDLYNAME,
NULL,
(unsigned char *)szFriendlyName,
sizeof(szFriendlyName) - 1,
NULL))
{
// Ignore ERROR_INSUFFICIENT_BUFFER
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return GetLastError();
}
// Find pointer to "COM" substring
pcParse = strstr(szFriendlyName, "COM");
if (pcParse == NULL)
{
return ERROR_WRONG_COM; // "COM" not found!
}
// Zero-terminate COM port string after last digit
if (!isdigit(pcParse[4]))
pcParse[4] = 0;
else if (!isdigit(pcParse[5]))
pcParse[5] = 0;
else
pcParse[6] = 0;
// Pass string to the return parameter
strcpy(lpszName, pcParse);
return ERROR_SUCCESS;
}
//------------------------------------------------------------------------------
// void CALLBACK FileIOCompletionRoutine(DWORD dwErrorCode,
// DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
//
// This function gets called upon file I/O completion. It reads out the
// received data from COMBuffer[], sets the global MSP430ButtonState variable,
// and displays the updated button status.
//
// IN: dwErrorCode
// dwNumberOfBytesTransfered
// lpOverlapped
// hCom
// COMBuffer[]
// OUT: MSP430ButtonState
//------------------------------------------------------------------------------
void CALLBACK FileIOCompletionRoutine(DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
{
// Data received?
if (dwErrorCode == 0 && dwNumberOfBytesTransfered)
{
// Process lower 4 bits of RX'ed byte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -