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.

[C5517] Microsecond-resolution real time clock

I have the EVM and I would like to know where or how to achieve the following function:

Pseudo-code:

1. Start timer T_1 = T_now (in microseconds resolution)

2. Acquire one sample from SAR ADC

3. Process the data

4. Wait (T - Elapsed(T_now - T_1)) (in microseconds resolution)

5. Go back to 1

Step 4 needs to be in real-time microseconds because of the need to sample at 500-1000 kHz for a multiplexed signal. I've been trying to get clock() and CLOCKS_PER_SECOND to work for this purpose but apparently it only ticks when the CPU is doing something in the program. I need something to tick at a constant rate no matter what. What should I look into?

I also need the clock ticks to be sent out as a clock signal with a duty cycle and clock divider that I can change, to synchronize the multiplexer. How to do this?

  • Elefant,

    There's some example code that you could work with to put together your steps. I don't know if you have already seen this, but there's GP timer example located at C55XCSL-LOWPOWER\c55_csl_3.04\c55xx_csl\ccs_v5.0_examples\gpt\CSL_GPTExample

    There's also a SAR poll example under C55XCSL-LOWPOWER\c55_csl_3.04\c55xx_csl\ccs_v5.0_examples\sar\CSL_SAR_PollExample.The above 2 are in the AUXPACK http://www.ti.com/tool/sprc133 

    There are RTC examples in the package as well.

    Hope this helps.

    Lali

  • Hi! Thanks for pointing me to the examples. I changed the examples and came up with the codes below. It is supposed to output a line every second. But it is too fast! The lines are actually 0.7 seconds apart.

    Snippet in test.c

    Void taskFxn2(Arg value_arg)
    {
    	LgUns i, j;
    	LgUns freq;
        Int value = ArgToInt (value_arg);
        Float onesecond, microSecsPerIntr, hcycles, lcycles, HIntrPerMs, LIntrPerMs;
    
        /* get frequency of platform */
        freq = GBL_getFrequency();
        printf("GBL Freq: %ld KHz\n", (LgUns)freq);
    
        lcycles = CLK_cpuCyclesPerLtime();
        printf("Cycles per ltime: %f\n", lcycles);
    LIntrPerMs = (Float)freq/lcycles; printf("LIntrPerMs = %lf\n", LIntrPerMs); /* compute timeout */ onesecond = 1000*LIntrPerMs; for (i = 0; i < value; i++) { printf("%ld\n", i); TSK_sleep((LgUns)onesecond); } printf("\n"); printf("end of task\n"); }

    Snippet in test.tcf

    bios.CLK.MICROSECONDS = 10; 
    
    var task;
    task          = bios.TSK.create("task");
    task.priority = 1;
    task.fxn      = prog.decl("taskFxn2");
    task.arg0     = 12;

  • Elefant,

    How are you measuring the 0.7 secs?
    Also, could you please post your full code here? I want to see if I can reproduce your issue.
    What version of CCS are you on? the latest is CCS 6.1.2

    Lali
  • Hi.

    I measured it with a video camera pointing at the Console tab in CCS.

    I am using CCS 6.1.1.00022

    clk.c:

    #include <std.h>
    #include <stdio.h>
    #include <log.h>
    #include <clk.h>
    #include <tsk.h>
    #include <gbl.h>
    #include "clkcfg.h"
    
    Void taskFxn2(Arg value_arg);
    
    Void main()
    {
        printf("Going into function\n");
    }
    
    Void taskFxn2(Arg value_arg)
    {
    	LgUns i;
    	LgUns currtime = CLK_gethtime();
    	LgUns freq;
    	printf("Inside hi-res test function. Current CPU htime = %lu\n", currtime);
        Int value = ArgToInt (value_arg);
        Float onesecond, hcycles, lcycles, HIntrPerMs, LIntrPerMs;
    
        printf("The task time in task2 is: %d ticks\n", (LgUns)TSK_time());
    
        /* get frequency of platform */
        freq = GBL_getFrequency();
        printf("GBL Freq: %lu KHz\n", (LgUns)freq);
    
        /* get cpu cycles per htime and ltime interrupt */
        hcycles = CLK_cpuCyclesPerHtime();
        lcycles = CLK_cpuCyclesPerLtime();
        printf("Cycles per htime: %f\n", hcycles);
        printf("Cycles per ltime: %f\n", lcycles);
    
        HIntrPerMs = (Float)freq/hcycles;
        LIntrPerMs = (Float)freq/lcycles;
    
        printf("HIntrPerMs = %lf\n", HIntrPerMs);
        printf("LIntrPerMs = %lf\n", LIntrPerMs);
    
        /* compute number of interrupts to make 1 second */
        onesecond = 1000*LIntrPerMs;
    
        printf("task, index, htime, ltime, timeAbs\n");
        for (i = 0; i < value; i++) {
        	printf("2, %lu, %lu, %lu, %lu\n", i, CLK_gethtime(), CLK_getltime(), CLK_gethtime() / CLK_countspms());
        	TSK_sleep((LgUns)onesecond);
        }
        printf("\n");
    
        printf("end of task2\n");
    }
    

    clk.tcf:

    utils.loadPlatform("ti.platforms.evm5517");
    
    bios.enableRealTimeAnalysis(prog);
    bios.enableMemoryHeaps(prog);
    bios.enableRtdx(prog);
    bios.enableTskManager(prog);
    
    bios.DARAM.createHeap      = true;
    bios.DARAM.enableHeapLabel = true;
    bios.DARAM["heapLabel"]    = prog.extern("SEG0");
    bios.DARAM.heapSize        = 0x500;
    bios.MEM.BIOSOBJSEG = prog.get("DARAM");
    bios.MEM.MALLOCSEG = prog.get("DARAM");
    
    
    bios.GBL.MEMORYMODEL = "LARGE";
    
    bios.CLK.MICROSECONDS = 10; 
    
    var trace;
    trace         = bios.LOG.create("trace");
    trace.bufLen  = 128;
    trace.logType = "circular";
    
    bios.LOG_system.bufLen = 512;
    
    var task;
    task          = bios.TSK.create("task");
    task.priority = 1;
    task.fxn      = prog.decl("taskFxn2");
    task.arg0     = 120;
    
    // !GRAPHICAL_CONFIG_TOOL_SCRIPT_INSERT_POINT!
    
    if (config.hasReportedError == false) {
        prog.gen();
    }
    

    Console output:

    Going into function
    Inside hi-res test function. Current CPU htime = 419
    The task time in task2 is: 0 ticks
    GBL Freq: 200000 KHz
    Cycles per htime: 2.000000
    Cycles per ltime: 2000.000000
    HIntrPerMs = 100000.000000
    LIntrPerMs = 100.000000
    task, index, htime, ltime, timeAbs
    2, 0, 347963, 348, 3
    2, 1, 34862636, 34862, 348
    2, 2, 69384636, 69384, 693
    2, 3, 103907825, 103907, 1039
    2, 4, 138433821, 138433, 1384
    2, 5, 172961636, 172961, 1729
    2, 6, 207485636, 207485, 2074
    2, 7, 242010824, 242010, 2420
    2, 8, 276537822, 276537, 2765
    2, 9, 311065865, 311065, 3110
    2, 10, 345594824, 345594, 3455
    2, 11, 380122827, 380122, 3801
    2, 12, 414650854, 414650, 4146
    2, 13, 449178824, 449178, 4491
    2, 14, 483706825, 483706, 4837
    2, 15, 518234854, 518234, 5182
    2, 16, 552764825, 552764, 5527
    2, 17, 587293827, 587293, 5872
    2, 18, 621822821, 621822, 6218
    2, 19, 656352821, 656352, 6563
    2, 20, 690883824, 690883, 6908
    2, 21, 725412822, 725412, 7254
    2, 22, 759943636, 759943, 7599
    2, 23, 794469636, 794469, 7944
    2, 24, 828995649, 828995, 8289
    2, 25, 863524824, 863524, 8635
    2, 26, 898054821, 898054, 8980
    2, 27, 932585821, 932585, 9325
    2, 28, 967115822, 967115, 9671
    2, 29, 1001645821, 1001645, 10016
    2, 30, 1036178821, 1036178, 10361
    2, 31, 1070709854, 1070709, 10707
    2, 32, 1105242822, 1105242, 11052
    2, 33, 1139773832, 1139773, 11397
    2, 34, 1174304649, 1174304, 11743
    2, 35, 1208834649, 1208834, 12088
    2, 36, 1243365821, 1243365, 12433
    2, 37, 1277899822, 1277899, 12778
    2, 38, 1312431822, 1312431, 13124
    2, 39, 1346965821, 1346965, 13469
    2, 40, 1381497822, 1381497, 13814
    2, 41, 1416030827, 1416030, 14160
    2, 42, 1450563865, 1450563, 14505
    2, 43, 1485098649, 1485098, 14850
    2, 44, 1519628821, 1519628, 15196
    2, 45, 1554162827, 1554162, 15541
    2, 46, 1588696865, 1588696, 15886
    2, 47, 1623228821, 1623228, 16232
    2, 48, 1657759825, 1657759, 16577
    2, 49, 1692291865, 1692291, 16922
    2, 50, 1726825649, 1726825, 17268
    2, 51, 1761356825, 1761356, 17613
    2, 52, 1795888825, 1795888, 17958
    2, 53, 1830422832, 1830422, 18304
    2, 54, 1864955649, 1864955, 18649
    2, 55, 1899486649, 1899486, 18994
    2, 56, 1934018821, 1934018, 19340
    2, 57, 1968550840, 1968550, 19685
    2, 58, 2003084636, 2003084, 20030
    2, 59, 2037614822, 2037614, 20376
    2, 60, 2072148827, 2072148, 20721
    2, 61, 2106681636, 2106681, 21066
    2, 62, 2141213825, 2141213, 21412
    2, 63, 2175746822, 2175746, 21757
    2, 64, 2210278865, 2210278, 22102
    2, 65, 2244811821, 2244811, 22448
    2, 66, 2279343854, 2279343, 22793
    2, 67, 2313877824, 2313877, 23138
    2, 68, 2348410822, 2348410, 23484
    2, 69, 2382942821, 2382942, 23829
    2, 70, 2417475840, 2417475, 24174
    2, 71, 2452009825, 2452009, 24520
    2, 72, 2486540821, 2486540, 24865
    2, 73, 2521074854, 2521074, 25210
    2, 74, 2555608649, 2555608, 25556
    2, 75, 2590140825, 2590140, 25901
    2, 76, 2624672822, 2624672, 26246
    2, 77, 2659206636, 2659206, 26592
    2, 78, 2693738821, 2693738, 26937
    2, 79, 2728272854, 2728272, 27282
    2, 80, 2762807821, 2762807, 27628
    2, 81, 2797342827, 2797342, 27973
    2, 82, 2831876825, 2831876, 28318
    2, 83, 2866411825, 2866411, 28664
    2, 84, 2900946840, 2900946, 29009
    2, 85, 2935479649, 2935479, 29354
    2, 86, 2970011636, 2970011, 29700
    2, 87, 3004541649, 3004541, 30045
    2, 88, 3039072821, 3039072, 30390
    2, 89, 3073606825, 3073606, 30736
    2, 90, 3108141854, 3108141, 31081
    2, 91, 3142674824, 3142674, 31426
    2, 92, 3177206827, 3177206, 31772
    2, 93, 3211740825, 3211740, 32117
    2, 94, 3246274821, 3246274, 32462
    2, 95, 3280809636, 3280809, 32808
    2, 96, 3315341649, 3315341, 33153
    2, 97, 3349872821, 3349872, 33498
    2, 98, 3384404827, 3384404, 33844
    2, 99, 3418938854, 3418938, 34189
    2, 100, 3453473865, 3453473, 34534
    2, 101, 3488009636, 3488009, 34880
    2, 102, 3522541824, 3522541, 35225
    2, 103, 3557074821, 3557074, 35570
    2, 104, 3591608854, 3591608, 35916
    2, 105, 3626143821, 3626143, 36261
    2, 106, 3660677822, 3660677, 36606
    2, 107, 3695211822, 3695211, 36952
    2, 108, 3729745821, 3729745, 37297
    2, 109, 3764281821, 3764281, 37642
    2, 110, 3798816822, 3798816, 37988
    2, 111, 3833351854, 3833351, 38333
    2, 112, 3867885824, 3867885, 38678
    2, 113, 3902419822, 3902419, 39024
    2, 114, 3936954649, 3936954, 39369
    2, 115, 3971486821, 3971486, 39714
    2, 116, 4006020827, 4006020, 40060
    2, 117, 4040554854, 4040554, 40405
    2, 118, 4075089825, 4075089, 40750
    2, 119, 4109625821, 4109625, 41096
    

    The median time between the iters is 345 ms, but in reality it's more like ~700 ms.

  • Elefant,

    To help debug the timing. Could you please try to integrate the attached project and see if you can post back the timing result? Thanks.

    /cfs-file/__key/communityserver-discussions-components-files/791/1817.0675.main.c

    /cfs-file/__key/communityserver-discussions-components-files/791/2705.nopRoutine.c

    Lali

  • Hi

    overhead of nopRoutine -417
    each value run for 120043 cycles

    The nopRoutine(15000)  took 19 seconds.

  • Hi,

    I found out one cause of the timing problem. TSK_sleep takes in an unsigned short (max 65535). One second translates to 100000 ticks, so it wrapped around in TSK_sleep. 

    The remaining problem is why the timing is doubled in real time: If bios.CLK.MICROSECONDS = 10  (microseconds between interrupts), 50000 ticks should be 0.5 second. But in reality it is 1.0 seconds.

  • Elefant,

    I'm unclear on your question.
    Does it have to do with the number of cycles per htime or cycles per ltime? Could you please elaborate.
    Regards,

    Lali
  • 1. CPU runs at 200 000 kHz

    GBL_getFrequency() = 200000   ( units: cycles / milliseconds )

    2. I've set bios.CLK.MICROSECONDS = 10 in the tconf so that 10 microseconds should pass between a pair of low-res interrupts (ltime). Thus, 

    CLK_cpuCyclesPerLtime() = 2000   ( units: cycles / Lintr )

    3. Hence, GBL_getFrequency() / CLK_cpuCyclesPerLtime() = 100    ( units: Lintr / milliseconds )

    4. So, if I execute TSK_sleep( 50000 ) in a task, it should sleep for 500 ms.

    However, it actually sleeps for 1000 ms. Why?

  • Elefant,

    "overhead of nopRoutine -417 
    each value run for 120043 cycles

    The nopRoutine(15000)  took 19 seconds."

    Based on the above response to the nopRoutine.

    If each value runs for (about) 120,000 cycles, and you ran it for 150,000 values.

    So it took 150,000 * 120,000 cycles = 1,800,000,000  cycles and it took about 18 seconds (the above results mentioned 19 but we round all the numbers including the response time)

    Then in each second there are 100,000,000 cycles or 100MHz

    The frequency number does not add-up.

    Lali

  • Perhaps the values reported by GBL_getFrequency(), which is 200000 kHz, is wrong.

  • Elefant,
    I have not taken a look at other possible alternatives, but do you need this function?

    Lali