ChronosTraining

Documentation for visualSTATE project 'ChronosTraining'



This document was created by visualSTATE Documenter 6, 3, 1, 1801 Copyright 1991 - 2009 IAR Systems . All rights reserved.


Model design

visualSTATE Signature Generator: "50"

Project Signature: "ba48 8e52 2735 852c 3361 5c36"

Chart

Hierarchy

Elements

Trainer

Chart

App (top)

Path: Trainer

Elements

Events

Action functions

External variables

Internal variables

Signals

Constants

Transitions

BaseApp

Path: Trainer :App

Reactions and default transitions

Chart

Hierarchy

States

WelcomeScreen

Path: Trainer :App .BaseApp

Reactions and default transitions

SetLowInterval

Path: Trainer :App .BaseApp

Reactions and default transitions

SetHighInterval

Path: Trainer :App .BaseApp

Reactions and default transitions

SetHighGoalRate

Path: Trainer :App .BaseApp

Reactions and default transitions

Training

Path: Trainer :App .BaseApp

Reactions and default transitions

LowInterval

Path: Trainer :App .BaseApp .Training

HighInterval

Path: Trainer :App .BaseApp .Training

Reactions and default transitions

SetRounds

Path: Trainer :App .BaseApp

Reactions and default transitions

WaitToGo

Path: Trainer :App .BaseApp

Summary

Path: Trainer :App .BaseApp

Reactions and default transitions

NoStrap

Path: Trainer :App .BaseApp

Battery

Path: Trainer :App

Reactions and default transitions

Chart

Hierarchy

States

MeasureBattery

Path: Trainer :App .Battery

LowBattery

Path: Trainer :App .Battery

Reactions and default transitions

IdleMode

Path: Trainer :App .Battery

Radio

Path: Trainer :App

Chart

Hierarchy

States

RadioOff

Path: Trainer :App .Radio

Reactions and default transitions

RadioActive

Path: Trainer :App .Radio

RadioSearching

Path: Trainer :App .Radio


Model test

Verificator result files

C:\IntervalTrainingPublishItems\Interval3PublishItems\Interval3\VSModel\verification.vre

/*****************************************************************************
* visualSTATE Verificator Report
* Generated by visualSTATE Verificator 6, 3, 1, 1801
* Time: 2010-02-19 13:30:30
* visualSTATE Project File: <ChronosTraining.vsp>
* visualSTATE Signature Generator: "50"
* Project Signature: "ba48 8e52 2735 852c 3361 5c36"
*****************************************************************************/


PROJECT INFORMATION

  Project Name: ChronosTraining

  Explanation:
    ""

******************************************************************************


SYSTEM INFORMATION

  System Name: Trainer

  Explanation:
    ""


ASSUMPTIONS

Verification is performed in forward mode.
Both guards and assignments are included in the verification.
Alternative verification engine (CUDD) and automatic variable reordering will be used.
Verification is performed using a signal queue of length 2.


USE OF ALL ELEMENTS

External variables which are never used:
HeartRateBR

Constants which are never used:
cBatteryHighTreshold cRadioSearch

Action functions which are never used:
ClearLINE1 ClearLINE2

Signals which are never used for triggering a transition:
sRadioOff



ACTIVATION OF ALL ELEMENTS

External variables which are never activated:
HeartRateBR

Constants which are never activated:
cBatteryHighTreshold cRadioSearch

Action functions which are never activated:
ClearLINE1 ClearLINE2

Signals which are never activated for triggering a transition:
sRadioOff



CONFLICTS




STATE DEAD ENDS

App.Battery.LowBattery


LOCAL DEAD ENDS

Local dead end for the machine: M_App_BaseApp
{App.BaseApp.SetRounds, App.BaseApp.NoStrap} x {App.Battery.LowBattery} x {App.Radio.RadioOff}
{App.BaseApp.NoStrap} x {App.Battery.LowBattery} x {App.Radio.RadioActive, App.Radio.RadioSearching}

Local dead end for the machine: M_App_Battery
{*} x {App.Battery.LowBattery} x {*} x {*}

Local dead end for the machine: M_App_Radio
{*} x {App.Battery.LowBattery} x {App.Radio.RadioOff} x {*}


SYSTEM DEAD ENDS

{App.BaseApp.SetRounds, App.BaseApp.NoStrap} x {App.Battery.LowBattery} x {App.Radio.RadioOff}

