[CIQBUG] One-Shot Timer Code Resets Vivoactive 2.70

The following code will reset Vivoactive hardware running version 2.70 firmware to the power-up screen, but works fine on the simulator. Please see attached error log.

using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
using Toybox.Lang as Lang;
using Toybox.Timer as Timer;

class TimerTestView extends Ui.WatchFace {

var timer1;
var updateCount = 0;

function callback1()
{
Ui.requestUpdate();
}

function onLayout(dc)
{
timer1 = new Timer.Timer();
}

function onUpdate(dc)
{
var string;

dc.setColor( Gfx.COLOR_BLACK, Gfx.COLOR_BLACK );
dc.clear();
dc.setColor( Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT );
string = "Count: " + updateCount;
dc.drawText( 40, (dc.getHeight() / 2) - 30, Gfx.FONT_MEDIUM, string, Gfx.TEXT_JUSTIFY_LEFT );

updateCount++;
timer1.start( method(:callback1), 200, false );
}


//! The user has just looked at their watch. Timers and animations may be started here.
function onExitSleep() {
}

//! Terminate any active timers and prepare for slow updates.
function onEnterSleep() {
timer1.stop();
}

}


  • If you create an empty file called CIQ_LOG.txt in "apps/logs" on the device you'll probably get more info on this. I suspect it has something to do with the timer1.stop() though.
  • It crashes on a 920xt as well. It doesn't take the entire device down, but the watch face vanishes and the default watch face replaces it. The fact that it takes the device down is definitely a bug, but I believe you're code is actually doing something illegal.

    Here is the contents of CIQ_LOG.txt after the crash on my 920xt.

    in C:\Development\Projects\Power\source\PowerApp.mc (onUpdate:34)
    in C:\Development\Projects\Power\source\PowerApp.mc (onUpdate:34)
    TVM ERROR:
    Permission Required
    Failed invoking <symbol>

    TVM ERROR:
    Permission Required
    failed in cdp_tvm_invoke


    Line 34 is

    32 updateCount++;
    33 timer1.start( method(:callback1), 200, false );
    34 }


    I'm guessing the problem is that you are trying to start a timer after timers have been disabled by the system. This is a big no-no. The solution is to remove the timer.start() out of your onUpdate() function. The following works just fine.

    class TimerTestView extends Ui.WatchFace
    {
    var timer1;
    var updateCount = 0;

    function callback1() {
    Ui.requestUpdate();
    }

    function initialize() {
    timer1 = new Timer.Timer();
    }

    // helper function
    hidden function startTicking() {
    timer1.start(method(:callback1), 200, true);
    }

    // helper function
    hidden function stopTicking() {
    timer1.stop();
    }

    function onShow() {
    startTicking();
    }

    function onHide() {
    stopTicking();
    }

    function onUpdate(dc) {
    dc.setColor( Gfx.COLOR_BLACK, Gfx.COLOR_BLACK );
    dc.clear();

    var string = "Count: " + updateCount;

    dc.setColor( Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT );
    dc.drawText( 40, (dc.getHeight() / 2) - 30, Gfx.FONT_MEDIUM, string, Gfx.TEXT_JUSTIFY_LEFT );

    updateCount++;
    }

    function onExitSleep() {
    startTicking();
    }

    function onEnterSleep() {
    stopTicking();
    }
    }


    Travis
  • I suspect this is related to the other issue LDSLARON reported (https://forums.garmin.com/showthread.php?244999-Vivoactive-Can-Update-Forever-at-1-Hz), and I can confirm it only affects the vivoactive. The FR920 and fenix 3 both handle this "gracefully" by dropping back to the default watch face. In a case like this, I would expect the vivoactive to do the same thing. I'll file another bug report and link it to the other mentioned above since they sound similar.