0

我遇到了一个与 winusbReadpipe 函数相关的问题。我正在使用 Pic18f4550 Mc(XC8 编译器)和 VC ++ 2013(MFC)。

我只是想从设备/主机读取和写入。Microchip 提供的示例程序运行良好,我能够从主机向设备中的所有端点 01、02、03 发送数据。

但是我无法阅读从设备到主机的任何反馈。我正在两个单独的线程中读取和写入数据。我的想法是只阅读在我的演示板上按下的按钮的反馈,或者至少是回显命令。看来,它只是在读取功能中输入一次,然后就停止了。不确定。

我尝试通过互联网搜索并实施了不同论坛中给出的所有建议,但迄今为止没有成功。最糟糕的是我试图在 Microchip 论坛上发布我的查询,但无法让自己注册,它总是说管理员会批准我的 ID,但还没有发生任何事情。

下面是我的设备端和主机端代码。请告诉我是否还有其他需要。

我期待您对此的支持。

谢谢,

拉胡尔


VC++ 代码:


阅读线程代码


UINT CUsbHighSpeedDlg::ReadThread()
   {
      while (true)
      {
        if (AttachedState == TRUE)  //Do not try to use the read/write handles unless the USB device is attached and ready
        {
            m_DebugVal7.SetWindowTextW(TEXT("INSIDE read //pipe"));

WinUsb_ReadPipe(MyWinUSBInterfaceHandle, 0x81, &INBuffer[0], 64, &BytesRead, NULL);

            if (INBuffer[0] = 0x81)
            {
                m_DebugVal5.SetWindowTextW(TEXT("button true"));
            }

            if ((INBuffer[0] = 0x81) && (INBuffer[1] = 0x00))
                {
                    PushbuttonPressed = TRUE;
                    m_DebugVal5.SetWindowTextW(TEXT("button true"));
                }

                if ((INBuffer[0] = 0x81) && (INBuffer[1] = 0x01))
                {
                    PushbuttonPressed = FALSE;
                    m_DebugVal6.SetWindowTextW(TEXT("button False"));
                }

                }
        }   return 0;
}

在 VC++ 中声明的用于使用读/写管道函数的头文件


//WinUsb_Initialize() needs to be called before the application can begin sending/receiving data with the USB device.

[DllImport("Winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_Initialize", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_Initialize(
    _In_  HANDLE                   DeviceHandle,
    _Out_ PWINUSB_INTERFACE_HANDLE InterfaceHandle
    );

//WinUsb_WritePipe() is the basic function used to write data to the USB device (sends data to OUT endpoints on the device)
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_WritePipe", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_WritePipe(
    _In_      WINUSB_INTERFACE_HANDLE InterfaceHandle,
    _In_      UCHAR                   PipeID,
    _In_      PUCHAR                  Buffer,
    _In_      ULONG                   BufferLength,
    _Out_opt_ PULONG                  LengthTransferred,
    _In_opt_  LPOVERLAPPED            Overlapped
    );


//WinUsb_ReadPipe() is the basic function used to read data from the USB device (polls for and obtains data from
//IN endpoints on the device)
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_ReadPipe", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_ReadPipe(
    _In_      WINUSB_INTERFACE_HANDLE InterfaceHandle,
    _In_      UCHAR                   PipeID,
    _Out_     PUCHAR                  Buffer,
    _In_      ULONG                   BufferLength,
    _Out_opt_ PULONG                  LengthTransferred,
    _In_opt_  LPOVERLAPPED            Overlapped
    );



//WinUsb_SetPipePolicy() can be used to configure the behavior of the WinUSB use of the specified endpoint
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_SetPipePolicy", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_SetPipePolicy(
    _In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
    _In_ UCHAR                   PipeID,
    _In_ ULONG                   PolicyType,
    _In_ ULONG                   ValueLength,
    _In_ PVOID                   Value
    );


//WinUsb_Free() is used to free up resources/close the handle that was returned when calling WinUsb_Initialize()
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_Free", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_Free(
    _In_  WINUSB_INTERFACE_HANDLE InterfaceHandle
    );

//WinUsb_FlushPipe() is used to discard any data that may be "cached in a pipe".
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_Free", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_FlushPipe(
    _In_  WINUSB_INTERFACE_HANDLE InterfaceHandle,
    _In_  UCHAR PipeID
    );

微控制器代码


变量声明部分