DOMAIN ERRORS



AMBIGUOUS ASSIGNMENTS (static check)



AMBIGUOUS ASSIGNMENTS (dynamic check)



SIGNAL QUEUE

The signal queue has the right size.

Verificator completed - 0 error(s), 18 warning(s).

Model interface

Events

EventPathExplanation
e1Hz () Trainer :App This event is generated by a periodic 1 Hz interrupt.
The model uses the event to trigger for example display updates
and fetching of BlueRobin data (i.e heart rate).
eButton_M1 () Trainer :App Event corresponding to the top left button on the clock housing. (Marked '*')
eButton_M2 () Trainer :App Event corresponding to the bottom left button on the clock housing. (Marked '#')
eButton_S1 () Trainer :App Event corresponding to the top
right button on the clock housing. (Marked 'Up Arrow')
eButton_S2 () Trainer :App Event corresponding to the bottom right button on the clock housing. (Marked 'Down Arrow')
eRadioSearchTimeout () Trainer :App Event sent to the model when the radio search timeout triggers.
eRestIntervalExpired () Trainer :App Event to indicate that the resting interval between two high
intensity intervals has expired.

(It is not strictly necessary to have two
different events for the expiry of the low- and high intensity intervals. The model can be somewhat
simplified by utilizing one event for both situations as they are mutually exclusive.)
eWorkIntervalExpired () Trainer :App Event to indicate when the high intensity phase is over for this round.

(It is not strictly necessary to have two
different events for the expiry of the low- and high intensity intervals.
The model can be somewhat
simplified by utilizing one event for both situations as they
are mutually exclusive.)

Action functions

Action functionPathExplanation
extern VS_VOID ClearLINE1 () Trainer :App Function to clear the 7-segment characters on display-line 1.
extern VS_VOID ClearLINE2 () Trainer :App Function to clear the 7-segment characters on display-line 2.
extern VS_VOID ClearScreen () Trainer :App Clears LINE1 and LINE2 7-segment characters.
extern VS_VOID ClearTimeForDisplay () Trainer :App This function just zeroes the variable used to hold an integer denoting
the time in seconds spent in the current rest or training interval.

Note that the variable is defined as a static within the action function implementation file.
extern VS_VOID Display8bitNum (VS_UINT8 num) Trainer :App Display generic 8 bit unsigned number on LINE2.
extern VS_VOID DisplayCriticalBattery () Trainer :App This function turns on the battery symbol in blinking mode
extern VS_VOID DisplayHeartrateBR () Trainer :App This function displays an 8-bit value from an "external" variable declared in the model.
However, the value of the variable is set by the accompanying function GetHeartRateBR()

The reason for this implementation style is that the
heart rate is now available both inside and outside the model and can be used if needed, but the model
is not cluttered with unnecessary assignments and parameter passing to the heart rate display function.
extern VS_VOID DisplayInitialMessage () Trainer :App Displays a welcome string that with some good will can be interpreted as "Interval training"... :-)
extern VS_VOID DisplayStringConstant (VS_UINT8 literalNumber) Trainer :App Function to display one of a set of predefined constant strings. The strings are stored in an array and indexed by the function parameter. Additional 4-letter strings can easily be defined and used.
The string collection can be found in VS_ActionFunctions.c
extern VS_VOID GetHeartRateBR () Trainer :App Query the BlueRobin interface for the latest heart rate measurement.
Assign the value to the "external" variable HeartRateBR. The heart rate value is thus available both inside the model and outside it.
extern VS_VOID IncreaseAndDisplayTime () Trainer :App This function increments and
displays the value of static unsigned 8-bit variable.
The function is called once a second and is used to
display the number of seconds spent in the current interval (rest or activity).
extern VS_VOID InitSoftwareTimers () Trainer :App Call the software timer initialization code in the software timer module. This model uses two software timers.
(See the description of the timer action functions for more details on sdesign choices etc)
extern VS_UINT16 MeasureVoltage () Trainer :App
extern VS_VOID RadioCloseDown () Trainer :App
extern VS_UINT8 RadioGetState () Trainer :App
extern VS_VOID RadioInit () Trainer :App
extern VS_VOID RadioShowActive () Trainer :App
extern VS_VOID RadioStart () Trainer :App
extern VS_VOID StartOneBuzz () Trainer :App Do a short 'buzz' on the buzzer
extern VS_VOID StartTwoBuzz () Trainer :App Do two short consecutive buzzes on the buzzer.
extern VS_VOID TimerRadioSearchTimeout (VS_UINT event, VS_UINT ticks) Trainer :App This timer is started when the radio search is initiated. We use a 10-seconds timeout for the state machine. The underlying radio interface is set by the application to stop searching after 8 seconds.
We are using the generated event to escape the Searching state and go back to the RadioOff state.
This timer must be independent from the two other timers in the example, so we cannot reuse one of them.
extern VS_VOID TimerRestInterval (VS_UINT event, VS_UINT ticks) Trainer :App A timer action function is an easy-to-use abstraction to handle timing intervals. The timer action function is called with two arguments, the delay in 'ticks' and the event to send back to the state machine when the timer expires. The timer action function can be implemented in any way fit for the application. In this application we have chosen to implement the underlying timer functionality with a software timer module.
The TimerRestInterval() function thus initializes and starts a timer from the software timer package. That timer will count up the number of ticks specified and then put the specified event into the event queue.

