1    /* 
     2     * Copyright (c) 2012, 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    import ti.sysbios.hal.Timer;
    47    
    48    /*!
    49     *  ======== Clock ========
    50     *  System Clock Manager
    51     *
    52     *  The System Clock Manager is responsible for all timing services in 
    53     *  SYS/BIOS.
    54     *  It generates the periodic system tick. The tick period is configurable.
    55     *  The timeout and period for all Clock Instances and timeout values in 
    56     *  other SYS/BIOS modules are specified in terms of Clock ticks.
    57     *
    58     *  The Clock Manager supports two tick "modes": a periodic mode with an 
    59     *  interrupt on each tick (TickMode_PERIODIC), and a tick suppression 
    60     *  mode (TickMode_DYNAMIC), which reduces the number of timer interrupts to 
    61     *  the minimum required to support the scheduled timeouts.  For devices that 
    62     *  support it (e.g., MSP430 devices), TickMode_DYNAMIC will be the default 
    63     *  mode if one is not specified in the application configuration; otherwise, 
    64     *  the default mode will be TickMode_PERIODIC.  The following example shows 
    65     *  how the tick mode  can be specified in the application configuration:
    66     *
    67     *  @p(code)
    68     *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    69     *
    70     *  // Tell the Clock module to use TickMode_PERIODIC
    71     *  Clock.tickMode = Clock.TickMode_PERIODIC;
    72     *  @p
    73     *
    74     *  Clock Instances are functions that can be scheduled to run after a 
    75     *  certain number of Clock ticks.
    76     *  Clock instances are either one-shot or periodic. Instances are started 
    77     *  when created or they are started later using the Clock_start()function. 
    78     *  Instances can be stopped using the Clock_stop() function. All Clock 
    79     *  Instances are executed when they expire in the context of a software 
    80     *  interrupt.
    81     *
    82     *  Clock objects are placed in the Clock object service list when 
    83     *  created/constructed and remain there until deleted/destructed.
    84     *  To minimize processing overhead, unused or expired Clock objects 
    85     *  should be deleted or destructed.
    86     *
    87     *  The getTicks() function returns number of clock ticks since startup.
    88     *
    89     *  By default, the Clock module statically configures a 
    90     *  {@link ti.sysbios.hal.Timer}
    91     *  timer instance to provide the periodic 1 ms tick interrupt. If you
    92     *  want to use a custom configured timer for the Clock module's tick source,
    93     *  use the following example configuration as a guide:
    94     *
    95     *  @p(code)
    96     *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    97     *
    98     *  // Tell the Clock module that YOU are providing the periodic interrupt
    99     *  Clock.tickSource = Clock.TickSource_USER;
   100     *
   101     *  // this example uses the ti.sysbios.timers.dmtimer.Timer module
   102     *  var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
   103     *
   104     *  // create a dmtimer config parameter object
   105     *  var timerParams = new Timer.Params();
   106     *
   107     *  // make sure you set the period to 1000 us (1ms)
   108     *  timerParams.period = 1000;
   109     *
   110     *  // custom dmtimer config parameters here...
   111     *  timerParams.twer.ovf_wup_ena = 1;
   112     *
   113     *  // Create the timer.
   114     *  // This example uses timer id 3.
   115     *  // The timer interrupt handler must be set to 'Clock.tick'. 
   116     *  Timer.create(3, Clock.tick, timerParams);
   117     *  @p
   118     *
   119     *  @p(html)
   120     *  <h3> Calling Context </h3>
   121     *  <table border="1" cellpadding="3">
   122     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   123     *    </colgroup>
   124     *
   125     *    <tr><th> Function                </th><th>  Hwi   </th><th>  Swi   </th>
   126     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   127     *    <!--                                                                -->
   128     *    <tr><td> {@link #construct}      </td><td>   N    </td><td>   N    </td>
   129     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   130     *    <tr><td> {@link #create}         </td><td>   N    </td><td>   N    </td>
   131     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   132     *    <tr><td> {@link #delete}         </td><td>   N    </td><td>   N    </td>
   133     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   134     *    <tr><td> {@link #destruct}       </td><td>   N    </td><td>   N    </td>
   135     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   136     *    <tr><td> {@link #getTicks}       </td><td>   Y    </td><td>   Y    </td>
   137     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   138     *    <tr><td> {@link #getTimeout}     </td><td>   Y    </td><td>   Y    </td>
   139     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   140     *    <tr><td> {@link #getTimerHandle} </td><td>   Y    </td><td>   Y    </td>
   141     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   142     *    <tr><td> {@link #Params_init}    </td><td>   Y    </td><td>   Y    </td>
   143     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   144     *    <tr><td> {@link #setFunc}        </td><td>   Y    </td><td>   Y    </td>
   145     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   146     *    <tr><td> {@link #setPeriod}      </td><td>   Y    </td><td>   Y    </td>
   147     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   148     *    <tr><td> {@link #setTimeout}     </td><td>   Y    </td><td>   Y    </td>
   149     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   150     *    <tr><td> {@link #start}          </td><td>   Y    </td><td>   Y    </td>
   151     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   152     *    <tr><td> {@link #stop}           </td><td>   Y    </td><td>   Y    </td>
   153     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   154     *    <tr><td> {@link #tick}           </td><td>   Y    </td><td>   Y    </td>
   155     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   156     *    <tr><td> {@link #tickReconfig}   </td><td>   Y    </td><td>   Y    </td>
   157     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   158     *    <tr><td> {@link #tickStart}      </td><td>   Y    </td><td>   Y    </td>
   159     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   160     *    <tr><td> {@link #tickStop}       </td><td>   Y    </td><td>   Y    </td>
   161     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   162     *    <tr><td colspan="6"> Definitions: <br />
   163     *       <ul>
   164     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   165     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   166     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   167     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   168     *           <ul>
   169     *             <li> In your module startup after this module is started 
   170     *    (e.g. Clock_Module_startupDone() returns TRUE). </li>
   171     *             <li> During 
   172     *    {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}. </li>
   173     *             <li> During main().</li>
   174     *             <li> During 
   175     *    {@link ti.sysbios.BIOS#startupFxns BIOS.startupFxns}.</li>
   176     *           </ul>
   177     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   178     *           <ul>
   179     *             <li> During 
   180     *    {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}.</li>
   181     *             <li> In your module startup before this module is started 
   182     *    (e.g. Clock_Module_startupDone() returns FALSE).</li>
   183     *           </ul>
   184     *       </ul>
   185     *    </td></tr>
   186     *
   187     *  </table>
   188     *  @p
   189     */
   190    
   191    @ModuleStartup
   192    @InstanceInitStatic /* Construct/Destruct CAN becalled at runtime */
   193    @InstanceFinalize   /* generate call to Clock_Instance_finalize on delete */
   194    @Template("./Clock.xdt")
   195    
   196    module Clock
   197    {
   198        /*! 
   199         *  ======== TickSource ========
   200         *  Clock tick source
   201         *
   202         *  @field(TickSource_TIMER) {@link #tick Clock_tick()} is called
   203         *  automatically from within a {@link ti.sysbios.hal.Timer} ISR.  The
   204         *  specific timer and its period can be controlled via {@link #timerId}
   205         *  and {@link tickPeriod}.
   206         *
   207         *  @field(TickSource_USER) {@link #tick Clock_tick()} must be explicitly
   208         *  called by the user's application.
   209         *
   210         *  @field(TickSource_NULL)  {@link #tick Clock_tick()} is never called.
   211         *  In this case, it is an error for the application to ever call
   212         *  Clock_tick().
   213         *
   214         *  @see #tickPeriod
   215         *  @see #timerId
   216         */
   217        enum  TickSource {
   218            TickSource_TIMER,   /*! Use Timer to automatically call Clock_tick() */
   219            TickSource_USER,    /*! Application explicitly calls Clock_tick() */
   220            TickSource_NULL     /*! Clock_tick() is never called */
   221        };
   222    
   223        /*!
   224         *  ======== TickMode ========
   225         *  Clock Tick Mode
   226         */
   227        enum  TickMode {
   228            TickMode_PERIODIC,  /*! Timer will interrupt every period */
   229            TickMode_DYNAMIC    /*! Unnecessary timer ticks can be suppressed */
   230        };
   231    
   232        /*!
   233         *  ======== BasicView ========
   234         *  @_nodoc
   235         */
   236        metaonly struct BasicView {
   237            String          label;
   238            UInt32          timeout;
   239            UInt            period;
   240            String          fxn[];
   241            UArg            arg;
   242            Bool            started;        /* Instance running? */
   243            String          tRemaining;     /* Remaining timeout */
   244            Bool            periodic;       /* Periodic? (vs. one-shot) */
   245        }
   246        
   247        /*!
   248         *  ======== ModuleView ========
   249         *  @_nodoc
   250         */
   251        metaonly struct ModuleView {
   252            String          ticks;
   253            String          tickSource;
   254            String          tickMode;
   255            String          timerHandle;
   256            UInt            timerId;
   257            UInt            swiPriority;
   258            UInt32          tickPeriod;
   259            volatile UInt   nSkip;
   260        }
   261    
   262        /*
   263         *  ======== rovViewInfo ========
   264         *  @_nodoc
   265         */
   266        @Facet
   267        metaonly config ViewInfo.Instance rovViewInfo = 
   268            ViewInfo.create({
   269                viewMap: [
   270                  ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',  structName: 'BasicView'}],
   271                  ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
   272                ]
   273            });
   274            
   275        /*!
   276         *  ======== FuncPtr ========
   277         * Instance function prototype
   278         */
   279        typedef Void (*FuncPtr)(UArg);
   280    
   281        /*!
   282         *  ======== LW_delayed ========
   283         *  Logged if Clock Swi delayed by >= 1 tick
   284         */
   285        config Log.Event LW_delayed = {
   286            mask: Diags.USER3,
   287            msg: "LW_delayed: delay: %d"
   288        };
   289    
   290        /*!
   291         *  ======== LM_tick ========
   292         *  Logged in every Clock tick interrupt
   293         */
   294        config Log.Event LM_tick = {
   295            mask: Diags.USER1 | Diags.USER2,
   296            msg: "LM_tick: tick: %d"
   297        };
   298    
   299        /*!
   300         *  ======== LM_begin ========
   301         *  Logged just prior to calling each Clock function
   302         */
   303        config Log.Event LM_begin = {
   304            mask: Diags.USER1 | Diags.USER2,
   305            msg: "LM_begin: clk: 0x%x, func: 0x%x"
   306        };
   307    
   308        /*!
   309         *  ======== A_clockDisabled ========
   310         *  Asserted in Clock_create()
   311         */
   312        config Assert.Id A_clockDisabled = {
   313            msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
   314        };
   315    
   316        /*!
   317         *  ======== A_badThreadType ========
   318         *  Asserted in Clock_create and Clock_delete
   319         */
   320        config Assert.Id A_badThreadType = {
   321            msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
   322        };
   323    
   324        /*!
   325         *  ======== tickSource ========
   326         *  Source of clock ticks
   327         *
   328         *  If this parameter is not set to TickSource_TIMER,
   329         *  {@link #tickStart Clock_tickStart()},
   330         *  {@link #tickStop Clock_tickStop()}, and
   331         *  {@link #tickReconfig Clock_tickReconfig()}, have no effect.
   332         *
   333         *  The default is TickSource_TIMER.
   334         */
   335        config TickSource tickSource = TickSource_TIMER;
   336    
   337        /*!
   338         *  ======== tickMode ========
   339         *  Timer tick mode
   340         *
   341         *  This parameter specifies the tick mode to be used by the underlying
   342         *  Timer.  With TickMode_PERIODIC the timer will interrupt the CPU at
   343         *  a fixed rate, defined by the tickPeriod.  With TickMode_DYNAMIC the
   344         *  timer can be dynamically reprogrammed by Clock, to interrupt the CPU
   345         *  when the next tick is actually needed for a scheduled timeout.
   346         */
   347        config TickMode tickMode;
   348    
   349        /*!
   350         *  ======== timerId ========
   351         *  Timer Id used to create a Timer instance
   352         *
   353         *  If {@link #tickSource Clock.tickSource} is set to TickSource_TIMER,
   354         *  the Clock module automatically  creates a
   355         *  {@link ti.sysbios.hal.Timer#create instance} that automatically calls
   356         *  Clock_doTick() on a periodic basis (as specified by
   357         *  {@link #tickPeriod tickPeriod} and {@link #periodType periodType}.)
   358         *
   359         *  This configuration parameter allows you to control which timer is
   360         *  used to drive the Clock module.
   361         *
   362         *  The default value is {@link ti.sysbios.hal.Timer#ANY Timer.ANY} (~0)
   363         *  and the maximum timerId possible is family and device specific.
   364         *
   365         *  @see ti.sysbios.hal.Timer
   366         */
   367        config UInt timerId = ~0;
   368    
   369        /*!
   370         *  ======== swiPriority ========
   371         *  The priority of Swi used by Clock to process its instances
   372         *
   373         *  All Clock instances are executed in the context of a single
   374         *  {@link Swi}.  This parameter allows you to control the priority of
   375         *  that Swi.
   376         *
   377         *  The default value of this parameter is Swi.numPriorities - 1; i.e.,
   378         *  the maximum Swi priority.
   379         *
   380         *  @see ti.sysbios.knl.Swi#numPriorities
   381         */
   382        metaonly config UInt swiPriority;
   383    
   384        /*!
   385         *  ======== tickPeriod ========
   386         *  Tick period specified in microseconds
   387         *  
   388         *  Default value is family dependent. For example, Linux systems often
   389         *  only support a minimum period of 10000 us and multiples of 10000 us.
   390         *  TI platforms have a default of 1000 us.
   391         */
   392        config UInt32 tickPeriod;
   393    
   394        /*!
   395         *  ======== getTicks ========
   396         *  Time in Clock ticks
   397         *
   398         *  The value returned will wrap back to zero after it reaches the max
   399         *  value that can be stored in 32 bits.
   400         *
   401         *  @b(returns)     time in clock ticks
   402         */
   403        @DirectCall
   404        UInt32 getTicks();
   405    
   406        /*!
   407         *  ======== getTimerHandle ========
   408         *  Get timer Handle
   409         *
   410         *  Used when is it necessary to change family 
   411         *  specific options for the timer and its Hwi Object.
   412         *
   413         *  @b(returns)     Timer Handle
   414         */
   415        @DirectCall
   416        ti.sysbios.hal.Timer.Handle getTimerHandle();
   417    
   418        /*!
   419         *  ======== tickStop ========
   420         *  Stop clock for reconfiguration
   421         *
   422         *  This function is used to stop the timer used for generation of
   423         *  clock ticks. It is used along with Clock_tickStart() and 
   424         *  Clock_tickReconfig() to allow reconfiguration of timer at runtime.
   425         *
   426         *  @a(constraints)
   427         *  This function is non-reentrant and appropriate locks must be used to
   428         *  protect against  re-entrancy.
   429         */
   430        @DirectCall
   431        Void tickStop();
   432    
   433        /*!
   434         *  ======== tickReconfig ========
   435         *  Reconfigure clock for new cpu frequency
   436         *  
   437         *  This function uses the new cpu frequency to reconfigure the timer used 
   438         *  for generation of clock ticks such that tick period is 
   439         *  accurate.  This function is used along with Clock_tickStop() and 
   440         *  Clock_tickStart() to allow reconfiguration of timer at runtime.
   441         *
   442         *  When calling Clock_tickReconfig outside of main(), you must also call
   443         *  Clock_tickStop and Clock_tickStart to stop and restart the timer. 
   444         *  Use the following call sequence:
   445         *
   446         *  @p(code)
   447         *  // disable interrupts if an interrupt could lead to
   448         *  // another call to Clock_tickReconfig or if interrupt
   449         *  // processing relies on having a running timer
   450         *  Hwi_disable() or Swi_disable();
   451         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   452         *  Clock_tickStop();
   453         *  Clock_tickReconfig();
   454         *  Clock_tickStart();
   455         *  Hwi_restore() or Swi_enable()
   456         *  @p
   457         *
   458         *  When calling Clock_tickReconfig from main(), the timer has not yet
   459         *  been started because the timer is started as part of BIOS_start().
   460         *  As a result, you can use the following simplified call sequence 
   461         *  in main():
   462         *
   463         *  @p(code)
   464         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   465         *  Clock_tickReconfig(Void);
   466         *  @p
   467         *
   468         *  The return value is false if the timer cannot support the new 
   469         *  frequency
   470         *
   471         *  @b(returns)     true if successful
   472         *
   473         *  @a(constraints)
   474         *  This function is non-reentrant and appropriate locks must be used to
   475         *  protect against  re-entrancy.
   476         */
   477        @DirectCall
   478        Bool tickReconfig();
   479    
   480        /*!
   481         *  ======== tickStart ========
   482         *  Start clock after reconfiguration
   483         *
   484         *  This function starts the timer used for generation of clock ticks
   485         *  It is used along with Clock_tickStop() and Clock_tickReconfig() to
   486         *  allow reconfiguration of timer at runtime. The new timer configuration 
   487         *  reflects changes caused by a call to reconfig().
   488         *
   489         *  @a(constraints)
   490         *  This function is non-reentrant and appropriate locks must be used to
   491         *  protect against  re-entrancy.
   492         */
   493        @DirectCall
   494        Void tickStart();
   495    
   496        /*!
   497         *  ======== tick ========
   498         *  Advance Clock time by one tick
   499         *
   500         *  After incrementing a global tick counter, this function posts a Swi
   501         *  that processes the clock instances.
   502         *
   503         *  This function is automatically called by a timer ISR when
   504         *  {@link #tickSource} is set to {@link #TickSource_TIMER}. 
   505         *
   506         *  When {@link #tickSource} is set to
   507         *  {@link #TickSource_USER}, Clock_tick() must be called by the
   508         *  application.  Usually, this is done within a user defined {@link Hwi},
   509         *  {@link Swi}, or {@link Task}.
   510         *
   511         *  Note that this function is not re-entrant.  The application is
   512         *  responsible for ensuring that invocations of this function are
   513         *  serialized: either only one thread in the system ever calls this
   514         *  function or all calls are "wrapped" by an appropriate mutex.
   515         *
   516         *  @see #tickSource
   517         */
   518        @DirectCall
   519        Void tick();
   520    
   521        /*! 
   522         *  @_nodoc 
   523         *  ======== workFunc ========
   524         *  Clock Q service routine
   525         *  
   526         *  @param(arg0)    Unused. required to match Swi.FuncPtr
   527         *  @param(arg1)    Unused. required to match Swi.FuncPtr
   528         */
   529        @DirectCall
   530        Void workFunc(UArg arg0, UArg arg1);
   531    
   532        /*! 
   533         *  @_nodoc 
   534         *  ======== workFuncDynamic ========
   535         *  Clock Q service routine for TickMode_DYNAMIC
   536         *  
   537         *  @param(arg0)    Unused. required to match Swi.FuncPtr
   538         *  @param(arg1)    Unused. required to match Swi.FuncPtr
   539         */
   540        @DirectCall
   541        Void workFuncDynamic(UArg arg0, UArg arg1);
   542    
   543        /*!
   544         *  @_nodoc
   545         *  ======= logTick ========
   546         *  Log the LD_tick from within Clock module scope
   547         */
   548        @DirectCall
   549        Void logTick();
   550    
   551        /*! 
   552         *  @_nodoc 
   553         *  ======== getCompletedTicks ========
   554         *  Get the number of Clock ticks that have completed
   555         *
   556         *  Retuns the number of ticks completed, to the point where
   557         *  the underlying Timer interrupt has been serviced.  
   558         * 
   559         *  @b(returns)     time in clock ticks
   560         */
   561        @DirectCall
   562        UInt32 getCompletedTicks();
   563    
   564        /*! 
   565         *  @_nodoc 
   566         *  ======== getTickPeriod ========
   567         *  Get the Clock tick period
   568         *
   569         *  The period is in units returned by the underlying Timer.
   570         *
   571         *  @b(returns)     period in timer counts
   572         */
   573        @DirectCall
   574        UInt32 getTickPeriod();
   575    
   576        /*!
   577         *  @_nodoc
   578         *  ======= setupTimerToSkipTicks ========
   579         *  Reprogram Clock's Timer to suppress unnecessary tick interrupts 
   580         */
   581        @DirectCall
   582        Void setupTimerToSkipTicks(UInt skips);
   583    
   584    instance:
   585    
   586        /*!
   587         *  ======== create ========
   588         *  Creates a Clock Instance
   589         *
   590         *  The first argument is the function that gets called when the timeout 
   591         *  expires.
   592         *
   593         *  The 'timeout' argument is used to specify the initial timeout 
   594         *  for both one-shot and periodic Clock instances (in Clock ticks).
   595         *
   596         *  The {@link #period} parameter is used to set the subsequent timeout
   597         *  interval (in Clock ticks) for periodic instances. 
   598         *
   599         *  For one-shot instances, the period parameter must be set to zero.
   600         *
   601         *  When instances are created they are placed upon a linked list managed
   602         *  by the Clock module.  For this reason, instances cannot be created
   603         *  from either Hwi or Swi context.
   604         *
   605         *  @param(clockFxn)  Function that runs upon timeout
   606         *  @param(timeout)   One-shot timeout or initial start delay (in clock
   607         *                    ticks)
   608         */
   609        @DirectCall
   610        create(FuncPtr clockFxn, UInt timeout);
   611    
   612        /*!
   613         *  ======== startFlag ========
   614         *  Start immediately after instance is created
   615         *
   616         *  When this flag is set to false, the user will have to call 
   617         *  Clock_start() to start the instance.
   618         *     
   619         *  When set to true, both statically created Clock objects and Clock
   620         *  objects created in main() are started at the end of main() when the 
   621         *  user calls BIOS_start(). Dynamically created Clock objects created 
   622         *  after main() (ie within a task) will be started immediately. 
   623         *
   624         *  The default setting for this parameter is false.
   625         *
   626         *  The configured Clock function will be called initially after an 
   627         *  interval equal to the 'timeout' argument for both one-shot and 
   628         *  periodic Clock objects. 
   629         *
   630         *  Periodic Clock objects will subsequently be called at the rate 
   631         *  specified by the {@link #period} parameter.
   632         *
   633         */
   634        config Bool startFlag = false;
   635    
   636        /*!
   637         *  ======== period ========
   638         *  Period of this instance (in clock ticks)
   639         *
   640         *  The default value of this parameter is 0, which indicates this is
   641         *  a one-shot Clock object.
   642         *
   643         *  A non zero value for this parameter specifies that the Clock
   644         *  object is to be called periodically, and also specifies the 
   645         *  rate (in Clock ticks) that the Clock function will be called
   646         *  AFTER the initial 'timeout' argument period.
   647         * 
   648         *  For one-shot Clock instances, this parameter must be set to zero.
   649         */
   650        config UInt period = 0;
   651    
   652        /*!
   653         *  ======== arg ========
   654         *  Uninterpreted argument passed to instance function
   655         *
   656         *  The default is null.
   657         */
   658        config UArg arg = null;
   659    
   660        /*!
   661         *  ======== start ========
   662         *  Start instance
   663         *
   664         *  The {@link #timeout} and {@link #period} values set during create() 
   665         *  or by calling Clock_setTimeout() and Clock_setPeriod() are used and 
   666         *  the expiry is recomputed. 
   667         *  Note that for periodic instances, the first expiry is 
   668         *  computed using the timeout specified. All subsequent expiries use the 
   669         *  period value. 
   670         *
   671         *  @a(constraints)
   672         *  Timeout of instance cannot be zero
   673         */
   674        @DirectCall
   675        Void start();
   676    
   677        /*!
   678         *  @_nodoc
   679         *  ======== startI ========
   680         *  Internal start function which assumes Hwis disabled
   681         */
   682        @DirectCall
   683        Void startI();
   684    
   685        /*!
   686         *  ======== stop ========
   687         *  Stop instance
   688         */
   689        @DirectCall
   690        Void stop();
   691    
   692        /*!
   693         *  ======== setPeriod ========
   694         *  Set periodic interval
   695         * 
   696         *  @param(period)          periodic interval in Clock ticks
   697         * 
   698         *  @a(constraints)
   699         *  Cannot change period of instance that has been started.
   700         */
   701        @DirectCall
   702        Void setPeriod(UInt period);
   703    
   704        /*!
   705         *  ======== setTimeout ========
   706         *  Set the initial timeout
   707         *
   708         *  @param(timeout)         initial timeout in Clock ticks
   709         *
   710         *  @a(constraints)
   711         *  Cannot change the initial timeout of instance that has been started.
   712         */
   713        @DirectCall
   714        Void setTimeout(UInt timeout);
   715    
   716        /*!
   717         *  ======== setFunc ========
   718         *  Overwrite Clock function and arg
   719         *
   720         *  Replaces a Clock object's clockFxn function originally
   721         *  provided in {@link #create}.
   722         *
   723         *  @param(clockFxn)        function of type FuncPtr
   724         *  @param(arg)             argument to clockFxn
   725         *
   726         *  @a(constraints)
   727         *  Cannot change function and arg of Clock object that has been started.
   728         */
   729        @DirectCall
   730        Void setFunc(FuncPtr fxn, UArg arg);
   731    
   732        /*!
   733         *  ======== getPeriod ========
   734         *  Get period of instance
   735         *
   736         *  Returns the period of an instance.
   737         *
   738         *  @b(returns)             returns periodic interval in Clock ticks
   739         */
   740        @DirectCall
   741        UInt getPeriod();
   742    
   743        /*!
   744         *  ======== getTimeout ========
   745         *  Get timeout of instance
   746         *
   747         *  Returns the remaining time if instance has been started.
   748         *
   749         *  @b(returns)             returns timeout in clock ticks
   750         */
   751        @DirectCall
   752        UInt getTimeout();
   753    
   754    internal:
   755    
   756        /*!
   757         *  ======== doTick ========
   758         *  Function called by the timer interrupt handler
   759         *
   760         *  @param(arg)     Unused. Required to match signature of Hwi.FuncPtr
   761         */
   762        Void doTick(UArg arg);
   763    
   764        /*
   765         *  ======== Instance_State ========
   766         */
   767        struct Instance_State {
   768            Queue.Elem      elem;           // required for clock queue
   769            UInt32          timeout;        // in clock ticks
   770            UInt32          currTimeout;    // working timeout
   771            UInt32          period;         // periodic instance if > 0
   772            volatile Bool   active;         // active/idle flag
   773            FuncPtr         fxn;            // instance function
   774            UArg            arg;            // function arg
   775        };
   776    
   777        /*
   778         *  ======== Module_State ========
   779         */
   780        struct Module_State {
   781            volatile UInt32 ticks;          // ticks
   782            UInt            swiCount;       // num of Swi posts before Swi runs
   783            Timer.Handle    timer;          // timer used
   784            Void            (*doTickFunc)(UArg); 
   785                                            // points to generated Clock_doTick()
   786            Queue.Object    clockQ;         // clock que
   787            Swi.Handle      swi;            // clock swi
   788            UInt32          periodCounts;   // clock tick period in timer counts
   789            volatile UInt   numTickSkip;    // number of ticks being suppressed
   790            UInt            skipsWorkFunc;  // new skips reg'd during workFunc
   791            Bool            inWorkFunc;     // true if in Clock Swi servicing Q
   792        };
   793    }
   794    /*
   795     *  @(#) ti.sysbios.knl; 2, 0, 0, 0,542; 2-24-2012 11:41:01; /db/vtree/library/trees/avala/avala-q28x/src/ xlibrary
   796    
   797     */
   798