Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

USB superspeed peripherals Forum Discussions

Anonymous
Not applicable

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 Solution
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

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

Hemanth

View solution in original post

0 Likes
2 Replies
Hemanth
Moderator
Moderator
Moderator
First like given First question asked 750 replies posted

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

Hemanth
0 Likes
Anonymous
Not applicable

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

0 Likes