- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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