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.

CCS/TMS320C6748: How to obtain stable 10us interrupt

Part Number: TMS320C6748
Other Parts Discussed in Thread: SYSBIOS

Tool/software: Code Composer Studio

Hi,

A few days ago, I found the timer interruption unstable during a test. First, I suspect the HWI DISPATCHER caused it.

So, I turn to TI for help. With the help of Sahin, I achieved an interrupt without DISPATCHER. The method can be found here.

https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/355/t/372449

Unfortunately, the problem has not been solved.The timer interrupt function is not stable.For the latest test I used external interrupts.

Trigger signal is generated by FPGA. I have found that each unstable clock cycle approaches the correct value multiple.

So I wonder if the interrupt DISABLE of the SYSBIOS caused the instability.

Is there any one who can give me some guidance?

Interrupt cycle 10us

Regards,

Dor

  • Hello,

    A similar issue was resolved in the following thread. Could you please try the suggestions from it and let us know?

    Long HWI interrupt latency on OMAP-L138 DSP (C6748); improvements?

    Regards,
    Sahin

  • Thank you Sabin, it looks very useful. I'll have a try.

  • Hi Sahin,

            I have tested this approach. Most of the interruptions are timely.  Sometimes, however, it is still unstable.

    The method provided by Graham has skipped the HWI DISPATCHER, I can't understand what causes the time jitter.

    Anything wrong with the time test method?

        time_diff = TSCL - time_stamp;
        time_stamp = TSCL;

    Or, the debugger has an impact on testing?

    Regards,

    Dor

  • Hi Dor,

    Are you disabling interrupts at any point in your application? This could be affecting your time cycle. 

    It would be good to calculate the overhead of getting the timestamp, and subtract that from your calculation too.

    Can you describe the behavior you're observing in more detail? Is there a pattern? How far off from the expected value?

    Which version of SYSBIOS are you using?

    Regards,
    Sahin

  • Hi Sahin,

             I didn't disable the interrupt anywhere. The SYSBIOS version is 6.37.03.30. 

    time_diff = TSCL - time_stamp;       // Tick count
    time_stamp = TSCL;

    time_diff_d = (double)time_diff / 456;  // Convert to us

    if (time_diff_d < time_diff_min)       // Capture minimum
    {
           time_diff_min = time_diff_d;
    }
    else if (time_diff_d > time_diff_max)      // Capture maximum
    {
           time_diff_max = time_diff_d;
    }

             Most of the time the "time_diff_d" is 10.  The minimum is 8, and the maximum is 12

    By the way,  I didn't create any task. There is only one timer interrupt in this project.

    If add the NDK and NSP, it's even worse.

    Regards,

    Dor

  • Would you be able to share more of your code?

    Do you have any printfs in your code? These typically take a long time and may be impacting your timer. 

    What does your ISR look like?

    What frequency are you running the DSP?

    Regards,
    Sahin

  • I used CCS5.5 to create a typical SYSBIOS project with main.c. No other special configuration in app.cfg.
    //---------------------------------------------------------------
    // Here is the timer initialization code.

    //---------------------------------------------------------------

    Timer_Params timerParams;
    Timer_Handle myTimer;
    Error_Block eb;
    
    Error_init(&eb);
    Timer_Params_init(&timerParams);
    
    timerParams.period = 10;
    timerParams.periodType = Timer_PeriodType_MICROSECS;
    timerParams.startMode = Timer_StartMode_AUTO;
    timerParams.runMode = Timer_RunMode_CONTINUOUS;
    timerParams.intNum = 4;
    
    myTimer = Timer_create(1, TimerIsr, &timerParams, &eb);
    if (myTimer == NULL)
    {
        System_abort("Timer create failed");
    }

    //---------------------------------------------------------------

    // Interrupt handler

    //---------------------------------------------------------------

    Void TimerIsr(UArg arg)
    {
        time_diff = TSCL - time_stamp;    // Now ticks - previous
        time_stamp = TSCL;               // For next time
    
        time_diff_d = (double)time_diff / 456;   // Convert
    
        if (time_diff_d < time_diff_min)    // Get max and min value.
        {
            time_diff_min = time_diff_d;
        }
        else if (time_diff_d > time_diff_max)
        {
            time_diff_max = time_diff_d;
        }
    
        if (init < 65535)   // Delay
        {
            init++;
            time_diff_min = 10000;
            time_diff_max = 0;
        }
    }

    There are 2 tasks in this project. The code is as follows.

    Void taskFxn(UArg a0, UArg a1)
    {
        while(1)
        {
            Task_sleep(10);
        }
    }

    Here, the result.

    The freqency is 456 Mhz. No printf or other BIG functions.

    Regards,

    Dor

  • Hello,

    I don't see anything wrong with the code you provided. It should be firing an interrupt every 10us as specified. The only thing I can think of is if you're using breakpoints, or the calculations in the ISR are affecting the timer period. 

    It may be worth trying to only toggle a GPIO in the ISR and probing the pin with a scope to verify the period.

    Can you try with this sample code below and let me know if you are observing the same behavior?

    /*
     *  ======== main.c ========
     */
    
    #include <xdc/std.h>
    #include <ti/sysbios/hal/Timer.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    #include <c6x.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #include <time.h>
    clock_t t_start, t_stop, t_diff;
    
    Void TimerIsr(UArg arg)
    {
        t_stop = _itoll(TSCH, TSCL);
        t_diff = t_stop - t_start;
        t_start = _itoll(TSCH, TSCL);
    
        System_printf("Time diff in cycles: %d\n", t_diff);
    
    }
    /*
     *  ======== taskFxn ========
     */
    
    Void taskFxn(UArg a0, UArg a1)
    {
        Error_Block eb;
        Timer_Params timerParams;
        Timer_Handle myTimer;
    
        Error_init(&eb);
        Timer_Params_init(&timerParams);
    
        timerParams.period = 10;
        timerParams.periodType = Timer_PeriodType_MICROSECS;
        timerParams.startMode = Timer_StartMode_AUTO;
        timerParams.runMode = Timer_RunMode_CONTINUOUS;
    
        myTimer = Timer_create(1, TimerIsr, &timerParams, &eb);
        if (myTimer == NULL)
        {
            System_abort("Timer create failed");
        }
    
        /* Initialize timer for clock */
        TSCL = 0, TSCH = 0;
    
        t_start = _itoll(TSCH, TSCL);
    
        while (1);
    }
    
    /*
     *  ======== main ========
     */
    Int main()
    {
        Task_Handle task;
        Error_Block eb;
    
        Error_init(&eb);
        task = Task_create(taskFxn, NULL, &eb);
        if (task == NULL)
        {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }
    
        BIOS_start(); /* does not return */
        return (0);
    }
    

    Regards,
    Sahin