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.

TMS320F28379D: how did the DEVICE_DELAY_US(x) function works in TI CCS?

Part Number: TMS320F28379D
Other Parts Discussed in Thread: LAUNCHXL-F28379D, C2000WARE

Hi Professionals,

I am studying how to play with the TI C2000 MCU with the TI CCS platform. Right now I am using the "LAUNCHXL-F28379D".

When I was digging the steps of the blinkyled example of TI's, I tried my best to understand every function it called but I encountered one that I don't understand, which is what the title mentioned: “DEVICE_DELAY_US(x)”.

By opening the declaration it refers to, I can see that DEVICE_DELAY_US(x)” is:

#define DEVICE_DELAY_US(x) SysCtl_delay( ( ( ((long double)(x)) / (1000000.0L / (long double)DEVICE_SYSCLK_FREQ) ) - 9.0L) / 5.0L).

Using the LAUNCHXL-F28379D I have, the above-mentioned equation would be:

(200x - 9) / 5 --> number of cycles used in SysCtl_delay; cycles is the number of OSCCLK cycles

I checked that "DEVICE_SYSCLK_FREQ" is 2e8 so the equation above should be solid. As for the OSCCLK cycles, what I understand is that it refers to the external crystal of the board, which is 10MHz, aka the time period of the cycle would be 1/10MHz=1e-7s per cycle.

Let's say x is 5e6. By the meaning of the function DEVICE_DELAY_US(x)”, I should get around a 5s delay. Indeed the LED in the "LAUNCHXL-F28379D" board reacts accordingly, aka every 5s. However, according to the equation I show above, you will get:

(200x - 9) / 5 ~= 2e8 cycles --> time period of 2e8 cycles would be 2e8*1e-7 = 20s.

20s V.S 5s. That's a big difference! So I am asking is there anything I misunderstood?

  • Shaojun,

    This statement is incorrect

    (200x - 9) / 5 --> number of cycles used in SysCtl_delay; cycles is the number of OSCCLK cycles

    it should be cycles in the SYSCLK domain, post any PLL multipliers etc since this function will run at the system clock frequency.

    The source file for this is in C2000Ware in this path: C:\ti\c2000\C2000Ware_4_00_00_00\device_support\f2837xd\common\source\F2837xD_usDelay.asm

    Let me know if this clears things up.  If there is a comment in TI source that says OSCCLK cycle, let me know the file name so I can get this corrected.

    Best,

    Matthew

  • Hi Mathew,

    Thanks for your reply.

    I am not familiar with the assembly files, but if it is using the SYSCLK and without using any CLK divider, then it would be:

    (200x - 9) / 5  ~= 2e8 cycles --> time period of 2e8 cycles would be 2e8*(1/200MHz) = 2e8*5e-9 = 1s.

    Still not getting the 5s result. Or is it using some CLK divider somewhere?

    The reason why I said "cycles is the number of OSCCLK cycles" is that I found the declaration of the function "SysCtl_delay()" in: \ti\ccs1100\C2000Ware_4_00_00_00\driverlib\f2837xd\driverlib\sysctl.h, with the following statement:

    //*****************************************************************************
    //
    //! Delays for a fixed number of cycles.
    //!
    //! \param count is the number of delay loop iterations to perform.
    //!
    //! This function generates a constant length delay using assembly code. The
    //! loop takes 5 cycles per iteration plus 9 cycles of overhead.
    //!
    //! \note If count is equal to zero, the loop will underflow and run for a
    //! very long time.
    //!
    //! \note Refer to the macro DEVICE_DELAY_US(x) in device.h which can be used to
    //! insert a delay in microseconds.
    //!
    //! \return None.
    //
    //*****************************************************************************
    extern void
    SysCtl_delay(uint32_t count);

    This statement does not indicate what "cycles" mean. However, in line No.1600 of this file, it has:

    //! \param cycles is the number of OSCCLK cycles.

  • Shaojun,

    Can you comment on the version of C2000Ware you are using?  I have V4.0 and the functions are defined as follows:

    #define DELAY_US(A)  F28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    Where CPU rate is set as follows for 200MHz F28379D:

    //  Specify the clock rate of the CPU (SYSCLKOUT) in nS.
    //
    //  Take into account the input clock frequency and the PLL multiplier
    //  selected in step 1.
    //
    //  Use one of the values provided, or define your own.
    //  The trailing L is required tells the compiler to treat
    //  the number as a 64-bit value.
    //
    //  Only one statement should be uncommented.
    //
    //  Example:   200 MHz devices:
    //             CLKIN is a 10 MHz crystal or internal 10 MHz oscillator
    //
    //             In step 1 the user specified the PLL multiplier = 40 for a
    //             200 MHz CPU clock (SYSCLKOUT = 200 MHz).
    //
    //             In this case, the CPU_RATE will be 5.000L
    //             Uncomment the line: #define CPU_RATE 5.000L
    //
    
    #define CPU_RATE   5.00L   // for a 200MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE   5.263L   // for a 190MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   5.556L   // for a 180MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   5.882L   // for a 170MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   6.250L   // for a 160MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   6.667L   // for a 150MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   7.143L   // for a 140MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   7.692L   // for a 130MHz CPU clock speed  (SYSCLKOUT)
    //#define CPU_RATE   8.333L   // for a 120MHz CPU clock speed  (SYSCLKOUT)
    

    Here is the assembly macro, explaining the context of the math translation:

            .global  __F28x_usDelay
    _F28x_usDelay:
            SUB    ACC,#1
            BF     _F28x_usDelay,GEQ    ;; Loop if ACC >= 0
            LRETR
    
    ;There is a 9/10 cycle overhead and each loop
    ;takes five cycles. The LoopCount is given by
    ;the following formula:
    ;  DELAY_CPU_CYCLES = 9 + 5*LoopCount
    ; LoopCount = (DELAY_CPU_CYCLES - 9) / 5
    ; The macro DELAY_US(A) performs this calculation for you
    ;