FX3 complex GPIO initialization

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

cross mob
LBence91
Level 4
Level 4
10 questions asked 50 sign-ins 25 replies posted

Hello!

I am trying develop an UVC application with the FX3 board(CYUSB3KIT). I am using as a base the AN75779 document and the UVC_AN75779 example project. I needed to modify the project, based on the FX3 Technical reference guide. I had to add some simple GPIO and one complex GPIO for a clock signal. The documentation says i had to bitmasking the gpios(like in the cyfxgpiocomplexapp and the cyfxgpioapp example projects), but if i masked them the board not even enumerate. I could successfully setup the simple gpio pins if i did not masking them, but initialize them with override in the "CyFxUVCApplnInit" thread. But for the complex gpio pin i was not able to use this method. Can you help what can be the problem?

0 Likes
1 Solution

Hello Bence,

Based on my understanding from the latest project that was shared, you are making use of a 16 bit data bus. As mentioned in the pin description section of FX3 datasheet, GPIO 20 and 25 are used for the control signals and they cannot be directly configured over the IO matrix. You can override and use them. Please note that the API CyU3PDeviceConfigureIOMatrix () will fail if you configure one IO that is actually mapped to a peripheral as a GPIO. The control signals are mapped to the GPIF II block and it is not possible to directly configure them as GPIOs through the IO matrix configurations.

About the PWM issue, we used the same project that was shared in your previous response without any modification. We were able to see a PWM on GPIO 34. Please find the snapshot of the traces captured at our end using saleae logic analyzer:

JayakrishnaT_76_0-1638518935608.png

I found that you have used a very small period for the PWM signal. Is this the actual requirement? If not then you can refer to the following KBA to understand how to calculate and set the period and duty cycle of the PWM signal:

https://community.infineon.com/t5/Knowledge-Base-Articles/Calculating-PWM-Period-and-Duty-Cycle-in-F...

Best Regards,
Jayakrishna

View solution in original post

0 Likes
11 Replies
JayakrishnaT_76
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hello,

Please share the source code of your project so that we can understand the problem better.

Also, I hope that you would have used the API CyU3PDeviceGpioOverride () for overriding an IO. Please confirm if the second parameter of this API was used as CyFalse for overriding an IO as a complex gpio or not.

Best Regards,
Jayakrishna
0 Likes

Dear Jayakrishna,

Thanks for your response. Yes I used the API CyU3PDeviceGpioOverride() function, and it worked for the simple gpios, but not for the complex pin.

I copied the code part where I setup the simple and complex gpio:

CyU3PDmaMultiChannelConfig_t dmaMultiConfig;
CyU3PEpConfig_t endPointConfig;
CyU3PReturnStatus_t apiRetStatus;
CyU3PGpioClock_t gpioClock;
CyU3PGpioComplexConfig_t gpioXConfig;
CyU3PGpioSimpleConfig_t gpioConfig;
CyU3PPibClock_t pibclock;

#ifdef USB_DEBUG_INTERFACE
CyU3PDmaChannelConfig_t channelConfig;
#endif

