- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I'm currently trying to implement a timer/counter with <1us of jitter.
I have the the following code:
GPIO CONFIGURATION:
CyU3PGpioComplexConfig_t gpioComplexConfig;
CyU3PGpioClock_t gpioClock;
gpioClock.fastClkDiv = 10;
gpioClock.slowClkDiv = 10;
gpioClock.simpleDiv = CY_U3P_GPIO_SIMPLE_DIV_BY_2;
gpioClock.clkSrc = CY_U3P_SYS_CLK_BY_4;
gpioClock.halfDiv = 0;
apiRetStatus = CyU3PGpioInit(&gpioClock, GPIO_Interrupt);
apiRetStatus = CyU3PDeviceGpioOverride (GPIO_TIMER, CyFalse);
if (apiRetStatus != CY_U3P_SUCCESS)
{
printDebugMessage("CyU3PDeviceGpioOverride failed\n");
}
// Im putting an 8KHz square wave into GPIO_TIMER
// This will generate an interrupt every 125us
gpioComplexConfig.outValue = CyFalse;
gpioComplexConfig.inputEn = CyTrue;
gpioComplexConfig.driveLowEn = CyFalse;
gpioComplexConfig.driveHighEn = CyFalse;
gpioComplexConfig.pinMode = CY_U3P_GPIO_MODE_STATIC;
gpioComplexConfig.intrMode = CY_U3P_GPIO_INTR_TIMER_THRES;
gpioComplexConfig.timerMode = CY_U3P_GPIO_TIMER_POS_EDGE;
gpioComplexConfig.timer = 0;
gpioComplexConfig.period = 0x00000001; // Reset after each interrupt
gpioComplexConfig.threshold = 0x00000001; //Generate interrupt every 125us
apiRetStatus = CyU3PGpioSetComplexConfig(GPIO_TIMER, &gpioComplexConfig);
if (apiRetStatus != CY_U3P_SUCCESS)
{
printDebugMessage("CyU3PGpioSetComplexConfig failed: %d\n",apiRetStatus);
}
GPIO INTERRUPT CALLBACK:
void GPIO_Interrupt(uint8_t gpioId)
{
if(gpioId == GPIO_TIMER)
{
// Pulse TEST_GPIO for debug
CyU3PGpioSetValue(TEST_GPIO, CyTrue);
CyU3PGpioSetValue(TEST_GPIO, CyFalse);
}
}
When I measure the signal coming out of 'TEST_GPIO', I observe pulses at 125us, as expected. HOWEVER I'm experiencing ~20us of jitter.
The other data flow in this system is as follows:
1. GPIF to USB (DMA)
2. USB to GPIF (DMA)
I want to set the GPIO interrupt to the highest priority, to ensure that the jitter is below 1us.
I have tried to use the following API function to set the interrupt vector of the GPIO to the highest priority:
CyU3PVicIntSetPriority(CY_U3P_VIC_GPIO_CORE_VECTOR, 0);
However, the jitter is still there.
I now want to set the interrupt from the GPIO as a fast interrupt (FIQ). Could you please help me with this?
Regards,
James
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
CyU3PGpioSetValue() API already has some delay before setting the hardware pin to the desired logic level. Instead of using this API you can refer to the KBA 90267 which will guide you how to set GPIO pins through registers directly:
Increasing Frequency of Bit-Banged GPIO Clock in EZ-USB® FX3™ - KBA90267
Please try this and confirm.
Thanks & Regards
Abhinav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
CyU3PGpioSetValue() API already has some delay before setting the hardware pin to the desired logic level. Instead of using this API you can refer to the KBA 90267 which will guide you how to set GPIO pins through registers directly:
Increasing Frequency of Bit-Banged GPIO Clock in EZ-USB® FX3™ - KBA90267
Please try this and confirm.
Thanks & Regards
Abhinav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Abhinav,
I have implemented the gpio toggle with the register access as you suggested. This does reduce latency - however I'm really trying to reduce the jitter.
I believe the source of this jitter is other interrupts which are running on the system. For this reason I want to implement the GPIO Block interrupt as an FIQ. It doesnt look like the FIQ handler has been defined for the SDK. As shown in cyu3vectors_gcc.S:
.global __CyU3PFiqHandler
__CyU3PFiqHandler:
b __CyU3PFiqHandler
I have started to write the assembly code to complete the FIQ interrupt handler, as follows:
.global __CyU3PFiqHandler
__CyU3PFiqHandler:
stmdb sp!, {r0-r3}
mrs r0, SPSR
sub lr, lr, #4
stmdb sp!, {r0, r10, r12, lr}
bl CyU3PFiqContextSave
ldr r1, =CY_U3P_VIC_ADDRESS_ADDRESS
mov r2, #0
str r2, [r1]
ldr r1, =CY_U3P_VIC_INT_CLEAR_ADDRESS
ldr r2, =CY_U3P_VIC_GPIO_MASK
str r2, [r1]
/*"bl CyU3PIrqNestingStart*/ /* !!Not sure if needed for FIQ. I cant find an equivalent FIQ function */
bl CyU3PGpioCoreIntHandler
/*"bl CyU3PIrqNestingStop*/ /* !!Not sure if needed for FIQ. I cant find an equivalent FIQ function */
ldr r1, =CY_U3P_VIC_INT_ENABLE_ADDRESS
ldr r2, =CY_U3P_VIC_GPIO_MASK
str r2, [r1]
b CyU3PFiqContextRestore
Setting the GPIO block as FIQ:
uvint32_t *vic_int_select_p = ((uvint32_t *)(0xfffff00c));
uvint32_t *vic_int_enable_p = ((uvint32_t *)(0xfffff0010));
uvint32_t *vic_int_clear_p = ((uvint32_t *)(0xfffff0014));
/* Disable GPIO Interrupt */
*vic_int_clear_p = VIC_GPIO_MASK;
/* Set as FIQ Interrupt */
*vic_int_select_p = VIC_GPIO_MASK;
/* Enable GPIO Interrupt */
*vic_int_enable_p = VIC_GPIO_MASK;
Can I get some assistance here. What else is involved with setting up an FIQ on the FX3?
Regards,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Right now current implementation of FX3 firmware doesn't handle FIQ_Interrupt. You can generate PWM wave at GPIO. Refer to the section 8.9.4.3 of FX3 TRM.
Thanks & Regards
Abhinav