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.

Does SysCtlDelay have counter wrapping issues?

I have found useful posts on how to use SysCtlDelay to implement a usec delay function.  (all my controllers run at > 1MHz).  So I ended up with a function that reads like:

inline void TMR_DelayUS(UINT8 usec) {
    // See user TivaWare user guide or
    // http://e2e.ti.com/support/microcontrollers/stellaris_arm/f/471/t/143842.aspx
    // or search for SysCtlDelay
    SysCtlDelay(usec*SysCtlClockGet()/1000000/3);
}

If I were to write this function my self using a timer, I would have to consider timer overflow.  I assume SysCtlDelay is using the sys clock timer, but does the code consider when the timer overflows?
Warning:  I have still not written a GPIO toggle function and put the above code to a test with an oscilliscope. 

P.S.  see below for better code.

  • Review of function, "SysCtlDelay()" w/in driverlib provides strong clue... 

    Multiple posts from vendor's Dave Wilson suggest that one of the many ARM timers often prove more robust & capable for your desired delay function...  (and - our small band has experimented & confirmed this timer superiority...)

    If the register referenced by, "SysCtlDelay()" is 32 bits (thus 4.294 billion) and your System Clock is 50MHz - my "back of napkin" scribble shows 85 seconds till dreaded, "overflow..." 

  • You know, I did not even realize I had the source code :|  Two years into Tiva and I have mainly looked at headers and example code.

    It looks like SysCtlDelay is just a tight assembly loop.  It probably works just fine, unless you have an interrupt.

    So I can see using a timer would make the code less impacted by interrupts - not insensitive, just less sensitive.

    Thanks for your imput.

  • John Osen said:
    I did not even realize I had the source code

    You are not alone!  Most all of our intern & new staff - even seasoned talent often miss.

    Do give a re-look @ my post - believe that your concern may not arise until 85 seconds have passed! 

    Re: Timer use - so much more capable - so much more flexible - and you can directly output the timer result.  (if config'ed as PWM - and pin is not otherwise, "in play.")

    And - as you list uS as desired delay range - might any higher priority interrupt intrude upon (thus confound) your target delay?  (i.e. do all of your interrupts execute & release in sub uS?)

    Bon chance et merci mon ami...  (I'd hitch your digital buggy to a Timer...)

  • De rien. 

    I do wish to create a StopWatch function, which is quite useful for understanding code operation and such.  This would definately need a timer.  More reason to spin up a timer.

    But as Bilbo once said, "Time!  Time!"

  • John Osen said:
    create a StopWatch function, useful for understanding code operation.  This would definitely need a timer.

    Perhaps not! 

    Present here the "cycle count" registered by the, "SysCtlClockSet()" function.  (Yes - 1.57 million cycles {31.51mS @ our 50MHz SysClock} were required)  While a properly programmed timer could provide this info - detail presented below resulted from several mouse-clicks w/in our paid IAR IDE.  (capability may exist w/in free Kickstarter version - I do not know)  A "real" IDE which supports ARM MCUs from many and is operationally robust & fast may "ping" your radar...

  • Better and tested code:

    void TMR_DelayUS(UINT8 usec) {
        // See user TivaWare user guide or
        // http://e2e.ti.com/support/microcontrollers/stellaris_arm/f/471/t/143842.aspx
        // or search for SysCtlDelay
        // passing zero gives a really long delay
        if (usec != 0) {
            // Parentheses are important due to UINT32 overflow issues
            SysCtlDelay((usec * (SysCtlClockGet() / 1000000))/(3*2));
        }
    }
    
    Using an 80MHz clock I have:
    Commanded Measured
    0 0.45
    1 3
    5 7
    10 12
    25 27
    50 52.4
    100 102
    255 258

    The .45 represents the pin toggling off, subroutine call and setup overhead. 

  • Believe this forum earlier advised that such results improved via use of the ROM version of SysCtlDelay().  And - would not "hard coding" of "SysCtlClockGet()" be more direct?

    And - adding to this challenge - may be access penalties for System Clocks beyond 40MHz.  (do check this point - may have been reserved for earlier, Stellaris family...)

  • cb1_mobile said:
    may be access penalties for System Clocks beyond 40MHz

    Why over 40MHz?  Do I recall that above 40MHz, some of the instructions start taking 2 cycles?

    I will try the ROM version of SysCtlDelay();  Thanks for the pointer.

    What do you mean by hard coding?  A HWREG reference?  The ROM_ version of SysCtrlClockGet will not likely work for me because of the 80 MHz uses a setting not support by the Set function?

  • a) Do I recall that above 40MHz, some of the instructions start taking 2 cycles?
         I believe you are correct in that (or substantially similar) recall, Sir.
     
    b) What do you mean by hard coding? 
        Simply replace the expression, "(SysCtlClockGet() / 1000000))/(3*2))" with its numeric value.  That simple.
        Why invite any complication or other source of error?
     
    As always - KISS works fastest/best - later (as/if needed) add refinement...
  • The function is a library function that will be used on multiple platforms running at different clock speeds.  I was so stuck on universal code, I short circuited on the 'hard coded' reference.

    I could declare a global constant then define specifically for each platform.  This would avoid the function call and speed up this function that needs to be as efficient as possible.

    I am rather pleased with the current state as it is greatly more accurate to what I had been using AND appears to have solved a infrequent issue, not seen since using this code.

  • John Osen said:
    AND appears to have solved an infrequent issue, not seen since using this code.

    Famous last words:

    J. Osen: "Appears to have solved..."

    G. Armstrong Custer: "Few Indians have been reported in the near vicinity of the Little Big Horn..."   ***

    ***  Your earlier stated, "counter-wrapping issue," may have impacted the good General's, "hostile count..."

    "Not seen since," normally/customarily does not rise to, "necessary & sufficient" as a sanctioned program, "fix."