Note: We have chosen to define one timer action for the rest interval and one for the work interval and use a separate software timer for the each interval.
It would be just as easy to use only one timer action and one softare timer in this example because the two timers are never active at the same time.
It would also be possible to have two timer action functions sharing one software timer.

The software timer ticks are driven by a 1Hz interrupt that calls an update function that also takes care of posting the event in case of time out for a timer.
extern VS_VOID TimerWorkInterval (VS_UINT event, VS_UINT ticks) Trainer :App

External variables

External variablePathExplanation
VS_UINT8 HeartRateBR = 0 Trainer :App This variable is defined by the model and available for the driver code. It is among other things used to store the received heart rate from the BlueRobin stack.

Constants

ConstantPathExplanation
VS_UINT16 cBatteryHighTreshold = 360 Trainer :App
VS_UINT16 cBatteryLowTreshold = 240 Trainer :App
VS_UINT8 cHighHeartRateString = 2 Trainer :App Index number into an array of short strings for display
VS_INT cHighIntervalString = 0 Trainer :App Index number into an array of short strings for display
VS_UINT8 cLoIntervalString = 1 Trainer :App Index number into an array of short strings for display
VS_UINT8 cNoRFString = 4 Trainer :App
VS_UINT8 cRadioActive = 1 Trainer :App Adapted from BlueRobin interface
VS_UINT8 cRadioOff = 0 Trainer :App Adapted from BlueRobin interface
VS_UINT8 cRadioSearch = 2 Trainer :App Adapted from BlueRobin interface
VS_UINT8 cSetRoundsString = 3 Trainer :App Index number into an array of short strings for display

Pseudo code

Project ChronosTraining
{
  SignalQueueOverflowBehavior: errorIfFull;
  Elements 
  {
  }
  System Trainer
  {
    Instances: 1;
    SignalQueueLength: 2;
    TopState App;
  }
}

