Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > USB Controllers > STALL handshake in Control-OUT transaction

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



STALL handshake in Control-OUT transaction
Moderator:
RSKV

Post Reply
Follow this topic



STALL handshake in Control-OUT transaction

Kudoh posted on 16 Feb 2012 11:24 PM PST
Senior Member
16 Forum Posts
Hi, In Control-OUT tansaction, please tell me how to send the STALL to the host after reading all EP0 data. I'd like to determine the result(ACK/STALL) by depending on the received data.


Re: STALL handshake in Control-OUT transaction

sodafarl posted on 16 Feb 2012 11:53 PM PST
Top Contributor
128 Forum Posts

Hi,

Take a look at the cyfxbulklpautoenum example where  setup requests are handled by the users firmware, with unknown requests setting the stall condition.

Sodafarl



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 16 Feb 2012 01:51 AM PST
Senior Member
16 Forum Posts

Thank you for your reply.

 

If the handshake result is decided in setup stage, the suggested sample illustrates the method to send STALL.

 

However, I'd like to know how to send STALL after CyU3PUsbGetEP0Data() call.

Because, in some case, the result(ACK or STALL) depends on the received data in data stage.

 



Re: STALL handshake in Control-OUT transaction

sodafarl posted on 16 Feb 2012 02:40 AM PST
Top Contributor
128 Forum Posts

Hi,

If you look at the bit of code describing the Get Configuration request if the attempt to get the data is unsuccessfull  then the status variable is set to reflect this

/* Return the current selected configuration. */
        case CY_U3P_USB_SC_GET_CONFIGURATION:
            glEp0Buffer[0] = glUsbConfiguration;
            status = CyU3PUsbSendEP0Data (wLength, glEp0Buffer);
            break;

 

Later on when the code comes to decide on the handshake  a stall is set if status was not successful

/* If there has been an error, stall EP0 to fail the transaction. */
    if ((isHandled != CyTrue) || (status != CY_U3P_SUCCESS))
    {
        /* This is an unhandled setup command. Stall the EP. */
        CyU3PUsbStall (0, CyTrue, CyFalse);
    }
    else
    {
        CyU3PUsbAckSetup ();
    }
 

From this the status phase of a control transfer happens after the data phase (in or out) so I think you should be able to handle the setup request, look at the data and then return a stall or an ack. In the above example the device is returning data over endpoint 0 but it should be the same for the device receiving data.

Sodafarl



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 16 Feb 2012 03:55 AM PST
Senior Member
16 Forum Posts

Hi,

in FX3APIGuide(Rev1.0),  6.3.7 CyU3PUSBSetupCb_t

Described that :

The handling of each setup request will involve one and only one of the following API calls.
•  CyU3PUsbSendEP0Data
•  CyU3PUsbGetEP0Data
•  CyU3PUsbAckSetup
•  CyU3PUsbStall

 

So, after CyU3PUsbGetEP0Data() call, ACK is sent automatically.

 

I tested CyU3PUsbStall() call after CyU3PUsbGetEPData(),

but, on the host PC, the control transfer API returns success.

 

Is it the limitation of FX3? I think it is not convenience...



Re: STALL handshake in Control-OUT transaction

sodafarl posted on 16 Feb 2012 05:19 AM PST
Top Contributor
128 Forum Posts

Hi,

I modified the CyFxBulkLpApplnUSBSetupCB function to handle my own vendor commands. If a vendor command is detected within CyFxBulkLpApplnUSBSetupCB it calls my function to handle the vendor requests.
If this vendor function returns false the CyFxBulkLpApplnUSBSetupCB sets the stall bit. I modified one of my vendor commands to check the downloaded payload data and if the value of the first byte  was 2 the vendor function returned false. I tried this code using Cypress Control center and if the payload data contained the value 2 I got the error message
CONTROL OUT transfer failed with Error Code:997
So I think this works. I understand  that the  APIGuide is saying only one type of API call is allowed, however this appears to be different from the example code that Cypress show handling the setup request in firmware where you send data using CyU3PUsbSendEP0Data and if this is not successful you can use the CyU3PUsbStall function

When you registered the callback function CyFxBulkLpApplnUSBSetupCB was fast enumeration set to false see below

