• AVR Freaks

Helpful Reply18F4550 USB Device - WinUSB - High Bandwidth Demo send to PC more than 64bytes data

Author
alexsg
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2008/12/19 23:41:06
  • Location: 0
  • Status: offline
2011/04/11 23:58:48 (permalink)
0

18F4550 USB Device - WinUSB - High Bandwidth Demo send to PC more than 64bytes data

I'm using this demo as my base.

I want to send more than 64bytes data.
Prior to this, i was able to send 64bytes to PC (without the do while looping, data was pass direct to INPacket).
now, it can't work.. On Pc software side, it keep hang.
attached captured USB transaction...
Any help?


#pragma udata USB_VARIABLES=0x500
..
..
BYTE INPacket[64];

#pragma udata
BYTE bData[192];
void ProcessIO(void)
{  
    unsigned char u8Count = 0;
    unsigned char u8Sent = 0;

    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
   

    if(!USBHandleBusy(USBGenericOutHandle))        //Check if the endpoint has received any data from the host.
    {  
            //
            // do something to get data from device more than 64bytes e.g.let's said 192bytes on bData
            //
            do
            {
                if(OUTPacket[4] > 64)//size
                {
                    OUTPacket[4] -= 64;
                    memcpy(bData + u8Count, (const void *)INPacket,64);   
                }
                else
                {
                    memcpy(bData + u8Count, (const void *)INPacket,OUTPacket[4]);   
                    OUTPacket[4] = 0;
                }               
                u8Sent = 0;
                while(!u8Sent)
                {
                    if(!USBHandleBusy(USBGenericInHandle))
                    {   
                        u8Sent = 1;
                        USBGenericInHandle = USBTransferOnePacket(USBGEN_EP_NUM, IN_TO_HOST,(BYTE*)&INPacket,USBGEN_EP_SIZE);
                    }
                }
                u8Count += 64;
            }while(OUTPacket[4]);
           
        USBGenericOutHandle = USBTransferOnePacket(USBGEN_EP_NUM, OUT_FROM_HOST,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
    }
}

//--------------------------------- usb_descriptors.c -------------------------//
   /* Endpoint Descriptor */
    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP01_OUT,                  //EndpointAddress
    _BULK,                       //Attributes
    USBGEN_EP_SIZE,0x00,        //size
    1,                         //Interval
   
    0x07,                       /*sizeof(USB_EP_DSC)*/
    USB_DESCRIPTOR_ENDPOINT,    //Endpoint Descriptor
    _EP01_IN,                   //EndpointAddress
    _BULK,                       //Attributes
    USBGEN_EP_SIZE,0x00,        //size
    1                          //Interval
};


//------------------------ PC side -------------------------------//
unsigned char InputPacketBuffer[192];
...
...
    u8Ret = WinUsb_WritePipe(MyWinUSBInterfaceHandle, 0x01, &OutputPacketBuffer[0], 64
                            , &BytesWritten, &OverlappedWriteStructureOut);       

    //Wait for the data to finish being transferred.
    dwWaitResult = WaitForSingleObject(IOEventOut, 5000);        //Blocking function until complete or timeout occurs.

    //The following call to WinUsb_ReadPipe() retrieves 64 bytes of data from the USB device.
    u8Ret = WinUsb_ReadPipe(MyWinUSBInterfaceHandle, 0x81, &InputPacketBuffer[0], 192
                            , &BytesRead, &OverlappedWriteStructureIn); 
    //Wait for the data to finish being transferred.
    dwWaitResult = WaitForSingleObject(IOEventIn, 5000);        //Blocking function until complete or timeout occurs.

 
post edited by alexsg - 2011/04/12 00:02:48

Attached Image(s)

#1
chinzei
Super Member
  • Total Posts : 2250
  • Reward points : 0
  • Joined: 2003/11/07 12:39:02
  • Location: Tokyo, Japan
  • Status: offline
Re:18F4550 USB Device - WinUSB - High Bandwidth Demo send to PC more than 64bytes data 2011/04/12 19:21:04 (permalink)
0

Your firmware code may fit to "USB Device - WinUSB - Generic Driver Demo", but not to "USB Device - WinUSB - High Bandwidth Demo"

"High Bandwidth Demo" actively uses ping-pong. To fill the EVEN and ODD BDTs alternately, this example applies two handles and two buffers.

In your above post, you use just single handle. It is the way shown in "USB Device - WinUSB - Generic Driver Demo".

If you want to write your code like above, start with "Generic Driver Demo".

Tsuneo
#2
alexsg
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2008/12/19 23:41:06
  • Location: 0
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/12 19:37:11 (permalink)
0
Sorry... for my mistake.. it should be generic driver demo that i am using now.

how can I send more than 64 bytes of data back to computer?
post edited by alexsg - 2011/04/12 19:56:00
#3
chinzei
Super Member
  • Total Posts : 2250
  • Reward points : 0
  • Joined: 2003/11/07 12:39:02
  • Location: Tokyo, Japan
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/12 20:32:39 (permalink)
0

If you are running this code on "USB Device - WinUSB - Generic Driver Demo",
I don't see any bug on your firmware code.