TopState Trainer:App
{
  Elements 
  {
    Events 
    {
      e1Hz ();  /* This event is generated by a periodic 1 Hz interrupt. 
The model uses the event to trigger for example display updates 
and fetching of BlueRobin data (i.e heart rate). */ 
      eButton_M1 ();  /* Event corresponding to the top left button on the clock housing. (Marked '*') */ 
      eButton_M2 ();  /* Event corresponding to the bottom left button on the clock housing. (Marked '#') */ 
      eButton_S1 ();  /* Event corresponding to the top 
right button on the clock housing. (Marked 'Up Arrow') */ 
      eButton_S2 ();  /* Event corresponding to the bottom right button on the clock housing. (Marked 'Down Arrow') */ 
      eRadioSearchTimeout ();  /* Event sent to the model when the radio search timeout triggers. */ 
      eRestIntervalExpired ();  /* Event to indicate that the resting interval between two high 
intensity intervals has expired.

(It is not strictly necessary to have two 
different events for the expiry of the low- and high intensity intervals. The model can be somewhat 
simplified by utilizing one event for both situations as they are mutually exclusive.) */ 
      eWorkIntervalExpired ();  /* Event to indicate when the high intensity phase is over for this round.

(It is not strictly necessary to have two 
different events for the expiry of the low- and high intensity intervals. 
The model can be somewhat 
simplified by utilizing one event for both situations as they 
are mutually exclusive.) */ 
    }
    ActionFunctions 
    {
      extern VS_VOID ClearLINE1 ();  /* Function to clear the 7-segment characters on display-line 1. */ 
      extern VS_VOID ClearLINE2 ();  /* Function to clear the 7-segment characters on display-line 2. */ 
      extern VS_VOID ClearScreen ();  /* Clears LINE1 and LINE2 7-segment characters. */ 
      extern VS_VOID ClearTimeForDisplay ();  /* This function just zeroes the variable used to hold an integer denoting 
the time in seconds spent in the current rest or training interval.

Note that the variable is defined as a static within the action function implementation file.
  */ 
      extern VS_VOID Display8bitNum (VS_UINT8 num);  /* Display generic 8 bit unsigned number on LINE2. */ 
      extern VS_VOID DisplayCriticalBattery ();  /* This function turns on the battery symbol in blinking mode */ 
      extern VS_VOID DisplayHeartrateBR ();  /* This function displays an 8-bit value from an "external" variable declared in the model.
However, the value of the variable is set by the accompanying function GetHeartRateBR()

The reason for this implementation style is that the 
heart rate is now available both inside and outside the model and can be used if needed, but the model 
is not cluttered with unnecessary assignments and parameter passing to the heart rate display function. */ 
      extern VS_VOID DisplayInitialMessage ();  /* Displays a welcome string that with some good will can be interpreted as "Interval training"... :-) */ 
      extern VS_VOID DisplayStringConstant (VS_UINT8 literalNumber);  /* Function to display one of a set of predefined constant strings. The strings are stored in an array and indexed by the function parameter. Additional 4-letter strings can easily be defined and used. 
The string collection can be found in VS_ActionFunctions.c */ 
      extern VS_VOID GetHeartRateBR ();  /* Query the BlueRobin interface for the latest heart rate measurement.
Assign the value to the "external" variable HeartRateBR. The heart rate value is thus available both inside the model and outside it. */ 
      extern VS_VOID IncreaseAndDisplayTime ();  /* This function increments and 
displays the value of static unsigned 8-bit variable.
The function is called once  a second and is used to 
display the number of seconds spent in the current interval (rest or activity). */ 
      extern VS_VOID InitSoftwareTimers ();  /* Call the software timer initialization code in the software timer module. This model uses two software timers. 
(See the description of the timer action functions for more details on sdesign choices etc) */ 
      extern VS_UINT16 MeasureVoltage ();
      extern VS_VOID RadioCloseDown ();
      extern VS_UINT8 RadioGetState ();
      extern VS_VOID RadioInit ();
      extern VS_VOID RadioShowActive ();
      extern VS_VOID RadioStart ();
      extern VS_VOID StartOneBuzz ();  /* Do a short 'buzz' on the buzzer */ 
      extern VS_VOID StartTwoBuzz ();  /* Do two short consecutive buzzes on the buzzer. */ 
      extern VS_VOID TimerRadioSearchTimeout (VS_UINT event, VS_UINT ticks);  /* This timer is started when the radio search is initiated. We use a 10-seconds timeout for the state machine. The underlying radio interface is set by the application to stop searching after 8 seconds.
We are using the generated event to escape the Searching state and go back to the RadioOff state.
This timer must be independent from the two other timers in the example, so we cannot reuse one of them.		 */ 
      extern VS_VOID TimerRestInterval (VS_UINT event, VS_UINT ticks);  /* A timer action function is an easy-to-use abstraction to handle timing intervals. The timer action function is called with two arguments, the delay in 'ticks' and the event to send back to the state machine when the timer expires.  The timer action function can be implemented in any way fit for the application. In this application we have chosen to implement the underlying timer functionality with a software timer module.
The TimerRestInterval() function thus initializes and starts a timer from the software timer package. That timer will count up the number of ticks specified and then put the specified event into the event queue.

Note: We have chosen to define one timer action for the rest interval and one for the work interval and use a separate software timer for the each interval.
It would be just as easy to use only one timer action and one softare timer in this example because the two timers are never active at the same time.
It would also be possible to have two timer action functions sharing one software timer.

The software timer ticks are driven by a 1Hz interrupt that calls an update function that also takes care of posting the event in case of time out for a timer.
 */ 
      extern VS_VOID TimerWorkInterval (VS_UINT event, VS_UINT ticks);
    }
    ExternalVariables 
    {
      VS_UINT8 HeartRateBR = 0;  /* This variable is defined by the model and available for the driver code. It is among other things used to store the received heart rate from the BlueRobin stack. */ 
    }
    InternalVariables 
    {
      VS_UINT8 HiGoalHR = 0;  /* This variable is used to store the desired goal heart rate for the work intervals. */ 
      VS_UINT8 HighIntervalTime = 0;  /* Desired work interval time. The user can change this in steps of +/- 15 seconds */ 
      VS_UINT8 LowIntervalTime = 0;  /* Desired rest interval time. The user can change this in steps of +/- 15 seconds.  */ 
      VS_UINT8 Rounds = 0;  /* Number of desired repetitions of the work/rest cycle. */ 
      VS_UINT8 SecondsBetweenBattMeas<0, 60> = 0;
      VS_UINT16 voltage = 0;
    }
    Signals 
    {
      sLowBattery;  /* Sent by the battery state machine when entering the LowBattery state. Is used as trigger in the Training state to exit training mode if battery voltage is too low. */ 
      sRadioActive;  /* This signal is emitted from the radio state machine when radio start is confirmed. */ 
      sRadioOff;  /* This signal is emitted by the radio state machine when the radio is confirmed to be off. */ 
      sTurnRadioOff;  /* This signal can be used by any part of the state machine to request the radio service to be turned off. */ 
      sTurnRadioOn;  /* This signal can be used by any region in the state machine to signal that it wants the radio service to start.
 */ 
    }
    Constants 
    {
      VS_UINT16 cBatteryHighTreshold = 360;
      VS_UINT16 cBatteryLowTreshold = 240;
      VS_UINT8 cHighHeartRateString = 2;  /* Index number into an array of short strings for display */ 
      VS_INT cHighIntervalString = 0;  /* Index number into an array of short strings for display */ 
      VS_UINT8 cLoIntervalString = 1;  /* Index number into an array of short strings for display */ 
      VS_UINT8 cNoRFString = 4;
      VS_UINT8 cRadioActive = 1;  /* Adapted from BlueRobin interface */ 
      VS_UINT8 cRadioOff = 0;  /* Adapted from BlueRobin interface */ 
      VS_UINT8 cRadioSearch = 2;  /* Adapted from BlueRobin interface */ 
      VS_UINT8 cSetRoundsString = 3;  /* Index number into an array of short strings for display */ 
    }
  }
  Transitions 
  {
    App.WelcomeScreen -> eButton_M1() / [ClearScreen ()] [DisplayStringConstant (cLoIntervalString)] -> App.SetLowInterval;
    App.SetLowInterval -> eButton_M1() / [ClearScreen ()] [DisplayStringConstant (cHighIntervalString)] -> App.SetHighInterval;
    App.SetLowInterval -> eButton_S1() [LowIntervalTime<180] / [LowIntervalTime = LowIntervalTime+15] -> App.SetLowInterval;
    App.SetLowInterval -> eButton_S2() [LowIntervalTime>15] / [LowIntervalTime = LowIntervalTime - 15] -> App.SetLowInterval;
    App.SetHighInterval -> eButton_S1() [HighIntervalTime<180] / [HighIntervalTime = HighIntervalTime + 15] -> App.SetHighInterval;
    App.SetHighInterval -> eButton_S2() [HighIntervalTime>15] / [HighIntervalTime = HighIntervalTime - 15] -> App.SetHighInterval;
    App.SetHighInterval -> eButton_M1() / [ClearScreen ()] [DisplayStringConstant (cHighHeartRateString)] -> App.SetHighGoalRate;
    App.SetHighGoalRate -> eButton_M1() / [ClearScreen ()] [DisplayStringConstant (cSetRoundsString)] -> App.SetRounds;
    App.SetHighGoalRate -> eButton_S1() [HiGoalHR<225] / [HiGoalHR = HiGoalHR + 1] -> App.SetHighGoalRate;
    App.SetHighGoalRate -> eButton_S2() [HiGoalHR>90] / [HiGoalHR = HiGoalHR - 1] -> App.SetHighGoalRate;
    App.Training -> eRestIntervalExpired() [Rounds==1] / [StartTwoBuzz ()] [ClearScreen ()] -> App.Summary;
    App.Training -> eButton_M2() / ^sTurnRadioOff -> App.WelcomeScreen;
    App.Training -> sLowBattery / ^sTurnRadioOff -> App.WelcomeScreen;
    App.SetRounds -> eButton_M1() !App.LowBattery / [ClearTimeForDisplay ()] ^sTurnRadioOn -> App.WaitToGo;
    App.SetRounds -> eButton_S1() [Rounds<20] / [Rounds = Rounds + 1] -> App.SetRounds;
    App.SetRounds -> eButton_S2() [Rounds>2] / [Rounds = Rounds - 1] -> App.SetRounds;
    App.WaitToGo -> eButton_M2() App.RadioActive / [ClearScreen ()] [StartTwoBuzz ()] -> App.Training;
    App.WaitToGo -> eButton_M2() !App.RadioActive / [DisplayStringConstant (cNoRFString)] -> App.NoStrap;
    App.Summary -> eButton_M2() / ^sTurnRadioOff -> App.WelcomeScreen;
    App.NoStrap -> eButton_M2() !App.LowBattery / [ClearScreen ()] ^sTurnRadioOn -> App.WaitToGo;
    App.MeasureBattery -> e1Hz() / -> App._JunctionState0;
    App.IdleMode -> e1Hz() [SecondsBetweenBattMeas<60] / [SecondsBetweenBattMeas = SecondsBetweenBattMeas + 1] -> App.IdleMode;
    App.IdleMode -> e1Hz() [SecondsBetweenBattMeas == 60] / [SecondsBetweenBattMeas = 0] [voltage = MeasureVoltage()] -> App.MeasureBattery;
    App._JunctionState0 -> [voltage<cBatteryLowTreshold] / [DisplayCriticalBattery ()] -> App.LowBattery;
    App._JunctionState0 -> [(voltage>=cBatteryLowTreshold) ] / -> App.IdleMode;
    App.RadioOff -> sTurnRadioOn / [TimerRadioSearchTimeout (eRadioSearchTimeout, 10)] [RadioStart ()] -> App.RadioSearching;
    App.RadioActive -> sTurnRadioOff / [RadioCloseDown ()] -> App.RadioOff;
    App.RadioActive -> e1Hz() [cRadioOff == RadioGetState()] / ^sTurnRadioOff -> App.RadioActive;
    App.RadioSearching -> sRadioActive / [RadioShowActive ()] -> App.RadioActive;
    App.RadioSearching -> eRadioSearchTimeout() / [RadioCloseDown ()] -> App.RadioOff;
    App.RadioSearching -> e1Hz() [cRadioActive == RadioGetState()] / ^sRadioActive -> App.RadioSearching;
    App.Training.LowInterval -> eRestIntervalExpired() [Rounds>1] / [Rounds = Rounds - 1] [StartOneBuzz ()] [ClearTimeForDisplay ()] [TimerWorkInterval (eWorkIntervalExpired, HighIntervalTime)] -> App.Training.HighInterval;
    App.Training.HighInterval -> eWorkIntervalExpired() / [StartOneBuzz ()] [ClearTimeForDisplay ()] [TimerRestInterval (eRestIntervalExpired, LowIntervalTime)] -> App.Training.LowInterval;
  }
  Region BaseApp
  {
    App._InitialState0 -> / [Rounds = 5] [LowIntervalTime = 30] [HiGoalHR = 160] [HighIntervalTime = 30] [ClearScreen ()] [InitSoftwareTimers ()] -> App.WelcomeScreen;

    SimpleState WelcomeScreen
    {
      Entry / [ClearScreen ()] [DisplayInitialMessage ()];
    }

    SimpleState SetLowInterval
    {
      Entry / [Display8bitNum (LowIntervalTime)];
    }

    SimpleState SetHighInterval
    {
      Entry / [Display8bitNum (HighIntervalTime)];
    }

    SimpleState SetHighGoalRate
    {
      Entry / [Display8bitNum (HiGoalHR)];
    }

    CompositeState Training
    {
      e1Hz() / [IncreaseAndDisplayTime ()] [GetHeartRateBR ()] [DisplayHeartrateBR ()];

      SimpleState LowInterval
      {
      }
      SimpleState HighInterval
      {
      }
      App.Training._InitialState1 -> / [TimerWorkInterval (eWorkIntervalExpired, HighIntervalTime)] -> App.Training.HighInterval;
    }

    SimpleState SetRounds
    {
      Entry / [Display8bitNum (Rounds)];
    }

    SimpleState WaitToGo
    {
    }
    SimpleState Summary
    {
      e1Hz() / [GetHeartRateBR ()] [DisplayHeartrateBR ()];
    }

    SimpleState NoStrap
    {
    }
  }
  Region Battery
  {
    App._InitialState2 -> / [SecondsBetweenBattMeas = 0] -> App.IdleMode;

    SimpleState MeasureBattery
    {
    }
    SimpleState LowBattery
    {
      Entry / ^sLowBattery;
    }

    SimpleState IdleMode
    {
    }
  }
  Region Radio
  {
    SimpleState RadioOff
    {
      Entry / ^sRadioOff;
    }
    App._InitialState3 -> / [RadioInit ()] -> App.RadioOff;

    SimpleState RadioActive
    {
    }
    SimpleState RadioSearching
    {
    }
  }
}


