vc2013 开发 winusb 简单测试程序 基于 nu_bridge

nu_bridge是新唐的牛桥,借助该USB工具,pc端可以方便的调试外部的SPI, I2C设备。
新唐提供的驱动包中已经包含了winusb的驱动。
在测试下面的程序之前需要安装驱动。

这里是用vs2013 开发一个简单的winUSB控制台测试程序,帮助入门winUSB的API。
新建一个控制台工程:nu_bridge_simple
这里写图片描述

这里写图片描述

点击完成

添加文件:
这里写图片描述

文件:device.cpp

#include "pch.h"

#include <SetupAPI.h>

HRESULT
RetrieveDevicePath(
    _Out_bytecap_(BufLen) LPTSTR DevicePath,
    _In_                  ULONG  BufLen,
    _Out_opt_             PBOOL  FailureDeviceNotFound
    );

HRESULT
OpenDevice(
    _Out_     PDEVICE_DATA DeviceData,
    _Out_opt_ PBOOL        FailureDeviceNotFound
    )
/*++

Routine description:

    Open all needed handles to interact with the device.

    If the device has multiple USB interfaces, this function grants access to
    only the first interface.

    If multiple devices have the same device interface GUID, there is no
    guarantee of which one will be returned.

Arguments:

    DeviceData - Struct filled in by this function. The caller should use the
        WinusbHandle to interact with the device, and must pass the struct to
        CloseDevice when finished.

    FailureDeviceNotFound - TRUE when failure is returned due to no devices
        found with the correct device interface (device not connected, driver
        not installed, or device is disabled in Device Manager); FALSE
        otherwise.

Return value:

    HRESULT

--*/
{
    HRESULT hr = S_OK;
    BOOL    bResult;

    DeviceData->HandlesOpen = FALSE;

    hr = RetrieveDevicePath(DeviceData->DevicePath,
                            sizeof(DeviceData->DevicePath),
                            FailureDeviceNotFound);

    if (FAILED(hr)) {

        return hr;
    }

    DeviceData->DeviceHandle = CreateFile(DeviceData->DevicePath,
                                          GENERIC_WRITE | GENERIC_READ,
                                          FILE_SHARE_WRITE | FILE_SHARE_READ,
                                          NULL,
                                          OPEN_EXISTING,
                                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                                          NULL);

    if (INVALID_HANDLE_VALUE == DeviceData->DeviceHandle) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        return hr;
    }

    bResult = WinUsb_Initialize(DeviceData->DeviceHandle,
                                &DeviceData->WinusbHandle);

    if (FALSE == bResult) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        CloseHandle(DeviceData->DeviceHandle);
        return hr;
    }

    DeviceData->HandlesOpen = TRUE;
    return hr;
}

VOID
CloseDevice(
    _Inout_ PDEVICE_DATA DeviceData
    )
/*++

Routine description:

    Perform required cleanup when the device is no longer needed.

    If OpenDevice failed, do nothing.

Arguments:

    DeviceData - Struct filled in by OpenDevice

Return value:

    None

--*/
{
    if (FALSE == DeviceData->HandlesOpen) {

        //
        // Called on an uninitialized DeviceData
        //
        return;
    }

    WinUsb_Free(DeviceData->WinusbHandle);
    CloseHandle(DeviceData->DeviceHandle);
    DeviceData->HandlesOpen = FALSE;

    return;
}
//下面的OSR_DEVICE_INTERFACE是从牛桥的pc端软件copy过来的
static const GUID OSR_DEVICE_INTERFACE =

{ 0x1f4911f2, 0xc55d, 0x4561, { 0x98, 0x7a, 0xbc, 0xfa, 0x74, 0xd5, 0xbb, 0x6d } };

HRESULT
RetrieveDevicePath(
    _Out_bytecap_(BufLen) LPTSTR DevicePath,
    _In_                  ULONG  BufLen,
    _Out_opt_             PBOOL  FailureDeviceNotFound
    )
