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.

Bug found with InstaSpin oscillator configuration or delay function...

Other Parts Discussed in Thread: MOTORWARE, CONTROLSUITE

Hello, we'd like to report a likely bug with the InstaSpin reference design in regards to either its stock oscillator configuration or the inner working of the supplied 'usDelay()' function.

Using a stock DRV8301-HC-EVM board and unmodified TI-provided MotorWare / InstaSpin software, we have found that 'usDelay()' returns 16.6666 times faster than expected.

In other words, calling usDelay(1,000,000) will pause execution for 1/16th of a second instead of the expected one second.  These tests were of course conducted well after the board initializes the oscillator and other Picolo peripherals.

To replicate this problem, starting with the stock board & software (for the drv8301kit_revD board and f2806xF Picolo), simply insert code like the following into any sample software (just before the main control loop) and use a chronometer to time the rate-of-increase of g_nTimeInSec

for (;;) {
    usDelay(1000000);    // Delay program execution for 1 million microseconds = 1 second (###BUG: returns 16.6666 times earlier than expected!)
    g_nTimeInSec++;        // This variable should increment at the rate of 1 hertz but is instead increasing at the rate of 16.6666 hertz!
}

What could be wrong?  Is the oscillator (internal) set correctly in the ref design?  Is the usDelay() function broken?

Any hint on what to test next would be greatly appreciated!!

   Jean-Pierre

P.S. Incidently, calling usDelay(1,000,000) one thousand times will yield a delay of precisely one minute!

  • Jean-Pierre,

    The function is incorrectly named and documented.  The function originally came from controlSUITE and is called through a macro which performs some compile time math on the delay value you pass.  This macro isn't present in motorware so the value the function gets called with isn't accurate.

    You can see how this is done in controlSUITE by looking at F2806x_Examples.h:

    #define CPU_RATE 12.500L // for a 80MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 16.667L // for a 60MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 20.000L // for a 50MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 25.000L // for a 40MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 33.333L // for a 30MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 41.667L // for a 24MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 50.000L // for a 20MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 66.667L // for a 15MHz CPU clock speed (SYSCLKOUT)
    //#define CPU_RATE 100.000L // for a 10MHz CPU clock speed (SYSCLKOUT)

    ...

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

    If you add these lines to a source file, change the call from DSP28x_usDelay to usDelay, and then change the calls in your application it should work.

    I'll go ahead and file a bug for this and get this fixed in future releases.

    BR,

  • Hi Trey,

    Thanks very much for the prompt response and usable workaround.  I'll try this right away and report what the logic analyser sees.

        Jean-Pierre

  • Hi Trey,


    I am a bit confused on how to go about implementing this fix.  If I declare the following macros as you advised:

    #define CPU_RATE 12.500L // for a 80MHz CPU clock speed (SYSCLKOUT)
    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    Firstly, the unfortunately the compiler can't find DSP28x_usDelay().

    Secondly, the codebase must surely have somewhere the 'SYSCLKOUT' defined somewhere so I can calculate 'CPU_RATE' without harcoding a number?

    Thanks again! :)

  • Jean-Pierre,

    1. In my previous post I mentioned changing DSP28x_usDelay to usDelay.  What I meant was:

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

            2. I agree this should be calculated using the SYSCLK frequency, but unfortunately this doesn't really work out too well.  I've actually tried this, but because of the multiplication and division of really big numbers the math doesn't quite work out.

    BR,