Element lists

Events

EventPathExplanation
e1Hz () Trainer :App This event is generated by a periodic 1 Hz interrupt.
The model uses the event to trigger for example display updates
and fetching of BlueRobin data (i.e heart rate).
eButton_M1 () Trainer :App Event corresponding to the top left button on the clock housing. (Marked '*')
eButton_M2 () Trainer :App Event corresponding to the bottom left button on the clock housing. (Marked '#')
eButton_S1 () Trainer :App Event corresponding to the top
right button on the clock housing. (Marked 'Up Arrow')
eButton_S2 () Trainer :App Event corresponding to the bottom right button on the clock housing. (Marked 'Down Arrow')
eRadioSearchTimeout () Trainer :App Event sent to the model when the radio search timeout triggers.
eRestIntervalExpired () Trainer :App Event to indicate that the resting interval between two high
intensity intervals has expired.

(It is not strictly necessary to have two
different events for the expiry of the low- and high intensity intervals. The model can be somewhat
simplified by utilizing one event for both situations as they are mutually exclusive.)
eWorkIntervalExpired () Trainer :App Event to indicate when the high intensity phase is over for this round.

(It is not strictly necessary to have two
different events for the expiry of the low- and high intensity intervals.
The model can be somewhat
simplified by utilizing one event for both situations as they
are mutually exclusive.)