#elif defined(__XC8) && defined(FIXED_ADDRESS_MEMORY)
    USB_VOLATILE uint8_t EP1OUTEvenBuffer[64] @ EP1_EVEN_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP1OUTOddBuffer[64]  @ EP1_ODD_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP2OUTEvenBuffer[64] @ EP2_EVEN_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP2OUTOddBuffer[64]  @ EP2_ODD_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP3OUTEvenBuffer[64] @ EP3_EVEN_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP3OUTOddBuffer[64]  @ EP3_ODD_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP1INEvenBuffer[64] @ EP1IN_EVEN_DATA_BUFFER_ADDRESS;
    USB_VOLATILE uint8_t EP1INOddBuffer[64]  @ EP1IN_ODD_DATA_BUFFER_ADDRESS;
#else

#define FIXED_ADDRESS_MEMORY

#define EP1_EVEN_DATA_BUFFER_ADDRESS    0x480
#define EP1_ODD_DATA_BUFFER_ADDRESS     0x4C0

#define EP2_EVEN_DATA_BUFFER_ADDRESS    0x500
#define EP2_ODD_DATA_BUFFER_ADDRESS     0x540

#define EP3_EVEN_DATA_BUFFER_ADDRESS    0x580
#define EP3_ODD_DATA_BUFFER_ADDRESS     0x5C0

#define EP1IN_EVEN_DATA_BUFFER_ADDRESS    0x600 //  NEW MEMORY ADDRESS DECLARED
#define EP1IN_ODD_DATA_BUFFER_ADDRESS     0x640//  NEW MEMORY ADDRESS DECLARED

#endif //FIXED_MEMORY_ADDRESS

描述符


/* Device Descriptor */
const USB_DEVICE_DESCRIPTOR device_dsc=
{
    0x12,                   // Size of this descriptor in bytes
    USB_DESCRIPTOR_DEVICE,  // DEVICE descriptor type
    0x0200,                 // USB Spec Release Number in BCD format        
    0x00,                   // Class Code
    0x00,                   // Subclass code
    0x00,                   // Protocol code
    USB_EP0_BUFF_SIZE,      // Max packet size for EP0, see usb_config.h
    0x04D8,                 // Vendor ID: 0x04D8 is Microchip's Vendor ID
    0x0052,                 // Product ID: 0x0052
    0x0000,                 // Device release number in BCD format
    0x01,                   // Manufacturer string index
    0x02,                   // Product string index
    0x00,                   // Device serial number string index
    0x01                    // Number of possible configurations
};

/* Configuration 1 Descriptor */
const uint8_t configDescriptor1[]={
    /* Configuration Descriptor */
    0x09,//sizeof(USB_CFG_DSC),    // Size of this descriptor in bytes
    USB_DESCRIPTOR_CONFIGURATION,                // CONFIGURATION descriptor type
    0x2E,0x00,            // Total length of data for this cfg
    1,                      // Number of interfaces in this cfg
    1,                      // Index value of this configuration
    0,                      // Configuration string index
    _DEFAULT | _SELF,               // Attributes, see usb_device.h
    50,                     // Max power consumption (2X mA)

    /* Interface Descriptor */
    0x09,//sizeof(USB_INTF_DSC),   // Size of this descriptor in bytes
    USB_DESCRIPTOR_INTERFACE,               // INTERFACE descriptor type
    0,                      // Interface Number
    0,                      // Alternate Setting Number
    4,                      // Number of endpoints in this intf
    0xFF,                   // Class code
    0xFF,                   // Subclass code
    0xFF,                   // Protocol code
    0,                      // Interface string index

    /* Endpoint Descriptor */
    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP01_OUT,                  //EndpointAddress
    _BULK,                       //Attributes
    64,0x00,                    //size
    1,                         //Interval

    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP02_OUT,                   //EndpointAddress
    _BULK,                       //Attributes
    64,0x00,                    //size
    1,                          //Interval

    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP03_OUT,                   //EndpointAddress
    _BULK,                       //Attributes
    64,0x00,                    //size
    1,                          //Interval

     0x07,                       /*sizeof(USB_EP_DSC)*/// New Endpoint for Sending Data To Host
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP01_IN,                   //EndpointAddress// VALUE MODIFED FOR SENDING DATA
    _BULK,                       //Attributes
    64,0x00,                    //size
    1                          //Interval

};

为批量传输初始化 USB


