0

I m stuck with a problem related to winusbReadpipe function. I m using Pic18f4550 Mc(XC8 Compiler) and VC ++ 2013 (MFC).

I my just trying to read and write to/from Device /Host. The sample Programme provide by Microchip is working fine and I am able to send Data to all Endpoints 01, 02, 03 in Device from Host.

However I am unable to read any feedback from Device to Host. I’m reading and writing data in two separate threads. My idea is to just read feedback of Button pressed in My demo board or at least an echo back command. It seems ,it just enter once in read function and then get stalled. Not Sure about this.

I tried searching over internet and implemented all suggestion given in Different forums but till date no success. worst is I m trying to post my query on Microchip forum but could not get myself registered , it always says administrator will approve my id but nothing has happened yet.

Below is my code both Device side and Host Side. Pls tell me if anything else is required from my side.

I look forwad for your support on this .

Thanks,

Rahul


VC++ code:


Read Thread Code


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;
}

Header files declared in VC++ for using read/writepipe function


//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
    );

Microcontroller code


Variable declaration Section


#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

Descriptor


/* 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

};

Initialization of USB for Bulk Transfer


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;
}

Code for data Transfer, Note : _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;
         }
    }

End of code


Rahul
  • 13
  • 6

1 Answers1

0

i resolve the issue of non working of winusb read pipe function.

after doing lots of hit and trial i made following chnages and could sucessfully read the feedback of potentiometer and button pressed.

fixed memory address


#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

setting endpoint IN address also as 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 DESCRIPTOR


/* 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

};

SO BASICALLY THE ISSUE GOT RESOLVED BECAUSE I AM USING 1 AS ENDPOINT ADDRESS FOR BOTH IN AND OUT TRANSFER.

HOWEVER THIS MEANS MY COMMUNICATION IS BI-DIRECTIONAL AND I WANT IT TO BE UNIDIRECTIONAL. SO THAT I CAN ACHIEVE HIGHER BADWIDTH.

I HAVE TO FIND OUT HOW TO COMMUNICATE USING 1 AS OUT END POINT AND 81 AS IN END POINT ADDRESS.

HAPPY PROGRAMMING!!

Rahul
  • 13
  • 6