2 Replies Latest reply on Mar 22, 2018 5:39 AM by ashlinsurey.a_2617601

    Type C connector enumeration issue

    ashlinsurey.a_2617601

      Hi,

      I have been working on a CX3 based camera with USB type-C connector. This will be connected to the PC through a USB Type-C to Type A cable. We have used a MUX in between the Type-C connector and the CX3 chip to select the correct Tx and Rx lines. I have added a code to detect the orientation of the cable so that it always enumerates as 3.0. I tried this in 1.3.3 sdk as well as 1.3.1 sdk. The snippet I have used for this is,

       

      status = CyU3PConnectState(CyTrue, CyTrue);

      if(CyU3PUsbGetSpeed() != CY_U3P_SUPER_SPEED)  /*Checks whether 3.0 connection is established in the default Tx1,Rx1 pair*/

      {

      status = CyU3PConnectState(CyFalse, CyFalse);

      /*First attempt failed*/

      /* Check in other orientation */

      CyU3PGpioSetValue(TYPEC_MUX_GPIO, CyFalse); /*Swiches the mux to the Tx2,Rx2 pair*/

      status = CyU3PUsbControlUsb2Support (CyTrue);

      status = CyU3PConnectState(CyTrue, CyTrue); /*Re establish connection through Tx2, Rx2 pair*/

      if (status != CY_U3P_SUCCESS)

      {

        CyU3PDebugPrint(4, "\n\rUSB Connect 2 failed, Error code = %d", status);

      }

      }

       

      In SDK 1.3.3:

      The problem I face here(Format1) is that the CyU3PUsbGetSpeed() API doesn't return CY_U3P_SUPER_SPEED when called immediately after CyU3PConnectState() . Because of this even if the Type-C plug is connected in the orientation Tx1,Rx1 pair , the if statement evaluates to false and the MUX changes to Tx2,Rx2 resulting in 2.0 operation. But if a code or delay is added in between these two lines (as in Format2, Format3), this works correctly as expected.

       

      In SDK 1.3.1:

      Format1,Format2,Format3 works correctly.

       

      I wonder how building the same code in different sdk works differently. (PS. I have used the same .ld file for both the SDKs). Can anyone explain this behaviour??

       

      Thanks in advance,

      Regards,

      Ashlin Surey. A

        • 1. Re: Type C connector enumeration issue
          hman

          Hi Ashlin,

           

          With respect to your code:

           

          Delay has to be given between the following two lines, for CyU3PUsbGetSpeed() to return correct value:

           

          status = CyU3PConnectState(CyTrue, CyTrue);     AND

           

          if(CyU3PUsbGetSpeed() != CY_U3P_SUPER_SPEED)

           

           

          The following is another way of working with Type C connector:

           

           

          Below is the sequence of steps that needs to be followed in FX3/CX3 firmware for mux control:

           

          1) Disable the USB2 support.

          2) Try to establish USB3 connection using the first USB3 pair.

          3) check for CY_U3P_USB_EVENT_SS_COMP_ENTRY and CY_U3P_USB_EVENT_USB3_LNKFAIL.

               If any of the two event gets triggered, do the following:

                    a)disable the USB PHY by using CyU3PConnectState(CyFalse, CyFalse);

                    b)toggle the mux selection GPIO.

                    c)enable the USB 2.0 support

                    d)Call connectstate API to establish a USB 3.0 connection using the second pair.

           

          Code changes if above steps are followed:

           

          A) First change:

           

          In your FX3/CX3 firmware comment out the CyU3PConnectState() API and add the below snippet in place of that:

           

           

          status = CyU3PUsbControlUsb2Support(CyFalse);

            if (status != CY_U3P_SUCCESS)

            {

                    CyU3PDebugPrint(4,"\r\nDisabling USB2 failed. Stopping Execution");

                    while(1);

            }

           

            CyU3PThreadSleep(20);

           

            status = CyU3PConnectState(CyTrue, CyTrue);

            CyU3PThreadSleep(50);

            for(int i =0 ; (i<100 && !U3_EVENT); i++ )

                      CyU3PThreadSleep(5);

           

            if(!U3_TRUE)

            {

                     CyU3PDebugPrint(5,"\r\nNot Super speed enumeration with MUX_SEL low. Flipping Mux to try again");

                     CyU3PConnectState(CyFalse, CyFalse);

                     CyU3PGpioSetValue(SS_MUX_SEL_GPIO22,CyTrue);

                     CyU3PUsbControlUsb2Support(CyTrue);

                     CyU3PThreadSleep(20);

                    status = CyU3PConnectState(CyTrue, CyTrue);

                     CyU3PThreadSleep(50);

                     if (status != CY_U3P_SUCCESS)

                     {

                          CyU3PDebugPrint (4, "\n\rAppInit:ConnectState Err = 0x%x", status);

                          CyCx3UvcAppErrorHandler(status);

                     }

           

            }

            else

            {

                     CyU3PDebugPrint(5,"\r\nSuper speed enumeration with MUX_SEL low");

            }

           

           

          B) Second change:

           

          Add these two cases in the USB Setup call back as shown below :

           

           

          /* This is the Callback function to handle the USB Events */

          static void

          CyCx3UvcAppUSBEventCB(

                            CyU3PUsbEventType_t evtype, /* Event type */

                            uint16_t evdata /* Event data */)

          {

           

           

                   switch (evtype)

                   {

                   case  CY_U3P_USB_EVENT_SS_COMP_ENTRY:

          #ifdef TYPE_C_ENABLED

                            U3_EVENT = CyTrue;

                            U3_TRUE = CyFalse;

                            CyU3PDebugPrint(5, "\n\rSS_COMP_ENTRY Event Occured");

          #endif

                            break;

           

           

                   case  CY_U3P_USB_EVENT_USB3_LNKFAIL:

          #ifdef TYPE_C_ENABLED

                            U3_EVENT = CyTrue;

                            U3_TRUE = CyFalse;

                            CyU3PDebugPrint(5, "\n\rUSB3_LNKFAIL Event Occured");

          #endif

                            break;

           

           

          With the above two code changes, 3.0 connection can be established with a Type-C connector.

           

          Regards,

          Hemanth

          • 2. Re: Type C connector enumeration issue
            ashlinsurey.a_2617601

            Hi Hemanth,

            The code you have provided works fine. To add to this, both the flags has to be declared as

            CyBool_t U3_EVENT = CyFalse,U3_TRUE=CyTrue;

            for proper working.

            Also, I observed only the occurrence of CY_U3P_USB_EVENT_USB3_LNKFAIL event. The CY_U3P_USB_EVENT_SS_COMP_ENTRY event never occurred.

             

            Thanks and Regards,

            Ashlin Surey. A