void APP_DeviceVendorThroughputTestInitialize()
{
    EP1OUTEvenHandle = NULL;
    EP2OUTEvenHandle = NULL;
    EP3OUTEvenHandle = NULL;
    EP1INEvenHandle = NULL;

    EP1OUTOddHandle = NULL;
    EP2OUTOddHandle = NULL;
    EP3OUTOddHandle = NULL;
    EP1INOddHandle = NULL;

    //Now that we are configured, enable the endpoints for use in the demo
    //  and start the initial transfers
    USBEnableEndpoint(_EP01_OUT,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(2,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(4,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(_EP01_IN,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    //Prepare the OUT endpoints to receive the first packets from the host.

    EP1OUTEvenHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTEvenBuffer,64);   //First 64-bytes of data sent to EP1 OUT will arrive in the even buffer.
    EP1OUTOddHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTOddBuffer,64); //Second 64-bytes of data sent to EP1 OUT will arrive in the odd buffer.
    EP1OUTEvenNeedsServicingNext = true;    //Used to keep track of which buffer will contain the next sequential data packet.

    EP2OUTEvenHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTEvenBuffer,64);
    EP2OUTOddHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTOddBuffer,64);
    EP2OUTEvenNeedsServicingNext = true;    //Used to keep track of which buffer will contain the next sequential data packet.

    EP3OUTEvenHandle = USBTransferOnePacket(4, OUT_FROM_HOST,(uint8_t*)&EP3OUTEvenBuffer,64);
    EP3OUTOddHandle = USBTransferOnePacket(4, OUT_FROM_HOST,(uint8_t*)&EP3OUTOddBuffer,64);
    EP3OUTEvenNeedsServicingNext = true;    //Used to keep track of which buffer will contain the next sequential data packet.

   EP1INEvenHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64);  //First 64-bytes of data RECIVE to EP3 IN will arrive in the even buffer.
 //  EP1INOddHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INOddBuffer,64);  //Second 64-bytes of data RECIVE to EP3 IN will arrive in the odd buffer.
 //   EP1INEvenNeedsServicingNext = true;
}

数据传输代码,注意:_EP01_Out =0x01 & _EP01_IN =0x81


if(EP1OUTEvenNeedsServicingNext == true)    //Check which buffer (even/odd) the next set of data is going to arrive in
    {
        if(!USBHandleBusy(EP1OUTEvenHandle))    //Check if the endpoint has received any data from the host.
        {

        PORTDbits.RD1=1;
        PORTDbits.RD2=0;
        switch(EP1OUTEvenBuffer[0])                 //Data arrived, check what kind of command might be in the packet of data.
        {
            case 0x81:  //Get push button state command from PC application.
EP1INEvenBuffer[0] = 0x81;
EP1INEvenHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64);
                break;

case 0x82:  //Toggle LED(s) command from PC application.
                 LATDbits.LD3=0;
                 break;

                 case 0x80:  //Toggle LED(s) command from PC application.
                 LATDbits.LD3=1;
                  break;
EP1OUTEvenHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTEvenBuffer,64);
            EP1OUTEvenNeedsServicingNext = false;

        }
    }
else        //else EP1OUTOdd needs servicing next
    {
         if(!USBHandleBusy(EP1OUTOddHandle))        //Check if the endpoint has received any data from the host.
                {

        PORTDbits.RD1=0;
        PORTDbits.RD2=1;
        switch(EP1OUTOddBuffer[0]) //Data arrived, check what kind of command might be in the packet of data.
       {
case 0x81:
  EP1INEvenBuffer[0] = 0x81;
EP1INEvenHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64);
break;

case 0x82:  //Toggle LED(s) command from PC application.
                 LATDbits.LD3=0;
                 break;
  case 0x80:  //Toggle LED(s) command from PC application.
                 LATDbits.LD3=1;
                  break;

}
 EP1OUTOddHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTOddBuffer,64);
            EP1OUTEvenNeedsServicingNext = true;
         }
    }

代码结束


4

1 回答 1

0

我解决了winusb读取管道功能不起作用的问题。

经过大量的点击和试验后,我做了以下更改,并且可以成功读取电位器和按下按钮的反馈。

固定内存地址


#define EP1_EVEN_DATA_BUFFER_ADDRESS    0x480
#define EP1_ODD_DATA_BUFFER_ADDRESS     0x4C0

#define EP2_EVEN_DATA_BUFFER_ADDRESS    0x500
#define EP2_ODD_DATA_BUFFER_ADDRESS     0x540

#define EP3_EVEN_DATA_BUFFER_ADDRESS    0x580
#define EP3_ODD_DATA_BUFFER_ADDRESS     0x5C0

#define EP1IN_EVEN_DATA_BUFFER_ADDRESS    0x600 //  NEW MEMORY ADDRESS DECLARED
#define EP1IN_ODD_DATA_BUFFER_ADDRESS     0x640//  NEW MEMORY ADDRESS DECLARED
#endif //FIXED_MEMORY_ADDRESS

