FX3: Accurate timer

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

cross mob
Anonymous
Not applicable

Hi all,

I need to create a timer which has better resolution then 1us on the FX3.

I have followed the following link to create a 0.1us timer on a complex gpio: How to Get a 0.1-µs Unit Timestamp with FX3 – KBA220034

However when I use CyU3PGpioComplexSampleNow() it doesnt seem very accurate.

For example:

CyU3PGpioComplexSampleNow (57, &testa);

CyU3PGpioComplexSampleNow (57, &testb);

This gives a time difference of ~3us which seems too long. Is the CyU3PGpioComplexSampleNow() a slow function?

I have also tried just reading directly from the general purpose IO registers. The io pin timer/counter register has a base address of '0xE0001004'. This is for one particular GPIO. How can I read the io pin timer/counter register for GPIO 57, what address do I use?

To summarise:

1. Is there an accurate way to count at 0.1us resolution on the FX3

2. What is the address of the io pin timer/counter register for GPIO 57

Thanks

2 Replies
Anonymous
Not applicable

Hi James,

You are right about the API being slow. The way this can be overcome is to directly read from the register as you suggested.

The source code of the FX3 APIs is present in the SDK in "C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\fx3_sdk_1_3_3_src.zip"

The source of this API is present in cyu3gpiocomplex.c file. You can find out which register is being read and how and just use the last part of the code.

In the source code, you can notice the "index" parameter. It is 1 in your case (for GPIO 57).

The last part of the API has this important code:

  /* Set the mode to sample now. Wait for the sampling to

     * complete and read the value from the threshold register. */

GPIO->lpp_gpio_pin[index].status = (regVal |

            (CY_U3P_GPIO_MODE_SAMPLE_NOW << CY_U3P_LPP_GPIO_MODE_POS));

    while (GPIO->lpp_gpio_pin[index].status & CY_U3P_LPP_GPIO_MODE_MASK);

    *value_p = GPIO->lpp_gpio_pin[index].threshold;

Here, GPIO->lpp_gpio_pin[index].status will be 0xE0001010 for index 1 (gpio 57).

GPIO->lpp_gpio_pin[index].threshold will be 0xE000101C for index 1 (gpio 57).

Regards,

-Madhu

0 Likes
Anonymous
Not applicable

Hi Madhu,

Looking into the source code there is a blocking loop in the CyU3PGpioComplexSampleNow():

    /* Set the mode to sample now. Wait for the sampling to

     * complete and read the value from the threshold register. */

    GPIO->lpp_gpio_pin[index].status = (regVal |

            (CY_U3P_GPIO_MODE_SAMPLE_NOW << CY_U3P_LPP_GPIO_MODE_POS));

    while (GPIO->lpp_gpio_pin[index].status & CY_U3P_LPP_GPIO_MODE_MASK);

    *value_p = GPIO->lpp_gpio_pin[index].threshold;

I believe this is the source of the latency associated with this API call. Even after rewriting the API call with plain register accesses, it still takes ~2.5us to complete.

We need to be able to measure time between events to 100ns accuracy. How can we achieve this with the FX3?

Regards,

James