/* Create UVC event group */
apiRetStatus = CyU3PEventCreate (&glFxUVCEvent);
if (apiRetStatus != 0)
{
CyU3PDebugPrint (4, "UVC Create Event failed, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}

/* Init the GPIO module */
gpioClock.fastClkDiv = 2;
gpioClock.slowClkDiv = 0;//2;
gpioClock.simpleDiv = CY_U3P_GPIO_SIMPLE_DIV_BY_2;
gpioClock.clksrc=CY_U3P_SYS_CLK;
gpioClock.halfDiv = 0;

/* Initialize Gpio interface */
apiRetStatus = CyU3PGpioInit (&gpioClock, NULL);
if (apiRetStatus != 0)
{
CyU3PDebugPrint (4, "GPIO Init failed, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}
//Original DEBUG PIN INIT
apiRetStatus = CyU3PDeviceGpioOverride (DEBUG1_GPIO, CyTrue);
if (apiRetStatus != 0)
{
CyU3PDebugPrint (4, "GPIO Override failed, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}

gpioConfig.outValue = CyFalse;
gpioConfig.driveLowEn = CyTrue;
gpioConfig.driveHighEn = CyTrue;
gpioConfig.inputEn = CyFalse;
gpioConfig.intrMode = CY_U3P_GPIO_NO_INTR;
apiRetStatus = CyU3PGpioSetSimpleConfig (DEBUG1_GPIO, &gpioConfig);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "GPIO Set Config Error, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}

//AC_INIT1 pin configure as an input
apiRetStatus = CyU3PDeviceGpioOverride (ACC_INIT, CyTrue);
if (apiRetStatus != 0)
{
CyU3PDebugPrint (4, "ACC_INIT Override failed, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}

gpioConfig.outValue = CyTrue;
gpioConfig.driveLowEn = CyFalse;
gpioConfig.driveHighEn = CyFalse;
gpioConfig.inputEn = CyTrue;
gpioConfig.intrMode = CY_U3P_GPIO_INTR_POS_EDGE;
apiRetStatus = CyU3PGpioSetSimpleConfig (ACC_INIT, &gpioConfig);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "ACC_INIT Set Config Error, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}

apiRetStatus = CyU3PDeviceGpioOverride (34, CyTrue);
if (apiRetStatus != 0)
{
CyU3PDebugPrint (4, "PWM Override failed, Error Code = %d\n", apiRetStatus);
CyFxAppErrorHandler (apiRetStatus);
}

//GPIO 34 as pwm
gpioXConfig.outValue = CyFalse;
gpioXConfig.inputEn = CyFalse;
gpioXConfig.driveLowEn = CyTrue;
gpioXConfig.driveHighEn = CyTrue;
gpioXConfig.pinMode = CY_U3P_GPIO_MODE_PWM;
gpioXConfig.intrMode = CY_U3P_GPIO_NO_INTR;
gpioXConfig.timerMode = CY_U3P_GPIO_TIMER_HIGH_FREQ;
gpioXConfig.timer = 0;
gpioXConfig.period = CY_FX_PWM_PERIOD;
gpioXConfig.threshold = CY_FX_PWM_8MH_THRESHOLD;
apiRetStatus = CyU3PGpioSetComplexConfig(34, &gpioXConfig);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PGpioSetComplexConfig failed, error code = %d\n",
apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}
apiRetStatus = CyU3PGpioComplexUpdate (34, CY_FX_PWM_8MH_THRESHOLD, CY_FX_PWM_PERIOD);//CY_FX_PWM_75P_THRESHOLD, CY_FX_PWM_PERIOD);
if (apiRetStatus != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyU3PGpioComplexUpdate failed, error code = %d\n",
apiRetStatus);
CyFxAppErrorHandler(apiRetStatus);
}

0 Likes

Hello,

As mentioned in my previous response, when you override an IO as a complex GPIO, you need to use the second parameter of the API CyU3PDeviceGpioOverride () as CyFalse and not CyTrue. Can you try to replace the following line in your code:

apiRetStatus = CyU3PDeviceGpioOverride (34, CyTrue);

to

apiRetStatus = CyU3PDeviceGpioOverride (34, CyFalse);

Please try this and let me know the result.

Best Regards,
Jayakrishna
0 Likes

Hello,

That's solved one half of the problem. Now i did not get the error debug print. But the board still not produce the pwm signal. Only the simple gpio pins behave as their porpuse. Also if I try to bitmasking the pins (simple or complex) the board not even enumerate as USB device after writing the image file.

This is only main configuration which works:

main (void)
{
CyU3PReturnStatus_t apiRetStatus;
CyU3PIoMatrixConfig_t io_cfg;
//CyFxGpioInit();

/* Initialize the device */
apiRetStatus = CyU3PDeviceInit (0);
if (apiRetStatus != CY_U3P_SUCCESS)
{
goto handle_fatal_error;
}

/* Turn on instruction cache to improve firmware performance. Use Release build to improve it further */
apiRetStatus = CyU3PDeviceCacheControl (CyTrue, CyFalse, CyFalse);

/* Configure the IO matrix for the device. */
io_cfg.isDQ32Bit = CyTrue;//CyFalse;//CyTrue;
io_cfg.s0Mode = CyFalse;//CY_U3P_SPORT_INACTIVE;//CyFalse;
io_cfg.s1Mode = CyFalse;//CY_U3P_SPORT_INACTIVE;//CyFalse;
io_cfg.lppMode = CY_U3P_IO_MATRIX_LPP_DEFAULT;
io_cfg.gpioSimpleEn[0] = 0;
io_cfg.gpioSimpleEn[1] = 0;//0x00000004;//0;//0x00008000;
io_cfg.gpioComplexEn[0] = 0;
io_cfg.gpioComplexEn[1] = 0;//0x00000004;//0x00000400;//0;//0x00000400;
io_cfg.useUart = CyTrue; /* Uart is enabled for logging. */
io_cfg.useI2C = CyTrue; /* I2C is used for the sensor interface. */
io_cfg.useI2S = CyFalse;
io_cfg.useSpi = CyFalse;
apiRetStatus = CyU3PDeviceConfigureIOMatrix (&io_cfg);
if (apiRetStatus != CY_U3P_SUCCESS)
{
goto handle_fatal_error;
}

/* This is a non returnable call for initializing the RTOS kernel */
CyU3PKernelEntry ();

/* Dummy return to make the compiler happy */
return 0;

0 Likes
JayakrishnaT_76
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hello,

FX3 IOs are multiplexed. Please refer to the Table 7 of FX3 datasheet to understand the Pin description of FX3. The link to the same is given below:

https://www.cypress.com/file/140296/download

As you are making use of a 32 bit interface, you can refer to the column 32 bit data bus in Table 7. You can use an IO as a GPIO only if a particular peripheral is not used. Otherwise, these IOs cannot be used as GPIOs. You can override them and use them in your application. 

>> But the board still not produce the pwm signal.

Can you please check if any other API is failing? If not, can you please share the complete project so that we can test it at our end.

Best Regards,
Jayakrishna
0 Likes
lock attach
Attachments are accessible only for community members.

Hello,

I have tired using this documentation and the FX3Api guide and the fx3 technical reference guide, but I still confused what is the problem. I am sure i have misunderstand something, so i attached the project as a zip.

Thank you for your help

Best regards.

0 Likes

Hello,

Please let me know what exactly did you mean by "Problem" in your previous reply. Is it the issue that you are not able to see PWM on the complex GPIO or is it the issue that you are not able to configure the GPIOs over IO matrix. Please clarify so that we can help you better.

In the project shared, I find that you have not used any simple/complex GPIO in the IO matrix configurations:

io_cfg.gpioSimpleEn[0] = 0;
io_cfg.gpioSimpleEn[1] = 0;
io_cfg.gpioComplexEn[0] = 0;
io_cfg.gpioComplexEn[1] = 0;

Please let me know which IOs do you want to use as simple/complex GPIOs?

Best Regards,
Jayakrishna
0 Likes

Hello,

My initial problem was that if i used the bitmasking method at the IO matrix configuration mz board did not enumerate as a UVC device. I was not able to find it with windows device manager or any other software tool. But if i left the io matrix configurator in the default state, and configured the simple gpio ios with the CyU3PDeviceGpioOverride and CyU3PGpioSetSimpleConfig API functions the simple GPIOS worked as i wanted. But if i tried to configure a complex gpio for generate a PWM signal with the CyU3PDeviceGpioOverride, CyU3PGpioSetComplexConfig API functions that gpio did not produced the pwm signal. Summary I am using the UVC_AN75779 example project with the OV7670 image sensor. I have a working UVC device with configured simple gpio ports :

GPIO 20 simple input (configured and working)

GPIO 25 simple output (configured and working)

GPIO 33 simple output (configured and working)

GPIO 35 simple output (configured and working)

GPIO 38 simple intput (configured and working)

GPIO 39 simple output (configured and working)

GPIO 50 simple output (configured and working)

GPIO 34 complex gpio as PWM (configured and NOT working)

Best Regards,

Bence

0 Likes

Hello Bence,

Based on my understanding from the latest project that was shared, you are making use of a 16 bit data bus. As mentioned in the pin description section of FX3 datasheet, GPIO 20 and 25 are used for the control signals and they cannot be directly configured over the IO matrix. You can override and use them. Please note that the API CyU3PDeviceConfigureIOMatrix () will fail if you configure one IO that is actually mapped to a peripheral as a GPIO. The control signals are mapped to the GPIF II block and it is not possible to directly configure them as GPIOs through the IO matrix configurations.

About the PWM issue, we used the same project that was shared in your previous response without any modification. We were able to see a PWM on GPIO 34. Please find the snapshot of the traces captured at our end using saleae logic analyzer:

JayakrishnaT_76_0-1638518935608.png

I found that you have used a very small period for the PWM signal. Is this the actual requirement? If not then you can refer to the following KBA to understand how to calculate and set the period and duty cycle of the PWM signal:

https://community.infineon.com/t5/Knowledge-Base-Articles/Calculating-PWM-Period-and-Duty-Cycle-in-F...

Best Regards,
Jayakrishna
0 Likes

Hello Jayakrishna,

Thank you, i noticed that the PWM actually produced, but when the board went into suspended USB event  the PWM turned off. Now i can use the PWM signal, only anomaly that the bit mapping causes fatal error state, but if I let it default zero i can configure the IOs.

0 Likes

Hello,

As mentioned in my previous response, GPIO 20 and 25 are used for the control signals.  The control signals are mapped to the GPIF II block and it is not possible to directly configure them as GPIOs through the IO matrix configurations. Please note that the API CyU3PDeviceConfigureIOMatrix () will fail if you configure one IO that is actually mapped to a peripheral as a GPIO. 

So, you can override and use the required IOs as GPIOs.

Best Regards,
Jayakrishna
0 Likes