1    /*
     2     * Copyright (c) 2013-2020, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== Clock.xdc ========
    34     *
    35     *
    36     */
    37    
    38    package ti.sysbios.knl;
    39    
    40    import xdc.rov.ViewInfo;
    41    
    42    import xdc.runtime.Assert;
    43    import xdc.runtime.Diags;
    44    import xdc.runtime.Log;
    45    
    46    /*!
    47     *  ======== Clock ========
    48     *  System Clock Manager
    49     *
    50     *  The System Clock Manager is responsible for all timing services in
    51     *  SYS/BIOS.
    52     *  It generates the periodic system tick. The tick period is configurable.
    53     *  The timeout and period for all Clock Instances and timeout values in
    54     *  other SYS/BIOS modules are specified in terms of Clock ticks.
    55     *
    56     *  The Clock Manager supports two tick "modes": a periodic mode with an
    57     *  interrupt on each tick (TickMode_PERIODIC), and a tick suppression
    58     *  mode (TickMode_DYNAMIC), which reduces the number of timer interrupts to
    59     *  the minimum required to support the scheduled timeouts.  For devices that
    60     *  support it (e.g., CC13xx/CC26xx devices), TickMode_DYNAMIC may be the default
    61     *  mode if one is not specified in the application configuration; otherwise,
    62     *  the default mode will be TickMode_PERIODIC.  The following example shows
    63     *  how the tick mode  can be specified in the application configuration:
    64     *
    65     *  @p(code)
    66     *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    67     *
    68     *  // Tell the Clock module to use TickMode_PERIODIC
    69     *  Clock.tickMode = Clock.TickMode_PERIODIC;
    70     *  @p
    71     *
    72     *  Clock objects contain functions that can be scheduled to run after a
    73     *  certain number of Clock ticks.
    74     *  Clock objects are either one-shot or periodic. Instances are started
    75     *  when created or they are started later using the Clock_start() function.
    76     *  Instances can be stopped using the Clock_stop() function. All Clock
    77     *  Instances are executed when they expire in the context of a software
    78     *  interrupt.
    79     *
    80     *  Clock objects are placed in the Clock object service list when
    81     *  created/constructed and remain there until deleted/destructed.
    82     *  To minimize processing overhead, unused or expired Clock objects
    83     *  should be deleted or destructed.
    84     *
    85     *  By default, all Clock functions run in the context of a Swi.
    86     *  That is, the Clock module automatically creates a Swi for
    87     *  its use and runs the Clock functions within that Swi.
    88     *  The priority of the Swi used by Clock can be changed
    89     *  by configuring {@link #swiPriority Clock.swiPriority}.
    90     *
    91     *  If Swis are disabled in an application
    92     *  (ie {@link ti.sysbios.BIOS#swiEnabled BIOS.swiEnabled} = false),
    93     *  then all Clock functions are executed within the context of
    94     *  a Timer Hwi.
    95     *
    96     *  The getTicks() function returns number of clock ticks since startup.
    97     *
    98     *  By default, the Timer module defined by {@link #TimerProxy} is used to
    99     *  statically create a timer instance that provides a periodic 1 ms 
   100     *  tick interrupt.
   101     *
   102     *  If you want to use a custom configured timer for the Clock module's
   103     *  tick source, use the following example configuration as a guide:
   104     *
   105     *  @p(code)
   106     *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
   107     *
   108     *  // Tell the Clock module that YOU are providing the periodic interrupt
   109     *  Clock.tickSource = Clock.TickSource_USER;
   110     *
   111     *  // this example uses the ti.sysbios.timers.dmtimer.Timer module
   112     *  var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
   113     *
   114     *  // Change Timer 3 frequency to 24 Mhz from default if necessary
   115     *  Timer.intFreqs[3] = { hi:0, lo:24000000 };
   116     *
   117     *  // create a dmtimer config parameter object
   118     *  var timerParams = new Timer.Params();
   119     *
   120     *  // make sure you set the period to 1000 us (1ms)
   121     *  timerParams.period = 1000;
   122     *
   123     *  // custom dmtimer config parameters here...
   124     *  timerParams.twer.ovf_wup_ena = 1;
   125     *
   126     *  // Create the timer.
   127     *  // This example uses timer id 3.
   128     *  // Provide your own timer interrupt handler function.
   129     *  Timer.create(3, '&myTimerTick', timerParams);
   130     *  @p
   131     *
   132     *  In your 'C' code, add your timer interrupt handler and have it
   133     *  call Clock_tick(), which will perform all of the Clock module
   134     *  tick duties:
   135     *
   136     *  @p(code)
   137     *  #include <ti/sysbios/knl/Clock.h>
   138     *
   139     *  Void myTimerTick(UArg arg)
   140     *  {
   141     *       Clock_tick();
   142     *       ...
   143     *  }
   144     *  @p
   145     *
   146     *  @a(Note)
   147     *  As Clock functions execute in either a Swi or Hwi context, they
   148     *  are not permitted to call blocking APIs.
   149    
   150     *  Clock requires regular interrupts by an underlying timer peripheral. (If
   151     *  operating with TickSource_USER, Clock requires regular invocation via
   152     *  Clock_tick().)  If the timer interrupt is inadvertently disabled Clock ticks
   153     *  will stop incrementing, Clock functions will not execute, and when queried
   154     *  Clock will report incorrect tick counts, timeouts, and ticks until timeout.
   155     *
   156     *  Clock objects are maintained in a queue, and there may be multiple Clock
   157     *  objects that need to be serviced upon a given timer interrupt.  Depending upon
   158     *  the content of the queue, and the servicing of other objects that have timed
   159     *  out, there will be some corresponding jitter in timing between the timer
   160     *  interrupt and the actual invocation of a Clock object's function.
   161     *
   162     *  If there is a mismatch in the configured Clock tick period and the resolution
   163     *  of the underlying timer peripheral, by convention Clock will generate a timeout
   164     *  early, rather than late.  For example, if the desired Clock tick period is 1
   165     *  millisecond, and the underlying timer is clocked at 32768Hz, the counts
   166     *  corresponding to 1 millisecond would be 32.678.  Since an integer value must
   167     *  be set in the timer peripheral, a truncated value of 32 counts will be used
   168     *  per interrupt, resulting in an actual tick period of 0.977 msec.
   169     *
   170     *  Clock timing services require timely servicing of the timer peripheral
   171     *  interrupt by the CPU, as well as timely execution of the Clock work function
   172     *  (typically executed as a Swi).  For the case where Clock runs and sees that
   173     *  there have been multiple intervening timer interrupts since it was last able to
   174     *  process its queue, it will walk the queue multiple times to 'catch up' and
   175     *  resync the timeouts. If this happens the timing of execution of the missed
   176     *  ticks will be faster than typical.  For example, if Clock finds there have been
   177     *  three intervening timer interrupts since it was last able to run, it will walk
   178     *  its queue three times rapidly to replay the missed ticks, in sequence, once for
   179     *  each intervening delayed tick.  So if there are Clock objects that timeout on
   180     *  each tick increment, they will be invoked in order, but the delay between the
   181     *  invocation of these functions will not be a full Clock tick period; it will be
   182     *  much quicker, as quickly as Clock is able to repeatedly process its queue to
   183     *  resync to real time.
   184     *
   185     *  Timely execution of the Clock work function is especially important for
   186     *  TickMode_DYNAMIC, as the timer peripheral needs to be reprogrammed on each
   187     *  timer peripheral interrupt.  The ability of Clock to keep time sync will vary
   188     *  by the configured Clock tick period, the underlying timer implementation, the
   189     *  peripheral's count width and resolution, and the rate that the timer
   190     *  increments.  In an extreme case, if the delay from the timer raising the
   191     *  interrupt to the execution of the Clock work function exceeds the rollover
   192     *  period of the underlying timer peripheral (e.g. a 16-bit timer running at 32kHz
   193     *  rolling over every 2 seconds), time sync will be lost, the next interrupt may
   194     *  be significantly delayed, and there will be gaps of lost Clock ticks versus
   195     *  real time.  Some general guidelines for TickMode_DYNAMIC to maintain continuous
   196     *  time sync are listed below.  Some implementations may be more tolerant to
   197     *  delays; these are conservative general limits.  If these conditions cannot be
   198     *  met the Clock module should be configured for TickMode_PERIODIC.
   199     *  @p(blist)
   200     *  - Hardware interrupts must not be disabled too long, to exceed a Clock tick
   201     *  period interval.
   202     *  -Non-nestable hardware ISRs must not run longer than the Clock tick period
   203     *  interval.
   204     *  -No application Swi or Hwi should be allowed to run at the same or higher
   205     *  priority as the Clock work function, long enough to exceed the Clock tick
   206     *  period interval.
   207     *  -The total execution time of Clock functions that execute on a given tick
   208     *  interrupt must not exceed the Clock tick period interval.
   209     *  @p
   210     *  @a
   211     *
   212     *  @p(html)
   213     *  <h3> Calling Context </h3>
   214     *  <table border="1" cellpadding="3">
   215     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   216     *    </colgroup>
   217     *
   218     *    <tr><th> Function                </th><th>  Hwi   </th><th>  Swi   </th>
   219     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   220     *    <!--                                                                -->
   221     *    <tr><td> {@link #construct}      </td><td>   N    </td><td>   N    </td>
   222     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   223     *    <tr><td> {@link #create}         </td><td>   N    </td><td>   N    </td>
   224     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   225     *    <tr><td> {@link #delete}         </td><td>   N    </td><td>   N    </td>
   226     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   227     *    <tr><td> {@link #destruct}       </td><td>   N    </td><td>   N    </td>
   228     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   229     *    <tr><td> {@link #getTicks}       </td><td>   Y    </td><td>   Y    </td>
   230     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   231     *    <tr><td> {@link #getTimerHandle} </td><td>   Y    </td><td>   Y    </td>
   232     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   233     *    <tr><td> {@link #Params_init}    </td><td>   Y    </td><td>   Y    </td>
   234     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   235     *    <tr><td> {@link #tick}           </td><td>   Y    </td><td>   Y    </td>
   236     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   237     *    <tr><td> {@link #tickReconfig}   </td><td>   Y    </td><td>   Y    </td>
   238     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   239     *    <tr><td> {@link #tickStart}      </td><td>   Y    </td><td>   Y    </td>
   240     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   241     *    <tr><td> {@link #tickStop}       </td><td>   Y    </td><td>   Y    </td>
   242     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   243     *
   244     *    <tr><td> {@link #getTimeout}     </td><td>   Y    </td><td>   Y    </td>
   245     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   246     *    <tr><td> {@link #isActive}       </td><td>   Y    </td><td>   Y    </td>
   247     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   248     *    <tr><td> {@link #setFunc}        </td><td>   Y    </td><td>   Y    </td>
   249     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   250     *    <tr><td> {@link #setPeriod}      </td><td>   Y    </td><td>   Y    </td>
   251     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   252     *    <tr><td> {@link #setTimeout}     </td><td>   Y    </td><td>   Y    </td>
   253     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   254     *    <tr><td> {@link #start}          </td><td>   Y    </td><td>   Y    </td>
   255     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   256     *    <tr><td> {@link #stop}           </td><td>   Y    </td><td>   Y    </td>
   257     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   258     *    <tr><td colspan="6"> Definitions: <br />
   259     *       <ul>
   260     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   261     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   262     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   263     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   264     *           <ul>
   265     *             <li> In your module startup after this module is started
   266     *    (e.g. Clock_Module_startupDone() returns TRUE). </li>
   267     *             <li> During
   268     *    {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}. </li>
   269     *             <li> During main().</li>
   270     *             <li> During
   271     *    {@link ti.sysbios.BIOS#startupFxns BIOS.startupFxns}.</li>
   272     *           </ul>
   273     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   274     *           <ul>
   275     *             <li> During
   276     *    {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}.</li>
   277     *             <li> In your module startup before this module is started
   278     *    (e.g. Clock_Module_startupDone() returns FALSE).</li>
   279     *           </ul>
   280     *       </ul>
   281     *    </td></tr>
   282     *
   283     *  </table>
   284     *  @p
   285     */
   286    
   287    @DirectCall
   288    /* REQ_TAG(SYSBIOS-520) */
   289    @ModuleStartup
   290    @InstanceInitStatic /* Construct/Destruct CAN becalled at runtime */
   291    @InstanceFinalize   /* generate call to Clock_Instance_finalize on delete */
   292    @Template("./Clock.xdt")
   293    
   294    /* REQ_TAG(SYSBIOS-519) */
   295    module Clock
   296    {
   297        /*!
   298         *  ======== TickSource ========
   299         *  Clock tick source
   300         *
   301         *  @field(TickSource_TIMER) The Clock module automatically configures a
   302         *  a Timer instance (see {@link #TimerProxy}) to drive the Clock tick.
   303         *  The specific timer and its period can be controlled via
   304         *  {@link #timerId} and {@link #tickPeriod}.
   305         *
   306         *  @field(TickSource_USER) The Application is responsible for calling
   307         *  {@link #tick Clock_tick()} periodically. Make sure {@link #tickPeriod
   308         *  Clock.tickPeriod} is set to the period that Clock_tick() is called.
   309         *
   310         *  Like most other module configuration parameters, the Clock.tickPeriod
   311         *  config parameter value is accessible in runtime C code as
   312         *  "Clock_tickPeriod".
   313         *
   314         *  @field(TickSource_NULL) The Clock module is disabled.
   315         *  In this case, it is an error for the application to ever call
   316         *  Clock_tick().
   317         *
   318         *  @see #tickPeriod
   319         *  @see #timerId
   320         */
   321        enum  TickSource {
   322            TickSource_TIMER,   /*! Internally configure a Timer to periodically call Clock_tick() */
   323            TickSource_USER,    /*! Application code calls Clock_tick() */
   324            TickSource_NULL     /*! The Clock module is disabled */
   325        };
   326    
   327        /*!
   328         *  ======== TickMode ========
   329         *  Clock Tick Mode
   330         */
   331        enum  TickMode {
   332            TickMode_PERIODIC,  /*! Timer will interrupt every period */
   333            TickMode_DYNAMIC    /*! Unnecessary timer ticks will be suppressed */
   334        };
   335    
   336        /*!
   337         *  ======== BasicView ========
   338         *  @_nodoc
   339         */
   340        metaonly struct BasicView {
   341            String          label;
   342            UInt32          timeout;
   343            UInt            period;
   344            String          fxn[];
   345            UArg            arg;
   346            Bool            started;        /* Instance running? */
   347            String          tRemaining;     /* Remaining timeout */
   348            Bool            periodic;       /* Periodic? (vs. one-shot) */
   349        }
   350    
   351        /*!
   352         *  ======== ModuleView ========
   353         *  @_nodoc
   354         */
   355        metaonly struct ModuleView {
   356            String          ticks;
   357            String          tickSource;
   358            String          tickMode;
   359            String          timerHandle;
   360            UInt            timerId;
   361            UInt            swiPriority;
   362            UInt32          tickPeriod;
   363            volatile UInt   nSkip;
   364        }
   365    
   366        /*
   367         *  ======== rovViewInfo ========
   368         *  @_nodoc
   369         */
   370        @Facet
   371        metaonly config ViewInfo.Instance rovViewInfo =
   372            ViewInfo.create({
   373                viewMap: [
   374                  ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',  structName: 'BasicView'}],
   375                  ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
   376                ]
   377            });
   378    
   379        /*!
   380         *  ======== FuncPtr ========
   381         * Instance function prototype
   382         */
   383        typedef Void (*FuncPtr)(UArg);
   384    
   385        /*! 
   386         *  ======== TimerProxy ========
   387         *  target/device-specific Timer implementation.
   388         *
   389         *  The Timer module used by the Clock module to
   390         *  create a Timer instance when Clock.tickSource_TIMER is configured.
   391         *
   392         *  By default, a target specific Timer module is internally selected 
   393         *  for this purpose. If the user wishes to use a different Timer module
   394         *  then the following configuration script will serve as an example for
   395         *  achieving that:
   396         *
   397         *  @p(code)
   398         *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
   399         *
   400         *  // Use a dmtimer Timer instance
   401         *  Clock.TimerProxy = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
   402         *  @p
   403         *
   404         */
   405        /* REQ_TAG(SYSBIOS-523) */
   406        proxy TimerProxy inherits ti.sysbios.interfaces.ITimer;
   407    
   408        /*!
   409         *  ======== LW_delayed ========
   410         *  Logged if Clock Swi delayed by >= 1 tick
   411         */
   412        config Log.Event LW_delayed = {
   413            mask: Diags.USER3,
   414            msg: "LW_delayed: delay: %d"
   415        };
   416    
   417        /*!
   418         *  ======== LM_tick ========
   419         *  Logged in every Clock tick interrupt
   420         */
   421        config Log.Event LM_tick = {
   422            mask: Diags.USER1 | Diags.USER2,
   423            msg: "LM_tick: tick: %d"
   424        };
   425    
   426        /*!
   427         *  ======== LM_begin ========
   428         *  Logged just prior to calling each Clock function
   429         */
   430        config Log.Event LM_begin = {
   431            mask: Diags.USER1 | Diags.USER2,
   432            msg: "LM_begin: clk: 0x%x, func: 0x%x"
   433        };
   434    
   435        /*!
   436         *  ======== A_clockDisabled ========
   437         *  Asserted in Clock_create()
   438         */
   439        config Assert.Id A_clockDisabled = {
   440            msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
   441        };
   442    
   443        /*!
   444         *  ======== A_badThreadType ========
   445         *  Asserted in Clock_create and Clock_delete
   446         */
   447        config Assert.Id A_badThreadType = {
   448            msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
   449        };
   450    
   451        /*!
   452         *  @_nodoc
   453         *  !!! Do not delete. Required for ROM compatibility !!!
   454         */
   455        config UInt32 serviceMargin = 0;
   456    
   457        /*!
   458         *  ======== tickSource ========
   459         *  Source of clock ticks
   460         *
   461         *  If this parameter is not set to TickSource_TIMER,
   462         *  {@link #tickStart Clock_tickStart()},
   463         *  {@link #tickStop Clock_tickStop()}, and
   464         *  {@link #tickReconfig Clock_tickReconfig()}, have no effect.
   465         *
   466         *  The default is TickSource_TIMER.
   467         */
   468        config TickSource tickSource = TickSource_TIMER;
   469    
   470        /*!
   471         *  ======== tickMode ========
   472         *  Timer tick mode
   473         *
   474         *  This parameter specifies the tick mode to be used by the underlying
   475         *  Timer.
   476         *
   477         *  With TickMode_PERIODIC the timer will interrupt the CPU at
   478         *  a fixed rate, defined by the tickPeriod.
   479         *
   480         *  With TickMode_DYNAMIC the timer can be dynamically reprogrammed by
   481         *  Clock, to interrupt the CPU when the next tick is actually needed for
   482         *  a scheduled timeout. TickMode_DYNAMIC is not supported on all devices,
   483         *  and may have some application constraints.
   484         */
   485        config TickMode tickMode;
   486    
   487        /*!
   488         *  ======== timerId ========
   489         *  Timer Id used to create a Timer instance
   490         *
   491         *  If {@link #tickSource Clock.tickSource} is set to TickSource_TIMER,
   492         *  the Clock module internally creates a
   493         *  static Timer instance (see {@link #TimerProxy}) that automatically calls
   494         *  Clock_doTick() on a periodic basis (as specified by
   495         *  {@link #tickPeriod tickPeriod} and {@link #periodType periodType}.)
   496         *
   497         *  This configuration parameter allows you to control which timer is
   498         *  used to drive the Clock module.
   499         *
   500         *  The default value is {@link ti.sysbios.hal.Timer#ANY Timer.ANY} (~0)
   501         *  and the maximum timerId possible is family and device specific.
   502         */
   503        config UInt timerId = ~0;
   504    
   505        /*!
   506         *  ======== swiPriority ========
   507         *  The priority of Swi used by Clock to process its instances
   508         *
   509         *  All Clock instances are executed in the context of a single
   510         *  {@link Swi}.  This parameter allows you to control the priority of
   511         *  that Swi.
   512         *
   513         *  The default value of this parameter is Swi.numPriorities - 1; i.e.,
   514         *  the maximum Swi priority.
   515         *
   516         *  @see ti.sysbios.knl.Swi#numPriorities
   517         */
   518        metaonly config UInt swiPriority;
   519    
   520        /*!
   521         *  ======== tickPeriod ========
   522         *  Tick period specified in microseconds
   523         *
   524         *  Default value is family dependent. For example, Linux systems often
   525         *  only support a minimum period of 10000 us and multiples of 10000 us.
   526         *  TI platforms have a default of 1000 us.
   527         *
   528         *  Like most other module configuration parameters, the Clock.tickPeriod
   529         *  config parameter value is accessible in runtime C code as
   530         *  "Clock_tickPeriod".
   531         */
   532        /* REQ_TAG(SYSBIOS-522) */
   533        config UInt32 tickPeriod;
   534    
   535        /*!
   536         *  @_nodoc
   537         *  ======== stopCheckNext ========
   538         *  Boolean to control whether a check is made upon each Clock_stop() call
   539         *  to determine if the Clock object being stopped is due to timeout on the
   540         *  next scheduled tick.  If this feature is enabled, and the timeout
   541         *  coincides with the next scheduled tick, then a special 'trigger' Clock
   542         *  will be started to force a reschedule of the next tick, as soon as
   543         *  possible. This feature is only applicable for Clock.TickMode_DYNAMIC.
   544         *
   545         *  For most use cases it is most efficient to simply stop
   546         *  a Clock object, and then let the next scheduled tick occur naturally.
   547         *  But some low power application use cases (that routinely stop the next
   548         *  expiring Clock object) can benefit by scheduling an immediate tick, to
   549         *  suppress the next scheduled tick.  The default value for most
   550         *  targets is 'false', for cc26xx/cc13xx it is 'true'.  The default is
   551         *  established in Clock.xs, if the application has not explicitly
   552         *  specified a value.
   553         */
   554        metaonly config Bool stopCheckNext;
   555    
   556        /*!
   557         *  ======== getTicks ========
   558         *  Time in Clock ticks
   559         *
   560         *  The value returned will wrap back to zero after it reaches the max
   561         *  value that can be stored in 32 bits.
   562         *
   563         *  @b(returns)     time in clock ticks
   564         */
   565        UInt32 getTicks();
   566    
   567        /*!
   568         *  @_nodoc
   569         *  ======== getTimerHandle ========
   570         *  Get timer Handle
   571         *
   572         *  Used when it is necessary to change family
   573         *  specific options for the timer and its Hwi Object.
   574         *
   575         *  @b(returns)     Timer Handle
   576         */
   577        TimerProxy.Handle getTimerHandle();
   578    
   579        /*!
   580         *  @_nodoc
   581         *  ======== setTicks ========
   582         *  Set the internal Clock tick counter
   583         *
   584         *  Used internally by Power modules. Only applicable for
   585         *  Clock.TickMode_PERIODIC
   586         */
   587        Void setTicks(UInt32 ticks);
   588    
   589        /*!
   590         *  ======== tickStop ========
   591         *  Stop clock for reconfiguration
   592         *
   593         *  This function is used to stop the timer used for generation of
   594         *  clock ticks. It is used along with Clock_tickStart() and
   595         *  Clock_tickReconfig() to allow reconfiguration of timer at runtime.
   596         *
   597         *  Stopping the timer may not be supported for some types of timers, and
   598         *  is not supported for Clock.TickMode_DYNAMIC; in these cases, this
   599         *  this function call will have no effect.
   600         *
   601         *  @a(constraints)
   602         *  This function is non-reentrant and appropriate locks must be used to
   603         *  protect against  re-entrancy.
   604         */
   605        Void tickStop();
   606    
   607        /*!
   608         *  ======== tickReconfig ========
   609         *  Reconfigure clock for new cpu frequency
   610         *
   611         *  This function uses the new cpu frequency to reconfigure the timer used
   612         *  for generation of clock ticks such that tick period is
   613         *  accurate.  This function is used along with Clock_tickStop() and
   614         *  Clock_tickStart() to allow reconfiguration of timer at runtime.
   615         *
   616         *  Reconfiguration may not be supported for some types of timers, and is
   617         *  not supported for Clock.TickMode_DYNAMIC; in these cases, this
   618         *  this function call will have no effect, and will return false.
   619         *
   620         *  When calling Clock_tickReconfig outside of main(), you must also call
   621         *  Clock_tickStop and Clock_tickStart to stop and restart the timer.
   622         *  Use the following call sequence:
   623         *
   624         *  @p(code)
   625         *  // disable interrupts if an interrupt could lead to
   626         *  // another call to Clock_tickReconfig or if interrupt
   627         *  // processing relies on having a running timer
   628         *  Hwi_disable() or Swi_disable();
   629         *  BIOS_setCpuFreq(&freq);
   630         *  Clock_tickStop();
   631         *  Clock_tickReconfig();
   632         *  Clock_tickStart();
   633         *  Hwi_restore() or Swi_enable()
   634         *  @p
   635         *
   636         *  When calling Clock_tickReconfig from main(), the timer has not yet
   637         *  been started because the timer is started as part of BIOS_start().
   638         *  As a result, you can use the following simplified call sequence
   639         *  in main():
   640         *
   641         *  @p(code)
   642         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   643         *  Clock_tickReconfig(Void);
   644         *  @p
   645         *
   646         *  The return value is false if the timer cannot support the new
   647         *  frequency
   648         *
   649         *  @b(returns)     true if successful
   650         *
   651         *  @a(constraints)
   652         *  This function is non-reentrant and appropriate locks must be used to
   653         *  protect against  re-entrancy.
   654         */
   655        Bool tickReconfig();
   656    
   657        /*!
   658         *  ======== tickStart ========
   659         *  Start clock after reconfiguration
   660         *
   661         *  This function starts the timer used for generation of clock ticks
   662         *  It is used along with Clock_tickStop() and Clock_tickReconfig() to
   663         *  allow reconfiguration of timer at runtime. The new timer configuration
   664         *  reflects changes caused by a call to reconfig().
   665         *
   666         *  Reconfiguration and restart of a timer may not be supported for some
   667         *  types of timers, and is not supported for Clock.TickMode_DYNAMIC; in
   668         *  these cases, this function call will have no effect.
   669         *
   670         *  @a(constraints)
   671         *  This function is non-reentrant and appropriate locks must be used to
   672         *  protect against  re-entrancy.
   673         */
   674        Void tickStart();
   675    
   676        /*!
   677         *  ======== tick ========
   678         *  Advance Clock time by one tick
   679         *
   680         *  After incrementing a global tick counter, this function posts a Swi
   681         *  that processes the clock instances.
   682         *
   683         *  This function is automatically called by a timer ISR when
   684         *  {@link #tickSource} is set to {@link #TickSource_TIMER}.
   685         *
   686         *  When {@link #tickSource} is set to
   687         *  {@link #TickSource_USER}, Clock_tick() must be called by the
   688         *  application.  Usually, this is done within a user defined {@link ti.sysbios.hal.Hwi Hwi},
   689         *  {@link Swi}, or {@link Task}.
   690         *
   691         *  Note that this function is not re-entrant.  The application is
   692         *  responsible for ensuring that invocations of this function are
   693         *  serialized: either only one thread in the system ever calls this
   694         *  function or all calls are "wrapped" by an appropriate mutex.
   695         *
   696         *  @see #tickSource
   697         */
   698        Void tick();
   699    
   700        /*!
   701         *  @_nodoc
   702         *  ======== workFunc ========
   703         *  Clock Q service routine
   704         *
   705         *  @param(arg0)    Unused. required to match Swi.FuncPtr
   706         *  @param(arg1)    Unused. required to match Swi.FuncPtr
   707         */
   708        /* REQ_TAG(SYSBIOS-525) */
   709        Void workFunc(UArg arg0, UArg arg1);
   710    
   711        /*!
   712         *  @_nodoc
   713         *  ======== workFuncDynamic ========
   714         *  Clock Q service routine for TickMode_DYNAMIC
   715         *
   716         *  @param(arg0)    Unused. required to match Swi.FuncPtr
   717         *  @param(arg1)    Unused. required to match Swi.FuncPtr
   718         */
   719        Void workFuncDynamic(UArg arg0, UArg arg1);
   720    
   721        /*!
   722         *  @_nodoc
   723         *  ======= logTick ========
   724         *  Log the LD_tick from within Clock module scope
   725         */
   726        Void logTick();
   727    
   728        /*!
   729         *  @_nodoc
   730         *  ======== getCompletedTicks ========
   731         *  Get the number of Clock ticks that have completed
   732         *
   733         *  Returns the number of ticks completed, to the point where
   734         *  the underlying Timer interrupt has been serviced.
   735         *
   736         *  Used by some TimestampProviders
   737         *
   738         *  @b(returns)     time in clock ticks
   739         */
   740        UInt32 getCompletedTicks();
   741    
   742        /*!
   743         *  @_nodoc
   744         *  ======== getTickPeriod ========
   745         *  Get the Clock tick period in timer counts
   746         *
   747         *  The period is in units returned by the underlying Timer.
   748         *
   749         *  Used by some TimestampProviders
   750         *
   751         *  @b(returns)     period in timer counts
   752         */
   753        UInt32 getTickPeriod();
   754    
   755        /*!
   756         *  @_nodoc
   757         *  ======== getTicksUntilInterrupt ========
   758         *  Get the number of Clock tick periods expected to expire between now
   759         *  and the next interrupt from the timer peripheral
   760         *
   761         *  Used internally by Power modules.
   762         *
   763         *  @b(returns)     count in ticks
   764         */
   765        UInt32 getTicksUntilInterrupt();
   766    
   767        /*!
   768         *  @_nodoc
   769         *  ======== getTicksUntilTimeout ========
   770         *  Get the number of Clock tick periods between now and the next
   771         *  active Clock object timeout.
   772         *
   773         *  Used internally by Power modules.
   774         *
   775         *  @a(constraints)
   776         *  Must be called with interrupts disabled.  Only applicable for
   777         *  Clock.TickSource_TIMER.
   778         *
   779         *  @b(returns)     count in ticks
   780         */
   781        UInt32 getTicksUntilTimeout();
   782    
   783        /*!
   784         *  @_nodoc
   785         *  ======= walkQueueDynamic ========
   786         *  Walk Clock's work queue for TickMode_DYNAMIC
   787         */
   788        UInt32 walkQueueDynamic(Bool service, UInt32 tick);
   789    
   790        /*!
   791         *  @_nodoc
   792         *  ======= walkQueuePeriodic ========
   793         *  Walk Clock's work queue for TickMode_PERIODIC
   794         */
   795        UInt32 walkQueuePeriodic();
   796    
   797        /*!
   798         *  @_nodoc
   799         *  ======= scheduleNextTick ========
   800         *  Reprogram Clock's Timer for earliest required tick
   801         */
   802        Void scheduleNextTick(UInt32 deltaTicks, UInt32 absTick);
   803    
   804    instance:
   805    
   806        /*!
   807         *  ======== create ========
   808         *  Creates a Clock Instance
   809         *
   810         *  The first argument is the function that gets called when the timeout
   811         *  expires.
   812         *
   813         *  The 'timeout' argument is used to specify the startup timeout for
   814         *  both one-shot and periodic Clock instances (in Clock ticks).  This
   815         *  timeout is applied when the Clock instance is started.  For periodic
   816         *  instances, the configured Clock function will be called initially
   817         *  after an interval equal to the timeout, and will be subsequently
   818         *  called at the rate specified by the {@link #period} parameter.  For
   819         *  one-shot instances (where the {@link #period} parameter is 0), once
   820         *  the Clock instance is started (with {@link #start Clock_start()} or
   821         *  automatically if {@link #startFlag} is true) the configured Clock
   822         *  function will be called once after an interval equal to the timeout.
   823         *
   824         *  When instances are created they are placed upon a linked list managed
   825         *  by the Clock module.  For this reason, instances cannot be created
   826         *  from either Hwi or Swi context.
   827         *
   828         *  By default, all Clock functions run in the context of a Swi.
   829         *  That is, the Clock module automatically creates a Swi for
   830         *  its use and runs the Clock functions within that Swi. 
   831         *  The priority of the Swi used by Clock can be changed
   832         *  by configuring {@link #swiPriority Clock.swiPriority}.
   833         *  
   834         *  If Swis are disabled in an application
   835         *  (ie {@link ti.sysbios.BIOS#swiEnabled BIOS.swiEnabled} = false),
   836         *  then all Clock functions are executed within the context of
   837         *  a Timer Hwi. 
   838         *  
   839         *  @a(constraint)
   840         *  @p(blist)
   841         *  As Clock functions execute in either a Swi or Hwi context, they
   842         *  are not permitted to call blocking APIs.
   843         *  @p
   844         *  @a
   845         *
   846         *  @param(clockFxn)  Function that runs upon timeout
   847         *  @param(timeout)   One-shot timeout or initial start delay (in clock
   848         *                    ticks)
   849         */
   850        create(FuncPtr clockFxn, UInt timeout);
   851    
   852        /* REQ_TAG(SYSBIOS-521) */
   853    
   854        /*!
   855         *  ======== startFlag ========
   856         *  Start immediately after instance is created
   857         *
   858         *  When this flag is set to false, the user will have to call
   859         *  Clock_start() to start the instance.
   860         *
   861         *  When set to true, both statically created Clock objects and Clock
   862         *  objects created in main() are started at the end of main() when the
   863         *  user calls BIOS_start(). Dynamically created Clock objects created
   864         *  after main() (ie within a task) will be started immediately.
   865         *
   866         *  The default setting for this parameter is false.
   867         *
   868         *  The configured Clock function will be called initially after an
   869         *  interval equal to the 'timeout' argument for both one-shot and
   870         *  periodic Clock objects.
   871         *
   872         *  Periodic Clock objects will subsequently be called at the rate
   873         *  specified by the {@link #period} parameter.
   874         *
   875         */
   876        config Bool startFlag = false;
   877    
   878        /*!
   879         *  ======== period ========
   880         *  Period of this instance (in clock ticks)
   881         *
   882         *  This parameter is used to set the subsequent timeout interval (in
   883         *  Clock ticks) for periodic instances.
   884         *
   885         *  The default value of this parameter is 0, which indicates this is
   886         *  a one-shot Clock object.
   887         *
   888         *  A non zero value for this parameter specifies that the Clock
   889         *  object is to be called periodically, and also specifies the
   890         *  rate (in Clock ticks) that the Clock function will be called
   891         *  AFTER the initial 'timeout' argument period.
   892         *
   893         *  For one-shot Clock instances, this parameter must be set to zero.
   894         */
   895        config UInt32 period = 0;
   896    
   897        /*!
   898         *  ======== arg ========
   899         *  Uninterpreted argument passed to instance function
   900         *
   901         *  The default is null.
   902         */
   903        config UArg arg = null;
   904    
   905        /*!
   906         *  @_nodoc
   907         *  ======== addI ========
   908         *  Lightweight One-Shot Clock create for internal SYS/BIOS timeout APIs
   909         *  Does NOT start the timeout (ie requires Clock_startI() to be called)
   910         *  Does NOT assume Hwis are disabled
   911         */
   912        Void addI(FuncPtr clockFxn, UInt32 timeout, UArg arg);
   913    
   914        /*!
   915         *  @_nodoc
   916         *  ======== initI ========
   917         *  Lightweight One-Shot Clock create for internal SYS/BIOS timeout APIs
   918         *  Does NOT start the timeout (ie requires Clock_startI() to be called)
   919         *  Does NOT assume Hwis are disabled
   920         *  Does NOT add Clock object to Clock Q.
   921         */
   922        Void initI(FuncPtr clockFxn, UInt32 timeout, UArg arg);
   923    
   924        /*!
   925         *  @_nodoc
   926         *  ======== enqueueI ========
   927         *  Add Clock object to Clock Q.
   928         *  Assumes Hwis are disabled
   929         */
   930        Void enqueueI();
   931    
   932        /*!
   933         *  @_nodoc
   934         *  ======== removeI ========
   935         *  Lightweight Clock delete for internal SYS/BIOS timeout APIs
   936         *  Assumes Hwis are disabled
   937         */
   938        Void removeI();
   939    
   940        /*!
   941         *  ======== start ========
   942         *  Start instance
   943         *
   944         *  The {@link #timeout} and {@link #period} values set during create()
   945         *  or by calling Clock_setTimeout() and Clock_setPeriod() are used and
   946         *  the expiry is recomputed.
   947         *  Note that for periodic instances, the first expiry is
   948         *  computed using the timeout specified. All subsequent expiries use the
   949         *  period value.
   950         *
   951         *  @a(constraints)
   952         *  The timeout of an instance cannot be zero.
   953         *
   954         *  @a(constraints)
   955         *  When using a very fast Clock tick period it may not always be possible
   956         *  to start a Clock object with maximum timeout (0xFFFFFFFF).  This limit
   957         *  applies when Clock_start() is called while Clock is in-process of
   958         *  servicing its timeout queue (called by another ISR, by a higher-priority
   959         *  Swi, or within a Clock function). In this situation the timeout of the
   960         *  newly-started object may occur in the near future rather than in the
   961         *  far future. For one-shot objects there will be a single early timeout;
   962         *  for periodic objects there will be an early timeout, but the next
   963         *  timeout will occur correctly offset from the first timeout. This
   964         *  condition is due to a Clock tick count wrap, and only occurs when there
   965         *  is a very fast Clock tick period such that there are virtual Clock tick
   966         *  period increments between the last timer interrupt to the invocation of
   967         *  Clock_start(). For example, if the Clock tick period is 10 usec, and if
   968         *  the Clock tick count is 0x10000005 when the interrupt occurs, and if
   969         *  there are 3 intervening tick periods (30 usec) before the call to
   970         *  Clock_start(), then the future timeout will be computed as
   971         *  0x10000005 + 3 + 0xFFFFFFFF = 0x10000007, only 2 ticks in the future.
   972         *  In this case, the maximum timeout should be limited to 0xFFFFFFFD to
   973         *  achieve the maximum delay since the last timer interrupt.
   974         */
   975        Void start();
   976    
   977        /*!
   978         *  @_nodoc
   979         *  ======== startI ========
   980         *  Internal start function which assumes Hwis disabled
   981         */
   982        Void startI();
   983    
   984        /*!
   985         *  ======== stop ========
   986         *  Stop instance
   987         */
   988        Void stop();
   989    
   990        /*!
   991         *  ======== setPeriod ========
   992         *  Set periodic interval
   993         *
   994         *  @param(period)          periodic interval in Clock ticks
   995         *
   996         *  @a(constraints)
   997         *  Cannot change period of instance that has been started.
   998         */
   999        Void setPeriod(UInt32 period);
  1000    
  1001        /*!
  1002         *  ======== setTimeout ========
  1003         *  Set the initial timeout
  1004         *
  1005         *  @param(timeout)         initial timeout in Clock ticks
  1006         *
  1007         *  @a(constraints)
  1008         *  Cannot change the initial timeout of instance that has been started.
  1009         */
  1010        Void setTimeout(UInt32 timeout);
  1011    
  1012        /*!
  1013         *  ======== setFunc ========
  1014         *  Overwrite Clock function and arg
  1015         *
  1016         *  Replaces a Clock object's clockFxn function originally
  1017         *  provided in {@link #create}.
  1018         *
  1019         *  @param(clockFxn)        function of type FuncPtr
  1020         *  @param(arg)             argument to clockFxn
  1021         *
  1022         *  @a(constraints)
  1023         *  Cannot change function and arg of Clock object that has been started.
  1024         */
  1025        Void setFunc(FuncPtr fxn, UArg arg);
  1026    
  1027        /*!
  1028         *  ======== getPeriod ========
  1029         *  Get period of instance
  1030         *
  1031         *  Returns the period of an instance.
  1032         *
  1033         *  @b(returns)             returns periodic interval in Clock ticks
  1034         */
  1035        UInt32 getPeriod();
  1036    
  1037        /*!
  1038         *  ======== getTimeout ========
  1039         *  Get timeout of instance
  1040         *
  1041         *  Returns the remaining time if the instance is active; if the instance
  1042         *  is not active, returns zero.
  1043         *
  1044         *  @b(returns)             returns timeout in clock ticks
  1045         */
  1046        UInt32 getTimeout();
  1047    
  1048        /*!
  1049         *  ======== isActive ========
  1050         *  Determine if Clock object is currently active (ie running)
  1051         *
  1052         *  Returns TRUE if Clock object is currently active
  1053         *
  1054         *  @b(returns)             returns active state
  1055         */
  1056        Bool isActive();
  1057    
  1058    internal:
  1059    
  1060        /*
  1061         * ======== timerSupportsDynamic ========
  1062         * used in Clock.xml to enable/disable tickMode setting
  1063         */
  1064        metaonly config Bool timerSupportsDynamic = false;
  1065    
  1066        /*
  1067         *  ======== doTickFunc =======
  1068         *  access doTick through a func ptr so that
  1069         *  ROM'd BIOS code doesn't reference a generated function.
  1070         */
  1071        config Void (*doTickFunc)(UArg);
  1072    
  1073        /*!
  1074         *  ======== doTick ========
  1075         *  Function called by the timer interrupt handler
  1076         *
  1077         *  @param(arg)     Unused. Required to match signature of Hwi.FuncPtr
  1078         */
  1079        /* REQ_TAG(SYSBIOS-531) */
  1080        Void doTick(UArg arg);
  1081    
  1082        /*
  1083         *  ======== triggerClock ========
  1084         *  Special Clock object created when Clock.stopCheckNext is 'true'.
  1085         */
  1086        config Clock.Handle triggerClock;
  1087    
  1088        /*
  1089         *  ======== triggerFunc ========
  1090         *  Empty function used by Clock.triggerClock
  1091         */
  1092        Void triggerFunc(UArg arg);
  1093    
  1094        /*
  1095         *  ======== Instance_State ========
  1096         */
  1097        struct Instance_State {
  1098            Queue.Elem      elem;           // required for clock queue
  1099            UInt32          timeout;        // in clock ticks
  1100            UInt32          currTimeout;    // working timeout
  1101            UInt32          period;         // periodic instance if > 0
  1102            volatile Bool   active;         // active/idle flag
  1103            FuncPtr         fxn;            // instance function
  1104            UArg            arg;            // function arg
  1105    
  1106            /*
  1107             *  For a periodic clock, this is initially set to timeout when
  1108             *  the clock is started.  Once timeout expires, it will be set
  1109             *  to the period.  For a one-shot clock, this will always be
  1110             *  timeout.  This is used by Clock_getTimeout() to determine
  1111             *  the remaining time until the clock is posted.
  1112             */
  1113            UInt32          timeoutTicks;
  1114        };
  1115    
  1116        /*
  1117         *  ======== Module_State ========
  1118         */
  1119        struct Module_State {
  1120            volatile UInt32     ticks;          // last tick serviced
  1121            UInt                swiCount;       // num of Swi posts before Swi runs
  1122            TimerProxy.Handle   timer;          // timer used
  1123                                                // points to generated Clock_doTick()
  1124            Queue.Object        clockQ;         // clock que
  1125            Swi.Handle          swi;            // clock swi
  1126            volatile UInt       numTickSkip;    // number of ticks being suppressed
  1127            UInt32              nextScheduledTick;
  1128            UInt32              maxSkippable;   // timer dependent (in tickPeriods)
  1129            Bool                inWorkFunc;     // true if in Clock Swi servicing Q
  1130            volatile Bool       startDuringWorkFunc; // Clock_start during workFunc?
  1131            Bool                ticking;        // set true during first Clock tick
  1132        };
  1133    }