1 2 Previous Next 16 Replies Latest reply on Mar 7, 2017 12:44 PM by dragonfly.synths

    USB3 Vendor Request

    laim.maskey

      Hi,

         

      Would you have some example code that shows how to implement a Vendor Request in the FX3?

         

      Thanks

        • 1. Re: USB3 Vendor Request
          anand.srinivasan.asokan

          At this moment we don't have FX3 example project for vendor request. Sorry for the inconvenience.

             

          Regards,

             

          Anand

          • 2. Re: USB3 Vendor Request
            laim.maskey

            Hi,

               

            I was able to modify the UVC firmware example so that vendor requests could be handled. The UVC example makes use of class requests  to control operation of the FX3 and this very similar to how vendor requests are handled. I’ve described below the steps necessary to implement  a simple vendor request for the FX3. The vendor request out transfer sends data to the FX3 while the vendor request in transfer reads this data back but multiplied by 2.  In some case code comments have been removed to allow easier reading.The steps to implement vendor requests in the FX3  are:

               

             

               

            Add separate thread in the CyFxApplicationDefine function to deal with the vendor requests

               

             

               

            ptr2 = CyU3PMemAlloc (VndReq_EP0_THREAD_STACK);

               

            retThrdCreate = CyU3PThreadCreate (&vndAppEP0Thread,

               

                                   "31:Vendor EP0 Thread",     

               

                                   VndReqEP0Thread_Entry,      

               

                                   0,                          

               

                                   ptr2,                       

               

                                   VndReq_EP0_THREAD_STACK,    

               

                                   VndReq_EP0_THREAD_PRIORITY, 

               

                                   VndReq_EP0_THREAD_PRIORITY, 

               

                                   CYU3P_NO_TIME_SLICE,        

               

                                   CYU3P_AUTO_START            

               

                                   );

               

             

               

            /* Check the return code */

               

            if (retThrdCreate != 0)

               

            {

               

                /* Application cannot continue */

               

                /* Loop indefinitely */

               

                while(1);

               

            }

               

             

               

            Create thread handling function called in this case VndReqEP0Thread_Entry. This function will carry out the vendor request actions.

               

             

               

            void

               

            VndReqEP0Thread_Entry (

               

                    uint32_t input)

               

            {

               

             

               

                uint32_t flag;

               

                uint16_t readcount;

               

                uint8_t i;

               

              

               

                CyU3PReturnStatus_t apiRetStatus;

               

              

               

                for (;;)

               

                {

               

                    /* Check for Vendor request event */

               

                    if (CyU3PEventGet (&glFxVREQEvent, (CY_FX_VREQ_RD | CY_FX_VREQ_WR) ,

               

                                       CYU3P_EVENT_OR_CLEAR, &flag,

               

                                       CYU3P_WAIT_FOREVER) == CY_U3P_SUCCESS)

               

                    {

               

                        /* Check for Vendor request upload event */

               

                        if (flag & CY_FX_VREQ_RD)

               

                        {

               

                           

               

                        // multiply download data by 2

               

                                 for (i = 0; i < 16; i++)

               

                                 Ep0_OutData[i] = Ep0_InData[i] * 2;

               

                                           

               

                                 apiRetStatus = CyU3PUsbSendEP0Data(16, Ep0_OutData);

               

                                 if (apiRetStatus != CY_U3P_SUCCESS)

               

                                 {

               

                                   /* Error handling */

               

                                   CyU3PDebugPrint (4, "EP0 Send Data Failed, Error Code = %d\n",apiRetStatus);

               

                                 }

               

                        }

               

                         /* Check for Vendor request download event */

               

                        else if (flag & CY_FX_VREQ_WR)

               

                        apiRetStatus = CyU3PUsbGetEP0Data(16, Ep0_InData, &readcount);

               

                            if (apiRetStatus != CY_U3P_SUCCESS)

               

                            {

               

                              /* Error handling */

               

                              CyU3PDebugPrint (4, "EP0 Get Data Failed, Error Code = %d\n",apiRetStatus);

               

                            }

               

                    }

               

             

               

                    /* Relinguish the thread */

               

                    CyU3PThreadRelinquish ();

               

                }

               

            }

               

             

               

             

               

            Modify the USB setup call back function (CyFxBulkLpApplnUSBSetupCB) to get the vendor requests and create the event flags

               

             

               

            /* Callback to handle the USB Setup Requests */

               

            CyBool_t

               

            CyFxBulkLpApplnUSBSetupCB (

               

                    uint32_t setupdat0, /* SETUP Data 0 */

               

                    uint32_t setupdat1  /* SETUP Data 1 */

               

                )

               

            {

               

                 uint8_t setupReqType, setupReq;

               

                CyU3PReturnStatus_t apiRetStatus;

               

                CyBool_t vndHandleReq = CyFalse;

               

                  

               

                /* Obtain Request Type and Request */

               

                setupReqType = (uint8_t)(setupdat0 & CY_FX_USB_SETUP_REQ_TYPE_MASK);

               

                setupReq = (uint8_t)((setupdat0 & CY_FX_USB_SETUP_REQ_MASK) >> 8);

               

                   

               

                /* Check for user vendor request */

               

                if (setupReq == CY_FX_VND_REQ1)

               

                 {

               

                    /* Vendor requests are handled in the application */

               

                    vndHandleReq = CyTrue;

               

                 

               

                    /* Check for vendor request upload */

               

                    if (setupReqType == CY_FX_USB_VND_GET_REQ_TYPE)

               

                    {

               

                                  

               

                      apiRetStatus = CyU3PEventSet(&glFxVREQEvent,CY_FX_VREQ_RD,CYU3P_EVENT_OR);

               

                      if (apiRetStatus != CY_U3P_SUCCESS)

               

                      {

               

                        /* Error handling */

               

                        CyU3PDebugPrint (4, "Get Vendor Request Event Failed, Error Code = %d\n",apiRetStatus);

               

                      }

               

                                 }

               

                                 /* Check for vendor request download */

               

                                 else if (setupReqType == CY_FX_USB_VND_SET_REQ_TYPE)

               

                                 apiRetStatus = CyU3PEventSet(&glFxVREQEvent,CY_FX_VREQ_WR,CYU3P_EVENT_OR);

               

                      if (apiRetStatus != CY_U3P_SUCCESS)

               

                      {

               

                         /* Error handling */

               

                         CyU3PDebugPrint (4, "Set Vendor Request Event Failed, Error Code = %d\n",apiRetStatus);

               

                      }

               

                                           

               

            Rest of user code follows on from here

               

             

               

            Update the  main .h file to include the user vendor requests; event flags variables and variables associated with the new thread.

               

             

               

            #define VndReq_EP0_THREAD_STACK       (0x0800)    /* Thread stack size */

               

            #define VndReq_EP0_THREAD_PRIORITY    (8)         /* Thread priority */

               

             

               

            #define CY_FX_VREQ_RD        (1 << 0)                                  /* rd event flag */

               

            #define CY_FX_VREQ_WR        (1 << 1)                                 /* wr event flag */

               

            #define CY_FX_VND_REQ1                    (uint8_t)(0xB1) /* Vendor request */

               

            #define CY_FX_USB_VND_SET_REQ_TYPE    (uint8_t)(0x40) /* Download */

               

            #define CY_FX_USB_VND_GET_REQ_TYPE  (uint8_t)(0xC0) /* Upload */

               

             

               

            Add memory buffers to store Ep0 vendor in and out data and event and flag variables.

               

            These are added to the main source code file

               

             

               

            static CyU3PThread BulkLpAppThread, vndAppEP0Thread;

               

            static CyU3PEvent glFxVREQEvent;  // vendor request event flags

               

            static uint8_t Ep0_InData[16];   // ep0 in data buffer

               

            static uint8_t Ep0_OutData[16];  // ep0 out data buffer

               

            void VndReqEP0Thread_Entry (uint32_t);  /* Declaration for the thread entry function */

               

             

               

            That’s it.

               

             

               

            Sodafarl

            • 3. Re: USB3 Vendor Request
              anand.srinivasan.asokan

              Thanks for sharing the code here.

                 

              Cheers,

                 

              Anand

              • 4. Re: USB3 Vendor Request
                wallace.tseng

                Hi Sodafarl,

                   

                May I know do you need to modify descriptor for supporting vendor request?

                   

                Wallace

                • 5. Re: USB3 Vendor Request
                  laim.maskey

                  Hi,

                     

                  You won't need to modify the descriptor  as vendor requests are carried by control endpoint 0 which is always present in a USB device. The example code should work as it is. I think the only thing I forgot in the example code was to declare ptr2 as a pointer in the  CyFxApplicationDefine function.

                     

                  Sodafarl

                  • 6. Re: USB3 Vendor Request
                    wallace.tseng

                     Hi sodafarl,

                       

                    Thank you for replying.

                       

                    BR, Wallace

                    • 7. Re: USB3 Vendor Request
                      lebrun.damien

                      Hi,

                         

                      I understand that used driver on PC side (host) is UVC.

                         

                      How do you transmit the vendor command from PC application to transfer it via UVC driver ?

                         

                      Best Regards,

                         

                      DamL.

                      • 8. Re: USB3 Vendor Request
                        laim.maskey

                        Hi,

                           

                        I used the UVC example firmware to understand how setup requests were being handled by the firmware.
                        I then modified the code -see above - to deal with vendor requests instead of UVC class requests.
                        The new vendor request functions were then added to the auto Bulk Loop example firmware compiled and downloaded using the Control Centre application. The new firmware used the standard Cypress USB 3 driver so
                        I was able to use the Control Centre to check the vendor requests were working.

                           

                        Sodafarl

                        • 9. Re: USB3 Vendor Request
                          lebrun.damien

                          Hi,

                             

                          thank you for your answer. So you don't use UVC driver on PC side. That's what I didn't understand in your previous posts.

                             

                          I guess it is possible to transmit Vendor-Command through UVC driver from PC side but this requires the device descriptor to be changed. As you said that It didn't need to be changed from your sample code I was making this mistake.

                             

                          Best Regards,

                             

                          DamL

                          • 10. Re: USB3 Vendor Request
                            oleg.seiljus

                             Hi,

                               

                            First of all, thank you for sharing the Vendor Request code example. 

                               

                            I've merged it into my application, but have been having problems with reading bytes from device. The 

                               

                            apiRetStatus = CyU3PUsbSendEP0Data(16, Ep0_OutData);

                               

                            call always returns error code 69 (CY_U3P_ERROR_TIMEOUT) after about 3-5 seconds. I use Control Centre Application to initiate the transaction over EP0. Do you have any ideas why this call timesout? 

                               

                            Many thank!

                               

                            OlegS

                            • 11. Re: USB3 Vendor Request
                              laim.maskey

                              Hi,

                                 

                              Are you able to write bytes out to the device?  Do you write bytes out to the device before trying to read bytes back in?

                                 

                              Have you tried reading bytes in before sending bytes out to the device - it might be sending bytes to the device that is causing the FX3 to timeout. I tried the code again and it workded fine. How is the Cypress Control Panel application setup to perform the Vendor request. For a Vendor requets to read bytes it should be

                                 

                              Direction IN Req Type Vendor  Target Device

                                 

                              Req Code your request code

                                 

                              Sodafarl

                              • 12. Re: USB3 Vendor Request
                                oleg.seiljus

                                 Hi Sodafarl,

                                   

                                I recreated a project using cyfxbulklpauto example. I had to make a small change to your code and add txApiRetStatus = CyU3PEventCreate(&glFxVREQEvent); to CyFxBulkLpApplnInit (void) so the flags are initialized. BY the way, I'm using Beta 3 SDK and testing on USB 2.0 port.

                                   

                                After the compiling and loading code using Control Centre device re-enumerates and I'm using Control Centre application to Write and Read.

                                   

                                First I try writing to a device using Control Panel and Set the following:

                                   

                                Bytes To Transfer=16

                                   

                                Direction=Out

                                   

                                Req Type=Vendor

                                   

                                Target=Device

                                   

                                Req Code=0xB1 (per example)

                                   

                                The Control Panel returns:

                                   

                                 

                                   

                                CONTROL OUT transfer 

                                   

                                CONTROL OUT transfer failed with Error Code:997

                                   

                                and the FX3 debug:

                                   

                                EP0 Get Data Failed, Error Code = 69

                                   

                                Reading from device has similar behavior:

                                   

                                 

                                   

                                CONTROL IN transfer 

                                   

                                CONTROL IN transfer failed with Error Code:997

                                   

                                and FX3: EP0 Send Data Failed, Error Code = 69

                                   

                                In both IN and OUT cases the FX3 code end-up in VndReqEP0Thread and Request and RequestType being parsed to correct values and event is generated, but the CyU3PUsbSendEP0Data() and CyU3PUsbGetEP0Data() always timing out for me. The header file suggests that error code 69 could be EP0 DMA related (returned in case of DMA failure (EP0 DMA channel) but I can't seem to find anything on it yet.

                                   

                                Many thanks for your help with this. Please let me know if you spot anything in the steps I'm doing to test.

                                   

                                Regards,

                                   

                                OlegS

                                • 13. Re: USB3 Vendor Request
                                  oleg.seiljus

                                   Hi Sodafarl,

                                     

                                  Interesting, the code works well when FX3 dev board is connected to USB3.0 and I'm able to do IN and OUT Vendor requests just fine, but not when connected to USB2.0 bus.

                                     

                                  Hi Anand,

                                     

                                  I'm playing with Vendor Request example Sodafarl has kindly provided and I'm able to do IN and OUT transaction when FX3 Dev board is connected to USB3.0 host. However, when FX3 Dev board is connected to USB2.0 host, the Control Center returns: CONTROL OUT transfer failed with Error Code:997 and FX3 CyU3PUsbSendEP0Data() and CyU3PUsbGetEP0Data() calls always return error 69 for me. Please see above messages for details of my setup.

                                     

                                  I would appreciate any suggestions or recommendations on why the CyU3PUsbSendEP0Data() and CyU3PUsbGetEP0Data() do not seem to process the EP0Data when EP0 request is sent onUSB2.0 bus?

                                     

                                   

                                     

                                  Many thanks,

                                     

                                  OlegS

                                  • 14. Re: USB3 Vendor Request
                                    oleg.seiljus

                                     Hello,

                                       

                                    I'm bumping this thread up so it does not end-up at the bottom unanswered.

                                       

                                    Regards,

                                       

                                    OlegS

                                    1 2 Previous Next