Action functions

Action functionPathExplanation
extern VS_VOID ClearLINE1 () Trainer :App Function to clear the 7-segment characters on display-line 1.
extern VS_VOID ClearLINE2 () Trainer :App Function to clear the 7-segment characters on display-line 2.
extern VS_VOID ClearScreen () Trainer :App Clears LINE1 and LINE2 7-segment characters.
extern VS_VOID ClearTimeForDisplay () Trainer :App This function just zeroes the variable used to hold an integer denoting
the time in seconds spent in the current rest or training interval.

Note that the variable is defined as a static within the action function implementation file.
extern VS_VOID Display8bitNum (VS_UINT8 num) Trainer :App Display generic 8 bit unsigned number on LINE2.
extern VS_VOID DisplayCriticalBattery () Trainer :App This function turns on the battery symbol in blinking mode
extern VS_VOID DisplayHeartrateBR () Trainer :App This function displays an 8-bit value from an "external" variable declared in the model.
However, the value of the variable is set by the accompanying function GetHeartRateBR()

The reason for this implementation style is that the
heart rate is now available both inside and outside the model and can be used if needed, but the model
is not cluttered with unnecessary assignments and parameter passing to the heart rate display function.
extern VS_VOID DisplayInitialMessage () Trainer :App Displays a welcome string that with some good will can be interpreted as "Interval training"... :-)
extern VS_VOID DisplayStringConstant (VS_UINT8 literalNumber) Trainer :App Function to display one of a set of predefined constant strings. The strings are stored in an array and indexed by the function parameter. Additional 4-letter strings can easily be defined and used.
The string collection can be found in VS_ActionFunctions.c
extern VS_VOID GetHeartRateBR () Trainer :App Query the BlueRobin interface for the latest heart rate measurement.
Assign the value to the "external" variable HeartRateBR. The heart rate value is thus available both inside the model and outside it.
extern VS_VOID IncreaseAndDisplayTime () Trainer :App This function increments and
displays the value of static unsigned 8-bit variable.
The function is called once a second and is used to
display the number of seconds spent in the current interval (rest or activity).
extern VS_VOID InitSoftwareTimers () Trainer :App Call the software timer initialization code in the software timer module. This model uses two software timers.
(See the description of the timer action functions for more details on sdesign choices etc)
extern VS_UINT16 MeasureVoltage () Trainer :App
extern VS_VOID RadioCloseDown () Trainer :App
extern VS_UINT8 RadioGetState () Trainer :App
extern VS_VOID RadioInit () Trainer :App
extern VS_VOID RadioShowActive () Trainer :App
extern VS_VOID RadioStart () Trainer :App
extern VS_VOID StartOneBuzz () Trainer :App Do a short 'buzz' on the buzzer
extern VS_VOID StartTwoBuzz () Trainer :App Do two short consecutive buzzes on the buzzer.
extern VS_VOID TimerRadioSearchTimeout (VS_UINT event, VS_UINT ticks) Trainer :App This timer is started when the radio search is initiated. We use a 10-seconds timeout for the state machine. The underlying radio interface is set by the application to stop searching after 8 seconds.
We are using the generated event to escape the Searching state and go back to the RadioOff state.
This timer must be independent from the two other timers in the example, so we cannot reuse one of them.
extern VS_VOID TimerRestInterval (VS_UINT event, VS_UINT ticks) Trainer :App A timer action function is an easy-to-use abstraction to handle timing intervals. The timer action function is called with two arguments, the delay in 'ticks' and the event to send back to the state machine when the timer expires. The timer action function can be implemented in any way fit for the application. In this application we have chosen to implement the underlying timer functionality with a software timer module.
The TimerRestInterval() function thus initializes and starts a timer from the software timer package. That timer will count up the number of ticks specified and then put the specified event into the event queue.

