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.

MSP-EXP432E401Y: System hanged at the location SysTickValueGet() called

Part Number: MSP-EXP432E401Y


Hi,

I am writing delay/sleep routine with SysTick driverlib APIs without interrupt in MSP-EXP432E401Y as follows:

    hz4milliseconds = ui32SysClock / 1000;
    
    SysTickEnable();                        // no interrupt
    SysTickIntDisable();

    while (1) {
        sleeptime = 1000;                   // 1 second
        for ( ; sleeptime > 0 ; --sleeptime) {
            SysTickPeriodSet(hz4milliseconds);
            while (SysTickValueGet() & hz4milliseconds > 0) ;
            // while (SysTickValueGet() > 0) ;
        }

        GPIO_toggle(CONFIG_GPIO_LED_0);
    }

I would like to make LED toggling every 1 second, but execution hanged at SysTickValueGet().

Please advise me how to solve this problem.

Any help/tips are appreciated in advance.

HaeSeung

  • >  while (SysTickValueGet() & hz4milliseconds > 0) ;

    I'm not completely sure what you intended, but maybe you meant "-" instead of "&"? Even with this change, this is unlikely to work since there will only be one CPU cycle (too short to see) where the condition is false (note: arithmetic will be unsigned).

    I suggest instead something like:

    > SysTickPeriodSet(0xFFFFFF+1);   // Full range, once and forever

    > SysTickEnable();   // Once and forever

    then in the loop:

    > uint32_t start = SysTickValueGet();   

    > while (((start-SysTickValueGet()) & 0xFFFFFF) < hz4milliseconds) /*EMPTY*/;  // Watch down-counter difference (24 bits)

    The unsigned (24-bit) arithmetic will deal with timer wrap up to (16M/120MHz)= ~139msec.

    [Edit: This is untested, but I think it's about right.]

  • Hi,

      Systick counter is only 24-bit wide and will not give you a 1 second period but rather a maximum of ~139ms as explained by Bruce. I will suggest you use the general purpose timer in 32bit mode to achieve the 1 second timeout. There is an example for it at C:\ti\simplelink_msp432e4_sdk_4_20_00_12\examples\nortos\MSP_EXP432E401Y\driverlib\gpt_32bit_periodicmode_interrupt. In this example. the LED is toggled every 1 second. 

  • Dear Bruce and Charles,

    Your tips are very helpful to solve this problem. Final code as follows:

        volatile uint32_t elapsedTime;
        uint32_t          startTime;
    
        hz4milliseconds = ui32SysClock / 1000;	// period for 1 milli second
    
        SysTickEnable();                        // enable module
        SysTickIntDisable();					// no interrupt
        SysTickPeriodSet(hz4milliseconds);
    
        while (1) {
            sleeptime = 1000;                   // 1 second
            for ( ; sleeptime > 0 ; --sleeptime) {
                // repeatedly evaluate elapsed time till 1 milli sec
                startTime = SysTickValueGet();
                do {
                    elapsedTime = (startTime - SysTickValueGet()) & 0x00FFFFFF;
                }
                while(elapsedTime <= hz4milliseconds);
            }
    
            GPIO_toggle(CONFIG_GPIO_LED_0);
        }

    Thanks, both of you.

    HaeSeung

  • I hesitate to argue with success, but I'm concerned this code may get you in trouble someday.

    Skipping to the end:

    >  SysTickPeriodSet(hz4milliseconds);

    I (still) recommend instead:

    > SysTickPeriodSet(0xFFFFFF+1);   // Full range, once and forever

    ---------

    This code is doing modulo-16M (24-bit) arithmetic on a modulo-120K value. This will work-by-accident most of the time, since each time the timer wraps (through 0) the modulo-16M difference will appear as a large (unsigned) value, so the loop will exit.

    But there are corner cases. Existence proof: Since the startTime is being fetched at some (unknown) point in the cycle, it is possible it will fetch the value (120000-1). When the counter counts to 0, the difference will be (120000-1), and when the counter wraps back to (120000-1) the difference will go back to 0; as a result, the loop will never exit. The "failure band" is actually much larger than this, since the code in the loop will add many CPU clocks of uncertainty.

    Doing modulo-120K arithmetic (besides being extra trouble) won't help, since then the difference will never exceed the modulus. The solution is to use a modulus (SysTick period) much larger than your timing period (1ms), and modulo-16M (~139ms) is very convenient for your arithmetic.

  • I fixed my code as recommended.

    Thanks a lot, Bruce.

    HaeSeung