/*++

Routine description:

    Retrieve the device path that can be used to open the WinUSB-based device.

    If multiple devices have the same device interface GUID, there is no
    guarantee of which one will be returned.

Arguments:

    DevicePath - On successful return, the path of the device (use with CreateFile).

    BufLen - The size of DevicePath's buffer, in bytes

    FailureDeviceNotFound - TRUE when failure is returned due to no devices
        found with the correct device interface (device not connected, driver
        not installed, or device is disabled in Device Manager); FALSE
        otherwise.

Return value:

    HRESULT

--*/
{
    BOOL                             bResult = FALSE;
    HDEVINFO                         deviceInfo;
    SP_DEVICE_INTERFACE_DATA         interfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
    ULONG                            length;
    ULONG                            requiredLength=0;
    HRESULT                          hr;

    if (NULL != FailureDeviceNotFound) {

        *FailureDeviceNotFound = FALSE;
    }

    printf("RetrieveDevicePath \n");
    //
    // Enumerate all devices exposing the interface
    //

    /*
    deviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBApplication1,
                                     NULL,
                                     NULL,
                                     DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
    */

    deviceInfo = SetupDiGetClassDevs(&OSR_DEVICE_INTERFACE,
        NULL,
        NULL,
        DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);


    if (deviceInfo == INVALID_HANDLE_VALUE) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        return hr;
    }

    interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    //
    // Get the first interface (index 0) in the result set
    //
    bResult = SetupDiEnumDeviceInterfaces(deviceInfo,
                                          NULL,
                                          &OSR_DEVICE_INTERFACE,
                                          0,
                                          &interfaceData);

    if (FALSE == bResult) {

        //
        // We would see this error if no devices were found
        //
        if (ERROR_NO_MORE_ITEMS == GetLastError() &&
            NULL != FailureDeviceNotFound) {

            *FailureDeviceNotFound = TRUE;
        }

        hr = HRESULT_FROM_WIN32(GetLastError());
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    //
    // Get the size of the path string
    // We expect to get a failure with insufficient buffer
    //
    bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,
                                              &interfaceData,
                                              NULL,
                                              0,
                                              &requiredLength,
                                              NULL);

    if (FALSE == bResult && ERROR_INSUFFICIENT_BUFFER != GetLastError()) {

        hr = HRESULT_FROM_WIN32(GetLastError());
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    //
    // Allocate temporary space for SetupDi structure
    //
    detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)
        LocalAlloc(LMEM_FIXED, requiredLength);

    if (NULL == detailData)
    {
        hr = E_OUTOFMEMORY;
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    length = requiredLength;

    //
    // Get the interface's path string
    //
    bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo,
                                              &interfaceData,
                                              detailData,
                                              length,
                                              &requiredLength,
                                              NULL);

    if(FALSE == bResult)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        LocalFree(detailData);
        SetupDiDestroyDeviceInfoList(deviceInfo);
        return hr;
    }

    //
    // Give path to the caller. SetupDiGetDeviceInterfaceDetail ensured
    // DevicePath is NULL-terminated.
    //
    hr = StringCbCopy(DevicePath,
                      BufLen,
                      detailData->DevicePath);

    LocalFree(detailData);
    SetupDiDestroyDeviceInfoList(deviceInfo);

    return hr;
}

其中下面这句话比较关键是和驱动配合使用的:

//下面的OSR_DEVICE_INTERFACE是从牛桥的pc端软件copy过来的
static const GUID OSR_DEVICE_INTERFACE =

{ 0x1f4911f2, 0xc55d, 0x4561, { 0x98, 0x7a, 0xbc, 0xfa, 0x74, 0xd5, 0xbb, 0x6d } };

文件:device.h

//
// Define below GUIDs
//
#include <initguid.h>

//
// Device Interface GUID.
// Used by all WinUsb devices that this application talks to.
// Must match "DeviceInterfaceGUIDs" registry value specified in the INF file.
// cce59234-f9f6-43c8-9007-a61e760fb59f
//

//DEFINE_GUID(GUID_DEVINTERFACE_USBApplication1,
//    0xcce59234,0xf9f6,0x43c8,0x90,0x07,0xa6,0x1e,0x76,0x0f,0xb5,0x9f);

//下面这句话没有用到
DEFINE_GUID(GUID_DEVINTERFACE_USBApplication1,
    0x1f4911f2, 0xc55d, 0x4561, 0x98, 0x7a, 0xbc, 0xfa, 0x74, 0xd5, 0xbb, 0x6d);



typedef struct _DEVICE_DATA {

    BOOL                    HandlesOpen;
    WINUSB_INTERFACE_HANDLE WinusbHandle;
    HANDLE                  DeviceHandle;
    TCHAR                   DevicePath[MAX_PATH];

} DEVICE_DATA, *PDEVICE_DATA;

HRESULT
OpenDevice(
    _Out_     PDEVICE_DATA DeviceData,
    _Out_opt_ PBOOL        FailureDeviceNotFound
    );