CyU3PUsbRegisterSetupCallback(CyFxBulkLpApplnUSBSetupCB, CyFalse);

Sodafarl



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 17 Feb 2012 10:39 PM PST
Senior Member
16 Forum Posts

Hi,

I  modified USBBulkLoopAutoEnum example to handle the vendor requets,

but,  ControlOUT transfer always successes.

(However, if wLength > 32, setup handler returns CyFalse immmediately and  ControlCenter shows error 997).

 

 

There is a piece of the setup handler, colored lines are my additional code.


/* Callback to handle the USB setup requests. */
CyBool_t
CyFxBulkLpApplnUSBSetupCB (
        uint32_t setupdat0, /* SETUP Data 0 */
        uint32_t setupdat1  /* SETUP Data 1 */
    )
{
    CyBool_t isHandled = CyTrue;
    CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

    uint8_t  bRequest, bReqType;
    uint8_t  bType, bTarget;
    uint16_t wValue, wIndex, wLength;

    /* Decode the fields from the setup request. */
    bReqType = (setupdat0 & CY_U3P_USB_REQUEST_TYPE_MASK);
    bType    = (bReqType & CY_U3P_USB_TYPE_MASK);
    bTarget  = (bReqType & CY_U3P_USB_TARGET_MASK);
    bRequest = ((setupdat0 & CY_U3P_USB_REQUEST_MASK) >> CY_U3P_USB_REQUEST_POS);
    wValue   = ((setupdat0 & CY_U3P_USB_VALUE_MASK)   >> CY_U3P_USB_VALUE_POS);
    wIndex   = ((setupdat1 & CY_U3P_USB_INDEX_MASK)   >> CY_U3P_USB_INDEX_POS);
    wLength  = ((setupdat1 & CY_U3P_USB_LENGTH_MASK)  >> CY_U3P_USB_LENGTH_POS);

    /* Currently there are no vendor / class request that we handle.
     * Stall EP0 or return CyFalse. */

    if ( (bReqType & 0x80) == 0 && bType == CY_U3P_USB_VENDOR_RQT && wLength >= 1 ){
        wLength = (wLength + 15) & ~15;
            /* in CyU3PGetEP0Data(), count number should be a multiple of 16 bytes. (see cyu3usb.h)
             *    This violation causes an argument error.
             */

        if( wLength > sizeof(glEp0Buffer) )
            return CyFalse;
        if( CyU3PUsbGetEP0Data(wLength, glEp0Buffer, NULL) != CY_U3P_SUCCESS )
            return CyFalse;

        if( glEp0Buffer[0] != 2 ){
            CyU3PUsbAckSetup();
            return CyTrue;
        }else{
            CyU3PUsbStall(0x00, CyTrue, CyFalse);
               
/* Note: There is no change to behavior even if removing CyU3PUsbStall() from here. */
            return CyFalse;
                /* Note: There is no change to behavior even if it returns CyTrue here instead of CyFalse. */
        }
    }

    if (bType != CY_U3P_USB_STANDARD_RQT)
    {
        return CyFalse;
    }

                                       (skip following code..)



Re: STALL handshake in Control-OUT transaction

sodafarl posted on 17 Feb 2012 12:43 AM PST
Top Contributor
128 Forum Posts

Hi,

I pasted your code into the USBBulkLoopAutoEnum with no other changes and the control transfer fails if I send the value 2 in the payload data with error code 997. With any other value the control transfer is susscessful. I am running this on a 32 bit Windows XP machine.  I changed the value to 3 and compiled again and this time the control transfer failed on the value 3. I''ve attached the compiled .img file if you would like to try this - fails on 3

Sodafarl



Re: STALL handshake in Control-OUT transaction

sodafarl posted on 17 Feb 2012 12:46 AM PST
Top Contributor
128 Forum Posts

File attached for stall on vendor request - change extension to .img

 



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 17 Feb 2012 05:38 AM PST
Senior Member
16 Forum Posts

Hi,

I'm using 32bit Windows7.

So, I'll test by Windows Xp, too.



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 19 Feb 2012 05:21 AM PST
Senior Member
16 Forum Posts

Hi,

I tested on WindowsXp, but result is not changes.

May the SDK Version differ? I'm using Ver 1.0.0.

 

Could you give me your compiled .img file?



Re: STALL handshake in Control-OUT transaction

sodafarl posted on 19 Feb 2012 07:55 AM PST
Top Contributor
128 Forum Posts

Hi,

 

I tried to send this file before but I'll attach it again. I am also using SDK version 1.0.0



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 19 Feb 2012 07:18 PM PST
Senior Member
16 Forum Posts

Hi,

Thank you for sending the file.

 

I found that this problem occurs at only USB2.0(HS), not in USB3.0(SS).

For both of your .img file and my .img file, at USB3.0, sending 0x03 causes error 997,

but at USB2.0, transfer always succeeds.



Re: STALL handshake in Control-OUT transaction

aasi posted on 20 Feb 2012 02:26 AM PST
Cypress Employee
1073 Forum Posts

That is strange. By any chance did you hook up a CATC trace to capture what is happening at the USB bus level?

Regards,

Anand



Re: STALL handshake in Control-OUT transaction

Kudoh posted on 20 Feb 2012 04:19 AM PST
Senior Member
16 Forum Posts

Hi,

Sorry, I don't have an USB 2.0 or 3.0 analyzer.

But I check with an USB 1.0 analyzer in full-speed connection,

then, FX3 sends ACK response in status phase.

And, in case of calling CyU3PUsbStall() only ( without calling CyU3PGetEP0Data() ),

FX3 sends STALL response in data phase (not in status phase).

 



Re: STALL handshake in Control-OUT transaction

lpcy posted on 14 Jun 2012 08:01 AM PST
Member
6 Forum Posts

Hello,

if've the same problem with CyU3PUsbGetEP0Data and CyU3PUsbStall.

 

Is there any example without the issue?

I write on UART continously the string given in example "Data tracker: buffers sent: %d.\r\n".
Now if I call the function

status = CyU3PUsbGetEP0Data(4096, glEp0Buffer, NULL);

there is no more output on UART.

My code:

[...]

uint8_t glEp0Buffer[4096]; //length has to be multiple of 16 bytes

[...]

switch(vReq) {

    case VR_WRITE:
        CyU3PDebugPrint(2, "write\r\n");
        status = CyU3PUsbGetEP0Data(4096, glEp0Buffer, NULL);
        if(CY_U3P_SUCCESS == status ) {
            CyU3PDebugPrint(2, "success\r\n");
        }
        else {
            if(status == CY_U3P_ERROR_BAD_ARGUMENT)
                CyU3PDebugPrint(2, "CY_U3P_ERROR_BAD_ARGUMENT%x\r\n", status );
            else
            CyU3PDebugPrint(2, "error%x\r\n", status );
            CyU3PUsbStall (0, CyTrue, CyFalse);
        }
        break;
    case VR_READ:
        CyU3PDebugPrint(2, "read\r\n");
        status = CyU3PUsbSendEP0Data(4096, glEp0Buffer);
        if(CY_U3P_SUCCESS == status ) {
            CyU3PDebugPrint(2, "success\r\n");
        }
        else {
            CyU3PDebugPrint(2, "error%x\r\n", status );
        }
        break;
    case CY_U3P_USB_TARGET_ENDPT:
        if(wValue == CY_U3P_USBX_FS_EP_HALT) {
            /* Clear stall on the endpoint. */
            CyU3PUsbStall (wIndex, CyFalse, CyTrue);
        }
        break;
}
[...]

 



Re: STALL handshake in Control-OUT transaction

RSKV posted on 15 Jun 2012 11:02 PM PST
Cypress Employee
655 Forum Posts

On FX3, it is not really possible to stall the status phase of a control transfer after the data phase is completed. This is because the firmware has no control on when the status phase happens and we may end up trying to stall the EP after the status phase is completed. (Essentially, stalling the status phase is a hit or miss operation. It may or may not work depending on how fast you do the stall and how much time the host gives you between data and status). 

This is why we are documenting that you can use only one of the four APIs (UsbAckSetup, SendEp0Data, GetEp0Data and UsbStall) in response to a control request. Once you have used GetEp0Data to get the data, you cannot call UsbStall to stall the request.

 






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.