Note: We have chosen to define one timer action for the rest interval and one for the work interval and use a separate software timer for the each interval.
It would be just as easy to use only one timer action and one softare timer in this example because the two timers are never active at the same time.
It would also be possible to have two timer action functions sharing one software timer.

The software timer ticks are driven by a 1Hz interrupt that calls an update function that also takes care of posting the event in case of time out for a timer.
extern VS_VOID TimerWorkInterval (VS_UINT event, VS_UINT ticks) Trainer :App

External variables

External variablePathExplanation
VS_UINT8 HeartRateBR = 0 Trainer :App This variable is defined by the model and available for the driver code. It is among other things used to store the received heart rate from the BlueRobin stack.

Internal variables

Internal variablePathExplanation
VS_UINT8 HiGoalHR = 0 Trainer :App This variable is used to store the desired goal heart rate for the work intervals.
VS_UINT8 HighIntervalTime = 0 Trainer :App Desired work interval time. The user can change this in steps of +/- 15 seconds
VS_UINT8 LowIntervalTime = 0 Trainer :App Desired rest interval time. The user can change this in steps of +/- 15 seconds.
VS_UINT8 Rounds = 0 Trainer :App Number of desired repetitions of the work/rest cycle.
VS_UINT8 SecondsBetweenBattMeas = 0 Trainer :App
VS_UINT16 voltage = 0 Trainer :App