VOID
CloseDevice(
    _Inout_ PDEVICE_DATA DeviceData
    );

文件:pch.h

#include <Windows.h>
#include <tchar.h>
#include <strsafe.h>
#include <winusb.h>
#include <usb.h>

#include "device.h"

将nu_bridge_simple.cpp中的所有内容删掉:
替换为如下内容:

// nu_bridge_simple.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"

#include "pch.h"

#include <stdio.h>

LONG __cdecl
_tmain(
LONG     Argc,
LPTSTR * Argv
)
/*++

Routine description:

Sample program that communicates with a USB device using WinUSB

--*/
{
    DEVICE_DATA           deviceData;
    HRESULT               hr;
    USB_DEVICE_DESCRIPTOR deviceDesc;
    BOOL                  bResult;
    BOOL                  noDevice;
    ULONG                 lengthReceived;

    UNREFERENCED_PARAMETER(Argc);
    UNREFERENCED_PARAMETER(Argv);

    //
    // Find a device connected to the system that has WinUSB installed using our
    // INF
    //
    hr = OpenDevice(&deviceData, &noDevice);

    if (FAILED(hr)) {

        if (noDevice) {

            printf("Device not connected or driver not installed\n");

        }
        else {

            printf("Failed looking for device, HRESULT 0x%x\n", hr);
        }

        return 0;
    }

    //
    // Get device descriptor
    //
    bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle,
        USB_DEVICE_DESCRIPTOR_TYPE,
        0,
        0,
        (PBYTE)&deviceDesc,
        sizeof(deviceDesc),
        &lengthReceived);

    if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {

        printf("Error among LastError %d or lengthReceived %d\n",
            FALSE == bResult ? GetLastError() : 0,
            lengthReceived);
        CloseDevice(&deviceData);
        return 0;
    }

    //
    // Print a few parts of the device descriptor
    //
    printf("Device found: VID_%04X&PID_%04X; bcdUsb %04X\n",
        deviceDesc.idVendor,
        deviceDesc.idProduct,
        deviceDesc.bcdUSB);

    getchar();

    CloseDevice(&deviceData);
    return 0;
}

添加完文件之后,需要添加库:
这里写图片描述

添加的库的名称是:
winusb.lib
setupapi.lib

这里写图片描述

将牛桥插入PC 的usb端口,然后编译程序,然后执行

运行效果如下:

RetrieveDevicePath
Device found: VID_0416&PID_3101; bcdUsb 0110

然后按下键盘任意键,退出程序。

参考内容:
1.How to Access a USB Device by Using WinUSB Functions
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device

2.Write a Windows desktop app based on the WinUSB template
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/how-to-write-a-windows-desktop-app-that-communicates-with-a-usb-device

3.How to Access a USB Device by Using WinUSB Functions
https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/using-winusb-api-to-communicate-with-a-usb-device

参考软件:

[0508] NuBridge SW/NuBridge.exe 源码 vs2008 MFC

继续:
将nu_bridge_simple.cpp中的所有内容删掉:
替换为如下内容:

// nu_bridge_simple.cpp : 定义控制台应用程序的入口点。
//
//#include "stdafx.h"

#include "pch.h"

#include <stdio.h>



int NU_SetDeviceSpiMasteMode(_In_  WINUSB_INTERFACE_HANDLE InterfaceHandle)
{
    WINUSB_SETUP_PACKET SetupPacket;
    SetupPacket.RequestType = 0x42;
    SetupPacket.Request = 1;
    SetupPacket.Value = 0;
    SetupPacket.Index = 0;
    SetupPacket.Length = 0;

    WinUsb_ControlTransfer(InterfaceHandle, SetupPacket, 0, 0, NULL, 0);

    return 0;
}


int NU_SetDeviceLED(_In_  WINUSB_INTERFACE_HANDLE InterfaceHandle)
{
    WINUSB_SETUP_PACKET SetupPacket;
    SetupPacket.RequestType = 0x40;
    SetupPacket.Request = 0;
    SetupPacket.Value = 0;
    SetupPacket.Index = 0;
    SetupPacket.Length = 0;


    printf("NU_SetDeviceLED\n");
    WinUsb_ControlTransfer(InterfaceHandle, SetupPacket, 0, 0, NULL, 0);

    return TRUE;
}