将端点 IN 地址也设置为 1


 //Now that we are configured, enable the endpoints for use in the demo
    //  and start the initial transfers
    USBEnableEndpoint(1,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(2,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    USBEnableEndpoint(3,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
 //   USBEnableEndpoint(1,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
    //Prepare the OUT endpoints to receive the first packets from the host.

    EP1OUTEvenHandle = USBTransferOnePacket(1, OUT_FROM_HOST,(uint8_t*)&EP1OUTEvenBuffer,64);   //First 64-bytes of data sent to EP1 OUT will arrive in the even buffer.
    EP1OUTOddHandle = USBTransferOnePacket(1, OUT_FROM_HOST,(uint8_t*)&EP1OUTOddBuffer,64); //Second 64-bytes of data sent to EP1 OUT will arrive in the odd buffer.
    EP1OUTEvenNeedsServicingNext = true;    //Used to keep track of which buffer will contain the next sequential data packet.

    EP2OUTEvenHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTEvenBuffer,64);
    EP2OUTOddHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTOddBuffer,64);
    EP2OUTEvenNeedsServicingNext = true;    //Used to keep track of which buffer will contain the next sequential data packet.

    EP3OUTEvenHandle = USBTransferOnePacket(3, OUT_FROM_HOST,(uint8_t*)&EP3OUTEvenBuffer,64);
    EP3OUTOddHandle = USBTransferOnePacket(3, OUT_FROM_HOST,(uint8_t*)&EP3OUTOddBuffer,64);
    EP3OUTEvenNeedsServicingNext = true;    //Used to keep track of which buffer will contain the next sequential data packet.

   EP1INEvenHandle = USBTransferOnePacket(1, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64); //First 64-bytes of data RECIVE to EP3 IN will arrive in the even buffer.
   EP1INOddHandle = USBTransferOnePacket(1, IN_TO_HOST,(uint8_t*)&EP1INOddBuffer,64);   //Second 64-bytes of data RECIVE to EP3 IN will arrive in the odd buffer.
    EP1INEvenNeedsServicingNext = true;

USB 描述符


/* Device Descriptor */
const USB_DEVICE_DESCRIPTOR device_dsc=
{
    0x12,                   // Size of this descriptor in bytes
    USB_DESCRIPTOR_DEVICE,  // DEVICE descriptor type
    0x0200,                 // USB Spec Release Number in BCD format        
    0x00,                   // Class Code
    0x00,                   // Subclass code
    0x00,                   // Protocol code
    USB_EP0_BUFF_SIZE,      // Max packet size for EP0, see usb_config.h
    0x04D8,                 // Vendor ID: 0x04D8 is Microchip's Vendor ID
    0x0052,                 // Product ID: 0x0052
    0x0000,                 // Device release number in BCD format
    0x01,                   // Manufacturer string index
    0x02,                   // Product string index
    0x00,                   // Device serial number string index
    0x01                    // Number of possible configurations
};

/* Configuration 1 Descriptor */
const uint8_t configDescriptor1[]={
    /* Configuration Descriptor */
    0x09,//sizeof(USB_CFG_DSC),    // Size of this descriptor in bytes
    USB_DESCRIPTOR_CONFIGURATION,                // CONFIGURATION descriptor type
    0x2E,0x00,            // Total length of data for this cfg
    1,                      // Number of interfaces in this cfg
    1,                      // Index value of this configuration
    0,                      // Configuration string index
    _DEFAULT | _SELF,               // Attributes, see usb_device.h
    50,                     // Max power consumption (2X mA)

    /* Interface Descriptor */
    0x09,//sizeof(USB_INTF_DSC),   // Size of this descriptor in bytes
    USB_DESCRIPTOR_INTERFACE,               // INTERFACE descriptor type
    0,                      // Interface Number
    0,                      // Alternate Setting Number
    4,                      // Number of endpoints in this intf
    0xFF,                   // Class code
    0xFF,                   // Subclass code
    0xFF,                   // Protocol code
    0,                      // Interface string index

    /* Endpoint Descriptor */
    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP01_OUT,                  //EndpointAddress
    _BULK,                       //Attributes
    64,0x00,                    //size
    1,                         //Interval

    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP02_OUT,                   //EndpointAddress
    _BULK,                       //Attributes
    64,0x00,                    //size
    1,                          //Interval

    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP03_OUT,                   //EndpointAddress
    _BULK,                       //Attributes
    64,0x00,                    //size
    1,                          //Interval

     0x07,                       /*sizeof(USB_EP_DSC)*/// New Endpoint for Sending Data To Host
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP01_IN,                   //EndpointAddress// VALUE MODIFED FOR SENDING DATA
    _BULK,                       //Attributes
    64,0x00,                    //size
    0                          //Interval

};

所以基本上问题得到了解决,因为我使用 1 作为端点地址进行进出传输。

然而,这意味着我的通信是双向的,我希望它是单向的。这样我就可以实现更高的带宽。

我必须了解如何使用 1 作为 OUT END POINT 和 81 作为 IN END POINT ADDRESS 进行通信。

编程愉快!!

于 2015-08-25T18:47:32.243 回答