1 2 Previous Next 17 Replies Latest reply on Jun 15, 2012 1:02 AM by rama.sai.krishna.vakkantula

    STALL handshake in Control-OUT transaction

    tatsuya.kudoh
              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.   
        • 1. Re: STALL handshake in Control-OUT transaction
          laim.maskey

          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

          • 2. Re: STALL handshake in Control-OUT transaction
            tatsuya.kudoh

            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.

            • 3. Re: STALL handshake in Control-OUT transaction
              laim.maskey

              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

              • 4. Re: STALL handshake in Control-OUT transaction
                tatsuya.kudoh

                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...

                • 5. Re: STALL handshake in Control-OUT transaction
                  laim.maskey

                  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

                  • 6. Re: STALL handshake in Control-OUT transaction
                    tatsuya.kudoh

                    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..)

                    • 7. Re: STALL handshake in Control-OUT transaction
                      laim.maskey

                      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

                      • 8. Re: STALL handshake in Control-OUT transaction
                        laim.maskey

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

                        • 9. Re: STALL handshake in Control-OUT transaction
                          tatsuya.kudoh

                          Hi,

                             

                          I'm using 32bit Windows7.

                             

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

                          • 10. Re: STALL handshake in Control-OUT transaction
                            tatsuya.kudoh

                            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?

                            • 11. Re: STALL handshake in Control-OUT transaction
                              laim.maskey

                              Hi,

                                 

                               

                                 

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

                              • 12. Re: STALL handshake in Control-OUT transaction
                                tatsuya.kudoh

                                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.

                                • 13. Re: STALL handshake in Control-OUT transaction
                                  anand.srinivasan.asokan

                                  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

                                  • 14. Re: STALL handshake in Control-OUT transaction
                                    tatsuya.kudoh

                                    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).

                                    1 2 Previous Next