BOOL GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed)
{
    if (!pDeviceSpeed || hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    ULONG length = sizeof(UCHAR);

    bResult = WinUsb_QueryDeviceInformation(hDeviceHandle, DEVICE_SPEED, &length, pDeviceSpeed);
    if (!bResult)
    {
        printf("Error getting device speed: %d.\n", GetLastError());
        goto done;
    }

    if (*pDeviceSpeed == LowSpeed)
    {
        printf("Device speed: %d (Low speed).\n", *pDeviceSpeed);
        goto done;
    }
    if (*pDeviceSpeed == FullSpeed)
    {
        printf("Device speed: %d (Full speed).\n", *pDeviceSpeed);
        goto done;
    }
    if (*pDeviceSpeed == HighSpeed)
    {
        printf("Device speed: %d (High speed).\n", *pDeviceSpeed);
        goto done;
    }

done:
    return bResult;
}


struct PIPE_ID
{
    UCHAR  PipeInId;
    UCHAR  PipeOutId;
};

BOOL QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));

    WINUSB_PIPE_INFORMATION  Pipe;
    ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION));


    bResult = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &InterfaceDescriptor);

    if (bResult)
    {
        for (int index = 0; index < InterfaceDescriptor.bNumEndpoints; index++)
        {
            bResult = WinUsb_QueryPipe(hDeviceHandle, 0, index, &Pipe);

            if (bResult)
            {
                if (Pipe.PipeType == UsbdPipeTypeControl)
                {
                    printf("Endpoint index: %d Pipe type: Control Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                }
                if (Pipe.PipeType == UsbdPipeTypeIsochronous)
                {
                    printf("Endpoint index: %d Pipe type: Isochronous Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                }
                if (Pipe.PipeType == UsbdPipeTypeBulk)
                {
                    if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId))
                    {
                        printf("Endpoint index: %d Pipe type: Bulk Pipe ID: %c.\n", index, Pipe.PipeType, Pipe.PipeId);
                        pipeid->PipeInId = Pipe.PipeId;
                    }
                    if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId))
                    {
                        printf("Endpoint index: %d Pipe type: Bulk Pipe ID: %c.\n", index, Pipe.PipeType, Pipe.PipeId);
                        pipeid->PipeOutId = Pipe.PipeId;
                    }

                }
                if (Pipe.PipeType == UsbdPipeTypeInterrupt)
                {
                    printf("Endpoint index: %d Pipe type: Interrupt Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                }
            }
            else
            {
                continue;
            }
        }
    }

done:
    return bResult;
}


BOOL SendDatatoDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;


    UCHAR bars = 0;

    WINUSB_SETUP_PACKET SetupPacket;
    ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
    ULONG cbSent = 0;

    //Set bits to light alternate bars
    for (short i = 0; i < 7; i += 2)
    {
        bars += 1 << i;
    }

    //Create the setup packet
    SetupPacket.RequestType = 0;
    SetupPacket.Request = 0xD8;
    SetupPacket.Value = 0;
    SetupPacket.Index = 0;
    SetupPacket.Length = sizeof(UCHAR);

    bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, &bars, sizeof(UCHAR), &cbSent, 0);
    if (!bResult)
    {
        goto done;
    }

    printf("Data sent: %d \nActual data transferred: %d.\n", sizeof(bars), cbSent);


done:
    return bResult;

}


BOOL NU_WritePipe(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID,UCHAR *buf, ULONG len)
{
    printf("NU_WritePipe\n");
    ULONG nBytesSent = 0;

    if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID )
    {
        return FALSE;
    }

    nBytesSent = 0;

    WinUsb_WritePipe(hDeviceHandle, *pID, buf, len, &nBytesSent, 0);

    if (nBytesSent != len)
    {
        return FALSE;
    }
    return TRUE;
}

BOOL Nu_WriteCmd(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID)
{

    UCHAR data[] = { 0x01,0x01,0x53 ,0x01  ,0x00 ,0x00 ,0x08 ,0x06  ,0x90 ,0x00 ,0x00 ,0x00  ,0x00 ,0x00 ,0x50 };

    NU_WritePipe(hDeviceHandle, pID,data,15);

    UCHAR tag[] = { 0x00, 0x01 };

    NU_WritePipe(hDeviceHandle, pID, tag, 2);

    return TRUE;
}


ULONG NU_ReadPipe(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, UCHAR *buf, ULONG len)
{
    ULONG nBytesRead = 0;
    printf("NU_ReadPipe\n");

    WinUsb_ReadPipe(hDeviceHandle, *pID, (unsigned char*)buf, len, &nBytesRead, 0);

    return nBytesRead;
}

