This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Accurate Delay Function

Other Parts Discussed in Thread: TMS570LS3137, HALCOGEN

Short explanation

I am using a TMS570LS3137 and I require an accurate delay of 500ns or longer. I am unable to do so with both the RTI Timer. The fastest delay I could get from the RTI  (without the pin toggling overhead of 455.5ns) was 700ns (32 RTI1CLKS, 129 CPU clocks). Is this correct? I can't find any documentation on the overhead of the RTI timer or the fastest it can run.

Is there a better, faster, more precise way to go about this?

Long explanation

I have been using Halcogen to help generate our code for us so I will start there. Using the rtiBlinky example, I modify it by setting the clocks to 16Mhz CLK input, PLL 180MHz, Counter0clk 90MHz, and RTI1CLK to 45MHz.

I change which pin is my output

ioSetDirection(mibspiPORT3, 0x00000200);

For my first test comment out everything and just sit in the while(1) and toggle that pin to measure my real world toggle time offset (time that the pin is set high) with the code below.

gioSetPort(mibspiPORT3, gioGetPort(mibspiPORT3) ^ 0x00000200);

Pin toggling overhead = 455.5ns

I then move the toggle function to the rtiNotification function and I added a line to change the period before I start the counter.

rtiSetPeriod(rtiCOMPARE0, 1000);

I then went through and swept through a bunch of different periods (RTI1CLKs between the interrupt firing) I call them ticks in the table below

Measured   HAL Exp Actual Actual w/o toggle w/o toggle w/o toggle
Ticks Input Time (s)   Time (s)   CPU Clocks RTI1 Clocks Time (s) CPU Clocks RTI1 Clocks
4500000 100.000E-3 s 100.000E-3 s 18.000E+6 4.500E+6 100.000E-3 18.000E+6 4.500E+6
450000 10.000E-3 s 10.000E-3 s 1.800E+6 450.000E+3 10.000E-3 1.800E+6 449.980E+3
45000 1.000E-3 s 1.000E-3 s 180.000E+3 45.000E+3 999.545E-6 179.918E+3 44.980E+3
4500 100.000E-6 s 100.000E-6 s 18.000E+3 4.500E+3 99.545E-6 17.918E+3 4.480E+3
450 10.000E-6 s 10.000E-6 s 1.800E+3 450.000E+0 9.545E-6 1.718E+3 429.503E+0
100 2.222E-6 s 2.200E-6 s 399.960E+0 99.990E+0 1.767E-6 317.970E+0 79.493E+0
80 1.778E-6 s 1.800E-6 s 320.040E+0 80.010E+0 1.323E-6 238.050E+0 59.513E+0
60 1.330E-6 s 1.300E-6 s 239.400E+0 59.850E+0 874.500E-9 157.410E+0 39.353E+0
53 1.178E-6 s 1.200E-6 s 212.040E+0 53.010E+0 722.500E-9 130.050E+0 32.513E+0
45 1.178E-6 s 1.000E-6 s 212.040E+0 53.010E+0 722.500E-9 130.050E+0 32.513E+0
40 1.245E-6 s 900.000E-9 s 224.100E+0 56.025E+0 789.500E-9 142.110E+0 35.528E+0
30 1.155E-6 s 800.000E-9 s 207.900E+0 51.975E+0 699.500E-9 125.910E+0 31.478E+0
20 1.155E-6 s 400.000E-9 s 207.900E+0 51.975E+0 699.500E-9 125.910E+0 31.478E+0
10 1.170E-6 s 220.000E-9 s 210.600E+0 52.650E+0 714.500E-9 128.610E+0 32.153E+0

As you can see there is a definite cieling i am hitting but i can not find it being discussed in any of the documentation. Is there a better faster way to go about making a precise delay function of 500ns?

rtiSetPeriod(rtiCOMPARE0, 1000);

  • Hello:

    We have received your post and will direct it to one of our experts to provide some feedback.

    Regards,

    Enrique
  • Hi Wade,

    Can you upload the CCS project with your modifications to the rtiBlinky program?

    Regards,
    Sunil
  • 4201.testblinks.zip

    I have compressed and uploaded my project. Please let me know if it does not work.

  •          I talked with Sunil Oak and it was pointed out that the A lot of this ceiling that I was hitting was due to writing the register for the GPIO pin.

             I decided to stop measuring the toggling of a pin and decided to use the PMU counter to count how many system clocks that it takes for the interrupt to fire. As it turns out there were a few different things that were contributing to the inaccuracies.

    1)      Halcogen is a tool to generate code that is universal to many different MCU’s and platforms so its functions tend to be a bit intense for time critical operations. Example:

                   rtiStopCounter(rtiCOUNTER_BLOCK1);

    This function is actually doing a more than just writing STOP to the register. It is doing the following.

                    rtiREG1->GCTRL &= ~(uint32)((uint32)1U << (counter & 3U));

             Most of these operations are taking time and since in my case the rti compare value was extremely low. This was causing the interrupt to fire while the mcu was trying stop the counter. This caused all kinds of chaos (pictured below)

      

    2)      I was trying to Stop the RTI counter AFTER it returned from the interrupt. This again added more time and instructions and caused the interrupt to fire before I was able to stop the counter.

    Below are my final results of my delay function.

    Conclusion

    There is still more optimization that i can do but, in my opinion, anything time sensitive should not be handled by Halcogen. You should directly write to the register yourself.

  • Hi Wade,

    This is a really great post - thank you for sharing.   I love the charts that you have made.

    Just want to poke a bit at your conclusion if you don't mind:

    Wade Oler said:
    There is still more optimization that i can do but, in my opinion, anything time sensitive should not be handled by Halcogen. You should directly write to the register yourself.

    Do you really think it is correct to say that the issue is using the code generated by HalCoGen?   My instinct says that the variability you are charting is likely more fundamental and it has to do with the other interrupts or tasks that are executing on your system.  

    I would not really expect using a HalCoGen function to introduce this much variability.   Rather I would expect additional latency.   To me it looks like you are showing the effect perhaps of another interrupt being active - and sometimes the RTI interrupt occurs followed directly by the measurement, whereas sometimes another interrupt or task inserts itself between the RTI interrupt and the measurement.