In your firmware, OUTPacket[4] determines the size of following IN transfer.
On the sniffer trace, it looks like 0x00 or 0x01.
On the host side, WinUsb_ReadPipe() always request 192 bytes in BufferLength (fourth) parameter.

On the host code, do you fill OutputPacketBuffer[4] with 192 correctly?

The "BufferLength" parameter is confusing naming, as usual on MS.
It doesn't mean the reserved buffer size, but "bytes to read" in this call.

Pass the same value as OutputPacketBuffer[4] to WinUsb_ReadPipe() at BufferLength parameter.

Tsuneo
#4
alexsg
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2008/12/19 23:41:06
  • Location: 0
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/12 20:46:50 (permalink)
0
sometimes, the read len is less than 64 bytes.

is USBGEN_EP_SIZE on USBTransferOnePacket has to be the same value with OUTPacket[4],
example OUTPacket[4] = 30 and USBGEN_EP_SIZE = 30 OR OUTPacket[4] = 64 and USBGEN_EP_SIZE = 64?
i fixed USBGEN_EP_SIZE = 64.
#5
chinzei
Super Member
  • Total Posts : 2250
  • Reward points : 0
  • Joined: 2003/11/07 12:39:02
  • Location: Tokyo, Japan
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/12 21:28:19 (permalink) ☄ Helpful
+2 (1)
Surely, with one more look, I noticed a couple of problems on your firmware code.
Here is a revised one.

void ProcessIO(void)
{  
    unsigned char u8Count = 0;
    unsigned char u8ToSend = 0;

    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;
   

    if(!USBHandleBusy( USBGenericOutHandle ) )          //Check if the endpoint has received any data from the host.
    {  
        //
        // do something to get data from device more than 64bytes e.g.let's said 192bytes on bData
        //
        while ( OUTPacket[4] > u8Count )
        {
            u8ToSend = OUTPacket[4] - u8Count;
            if ( u8ToSend > USBGEN_EP_SIZE )            // split the transfer into USBGEN_EP_SIZE transactions
            {
                u8ToSend = USBGEN_EP_SIZE;
            }

            while( USBHandleBusy(USBGenericInHandle) ); // wait until the IN EP finishes last transaction
            memcpy( bData + u8Count, (const void *)INPacket, u8ToSend );   // now, INPacket is free. copy new data and pass it to USB engine.
            USBGenericInHandle = USBTransferOnePacket( USBGEN_EP_NUM, IN_TO_HOST, (BYTE*)&INPacket, u8ToSend );

            u8Count += u8ToSend;                        // for next transaction
        }
           
        USBGenericOutHandle = USBTransferOnePacket(USBGEN_EP_NUM, OUT_FROM_HOST,(BYTE*)&OUTPacket,USBGEN_EP_SIZE);
    }
}

post edited by chinzei - 2011/04/12 21:37:54
#6
alexsg
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2008/12/19 23:41:06
  • Location: 0
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/12 23:38:32 (permalink)
0
look promising...i'll try it out...
one question for the host(computer side), what is the optimum timeout do we need?
is it depend on the length of data? how to gauge?

   u8Ret = WinUsb_WritePipe(MyWinUSBInterfaceHandle, 0x01, &OutputPacketBuffer[0], 64
                            , &BytesWritten, &OverlappedWriteStructureOut);       

    //Wait for the data to finish being transferred.
    dwWaitResult = WaitForSingleObject(IOEventOut, 5000);        //Blocking function until complete or timeout occurs.

    //The following call to WinUsb_ReadPipe() retrieves 64 bytes of data from the USB device.
    u8Ret = WinUsb_ReadPipe(MyWinUSBInterfaceHandle, 0x81, &InputPacketBuffer[0], 192
                            , &BytesRead, &OverlappedWriteStructureIn); 
    //Wait for the data to finish being transferred.
    dwWaitResult = WaitForSingleObject(IOEventIn, 5000);        //Blocking function until complete or timeout occurs.

#7
alexsg
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2008/12/19 23:41:06
  • Location: 0
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/13 03:00:45 (permalink)
0
I tried it but, when i try to send 200 bytes, it will stuck on 2nd iteration at "while( USBHandleBusy(USBGenericInHandle) );" (after the first loop )
It work when data at then 64 bytes.

at computer side, i wait for 5sec.
    u8Ret = WinUsb_ReadPipe(MyWinUSBInterfaceHandle, 0x81, &InputPacketBuffer[0], 200
                            , &BytesRead, &OverlappedWriteStructureIn); 

dwWaitResult = WaitForSingleObject(IOEventIn, 5000);


#8
alexsg
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2008/12/19 23:41:06
  • Location: 0
  • Status: offline
Re:18F4550 USB Device - WinUSB - Generic driver Demo send to PC more than 64bytes data 2011/04/14 19:18:34 (permalink)
0
Hi Tsuneo,
i've solve the problem for minor mistake on the memcpy.
thanks for your help.
By the way, what is the optimum timeout for the WaitForSingleObject e.g. 3, 5, 9 sec or ?
#9
Jump to:
© 2019 APG vNext Commercial Version 4.5