BOOL Nu_ReadCmd(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID)
{   
    UCHAR data[64];

    int len;

    int i;

    memset(data, 0, 64);


    len = NU_ReadPipe(hDeviceHandle, pID, data,64);

    printf("Nu_ReadCmd len= %d\n", len);

    for (i = 0; i < len; i++){

        printf("%x,", data[i]);
    }

    printf("\n");

    return TRUE;
}


BOOL NuWriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    UCHAR szBuffer[] = "Hello World";
    ULONG cbSize = strlen((const char *)szBuffer);
    ULONG cbSent = 0;

    bResult = WinUsb_WritePipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbSent, 0);
    if (!bResult)
    {
        goto done;
    }

    printf("Wrote to pipe %d: %s \nActual data transferred: %d.\n", *pID, szBuffer, cbSent);
    *pcbWritten = cbSent;


done:
    return bResult;

}


BOOL WriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    UCHAR szBuffer[] = "Hello World";
    ULONG cbSize = strlen((const char *)szBuffer);
    ULONG cbSent = 0;

    bResult = WinUsb_WritePipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbSent, 0);
    if (!bResult)
    {
        goto done;
    }

    printf("Wrote to pipe %d: %s \nActual data transferred: %d.\n", *pID, szBuffer, cbSent);
    *pcbWritten = cbSent;


done:
    return bResult;

}


BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG cbSize)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    UCHAR* szBuffer = (UCHAR*)LocalAlloc(LPTR, sizeof(UCHAR)*cbSize);

    ULONG cbRead = 0;

    bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbRead, 0);
    if (!bResult)
    {
        goto done;
    }

    printf("Read from pipe %d: %s \nActual data read: %d.\n", *pID, szBuffer, cbRead);


done:
    LocalFree(szBuffer);
    return bResult;

}



int _tmain(int argc, _TCHAR* argv[])
{

    DEVICE_DATA           deviceData;
    HRESULT               hr;
    USB_DEVICE_DESCRIPTOR deviceDesc;

    BOOL                  noDevice;
    ULONG                 lengthReceived;



    BOOL bResult = TRUE;

    PIPE_ID PipeID;

    HANDLE hDeviceHandle = INVALID_HANDLE_VALUE;
    WINUSB_INTERFACE_HANDLE hWinUSBHandle = INVALID_HANDLE_VALUE;

    UCHAR DeviceSpeed;
    ULONG cbSize = 0;


    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);

    //
    // Find a device connected to the system that has WinUSB installed using our
    // INF
    //
    hr = OpenDevice(&deviceData, &noDevice);

    if (FAILED(hr)) {

        if (noDevice) {

            printf("Device not connected or driver not installed\n");

        }
        else {

            printf("Failed looking for device, HRESULT 0x%x\n", hr);
        }

        return 0;
    }



    hWinUSBHandle = deviceData.WinusbHandle;

    hDeviceHandle = deviceData.DeviceHandle;


    bResult = GetUSBDeviceSpeed(hWinUSBHandle, &DeviceSpeed);
    if(!bResult)
    {
        goto done;
    }

    bResult = QueryDeviceEndpoints(hWinUSBHandle, &PipeID);
    if(!bResult)
    {
        goto done;
    }

#if 0
    bResult = NU_SetDeviceLED(hWinUSBHandle);
    if(!bResult)
    {
        goto done;
    }
#endif

    printf("PipeID.PipeInId  = %d\n", PipeID.PipeInId);

    printf("PipeID.PipeOutId = %d\n", PipeID.PipeOutId);

    NU_SetDeviceSpiMasteMode(hWinUSBHandle);

    Nu_WriteCmd(hWinUSBHandle, &PipeID.PipeOutId);

    Nu_ReadCmd(hWinUSBHandle, &PipeID.PipeInId);

    system("PAUSE");

done:
    CloseHandle(hDeviceHandle);
    WinUsb_Free(hWinUSBHandle);

    return 0;
}

运行效果:

RetrieveDevicePath
Device speed: 1 (Low speed).
Endpoint index: 0 Pipe type: Bulk Pipe ID: 
Endpoint index: 1 Pipe type: Bulk Pipe ID: 
PipeID.PipeInId  = 132
PipeID.PipeOutId = 5
NU_WritePipe
NU_WritePipe
NU_ReadPipe
Nu_ReadCmd len= 10
1,0,6,0,ff,ff,ff,ff,51,14,
请按任意键继续. . .

End

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值