Signals

SignalPathExplanation
sLowBattery Trainer :App Sent by the battery state machine when entering the LowBattery state. Is used as trigger in the Training state to exit training mode if battery voltage is too low.
sRadioActive Trainer :App This signal is emitted from the radio state machine when radio start is confirmed.
sRadioOff Trainer :App This signal is emitted by the radio state machine when the radio is confirmed to be off.
sTurnRadioOff Trainer :App This signal can be used by any part of the state machine to request the radio service to be turned off.
sTurnRadioOn Trainer :App This signal can be used by any region in the state machine to signal that it wants the radio service to start.

Constants

ConstantPathExplanation
VS_UINT16 cBatteryHighTreshold = 360 Trainer :App
VS_UINT16 cBatteryLowTreshold = 240 Trainer :App
VS_UINT8 cHighHeartRateString = 2 Trainer :App Index number into an array of short strings for display
VS_INT cHighIntervalString = 0 Trainer :App Index number into an array of short strings for display
VS_UINT8 cLoIntervalString = 1 Trainer :App Index number into an array of short strings for display
VS_UINT8 cNoRFString = 4 Trainer :App
VS_UINT8 cRadioActive = 1 Trainer :App Adapted from BlueRobin interface
VS_UINT8 cRadioOff = 0 Trainer :App Adapted from BlueRobin interface
VS_UINT8 cRadioSearch = 2 Trainer :App Adapted from BlueRobin interface
VS_UINT8 cSetRoundsString = 3 Trainer :App Index number into an array of short strings for display

Index

Index entries: A C D E G H I L M N R S T V W

A

C

D

E

G

H

I

L

M

N

R

S

T

V

W