秋月電子通商から発売されているUSB-IO2.0をコマンドラインで操作するプログラムをVC6で作ってみました。
USB-IO2.0制御サンプルを参考にしています。
関連 : 水雲風 USB-IO2.0を使ってrubyからLEDをピカピカさせてみた
usbio2ctrl.exe [ポート1に対する出力値]
// usbio2ctrl.cpp // #include "stdafx.h" #include "UsbIO2Ctrl1.h" int main(int argc, char* argv[]) { if (argc != 2) { printf("usage: %s number\n", argv[0]); return 0; } char in1 = atoi(argv[1]); UsbIO2Ctrl ctrl; DWORD result = ctrl.initialize(); if (result != NO_ERROR) { printf("error:%d\n", result); return -1; } result = ctrl.inout(in1, 0x00); if (result != NO_ERROR) { printf("error:%d\n", result); return -2; } return 0; }
// UsbIO2Ctrl1.cpp: UsbIO2Ctrl // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "UsbIO2Ctrl1.h" namespace { const USHORT VENDOR_ID = 0x1352; const USHORT PRODUCT_ID = 0x121; } UsbIO2Ctrl::UsbIO2Ctrl() { } UsbIO2Ctrl::~UsbIO2Ctrl() { } DWORD UsbIO2Ctrl::initialize() { GUID hidGuid = {0}; ::HidD_GetHidGuid(&hidGuid); HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); DWORD memberIndex = 0; for (memberIndex = 0; ;memberIndex++) { SP_DEVICE_INTERFACE_DATA myDeviceInfoData = {0}; myDeviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); BOOL result = ::SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &hidGuid, memberIndex, &myDeviceInfoData); if (result == FALSE) { return ::GetLastError(); } DWORD needed = 0; result = ::SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &myDeviceInfoData, NULL, 0, &needed, NULL); boost::shared_array<char> detailData(new char[needed]); ::memset(detailData.get(), 0, needed); PSP_DEVICE_INTERFACE_DETAIL_DATA detailDataPtr = (PSP_DEVICE_INTERFACE_DETAIL_DATA)detailData.get(); detailDataPtr->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); DWORD length = 0; result = ::SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &myDeviceInfoData, detailDataPtr, needed, &length, NULL); if (result == FALSE) { return ::GetLastError(); } SECURITY_ATTRIBUTES sa = {0}; sa.nLength = sizeof(SECURITY_ATTRIBUTES); HANDLE hidDevice = ::CreateFile(detailDataPtr->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0); if (hidDevice == INVALID_HANDLE_VALUE) { continue; } m_hidDevice = boost::shared_ptr<void>(hidDevice, ::CloseHandle); HIDD_ATTRIBUTES deviceAttributes; BOOLEAN res = ::HidD_GetAttributes(hidDevice, &deviceAttributes); if (res == FALSE) { return ::GetLastError(); } if ((deviceAttributes.VendorID != VENDOR_ID) || (deviceAttributes.ProductID != PRODUCT_ID)) { continue; } PHIDP_PREPARSED_DATA preparsedData = {0}; ::HidD_GetPreparsedData(hidDevice, &preparsedData); ::HidP_GetCaps(preparsedData, &m_capabilities); return NO_ERROR; } return ERROR_DEVICE_NOT_AVAILABLE; } DWORD UsbIO2Ctrl::inout(char in1, char in2, char* out1, char* out2) { boost::shared_array<char> sendData(new char[64]); ::memset(sendData.get(), 0, 64); boost::shared_array<char> recvData(new char[64]); ::memset(recvData.get(), 0, 64); sendData[0] = 0x20; sendData[1] = 0x01; sendData[2] = in1; sendData[3] = 0x02; sendData[4] = in2; sendData[63] = 0x00; DWORD result = sendRecv(sendData.get(), recvData.get()); if (result != NO_ERROR) { return result; } if (out1 != NULL) { (*out1) = recvData.get()[1]; } if (out2 != NULL) { (*out2) = recvData.get()[2]; } return result; } DWORD UsbIO2Ctrl::sendRecv(char* sendData, char* recvData) { boost::shared_array<char> writeData(new char[m_capabilities.OutputReportByteLength]); ::memset(writeData.get(), 0, m_capabilities.OutputReportByteLength); boost::shared_array<char> readData(new char[m_capabilities.InputReportByteLength]); ::memset(readData.get(), 0, m_capabilities.InputReportByteLength); for (int i = 0; i < 64; i++) { writeData.get()[i + 1] = sendData[i]; } DWORD numberOfBytesWritten = 0; BOOL result = ::WriteFile(m_hidDevice.get(), writeData.get(), m_capabilities.OutputReportByteLength, &numberOfBytesWritten, NULL); if (result == FALSE) { return ::GetLastError(); } do { DWORD numberOfBytesRead = 0; result = ::ReadFile(m_hidDevice.get(), readData.get(), m_capabilities.InputReportByteLength, &numberOfBytesRead, NULL); if (result == FALSE) { return ::GetLastError(); } } while (writeData.get()[64] != readData.get()[64]); for (int j = 0; j < 64; j++) { recvData[j] = readData.get()[j + 1]; } return NO_ERROR; }
// UsbIO2Ctrl1.h: UsbIO2Ctrl // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_USBIO2CTRL1_H__0E3080BB_4959_47D7_9C0F_F6A89A3232BD__INCLUDED_) #define AFX_USBIO2CTRL1_H__0E3080BB_4959_47D7_9C0F_F6A89A3232BD__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class UsbIO2Ctrl { public: UsbIO2Ctrl(); virtual ~UsbIO2Ctrl(); DWORD initialize(); DWORD inout(char in1, char in2, char* out1 = NULL, char* out2 = NULL); DWORD sendRecv(char* sendData, char* recvData); private: boost::shared_ptrm_hidDevice; HIDP_CAPS m_capabilities; }; #endif
#if !defined(AFX_STDAFX_H__4573BBF8_3077_496E_B522_436B91A60FEA__INCLUDED_) #define AFX_STDAFX_H__4573BBF8_3077_496E_B522_436B91A60FEA__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN #include <stdio.h> #include <windows.h> #include <boost/shared_ptr.hpp> #include <boost/shared_array.hpp> #include <setupapi.h> extern "C" { #include <Hidsdi.h> } #endif