1    /* 
     2     * Copyright (c) 2011, 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     *  Clock Instances are functions that can be scheduled to run after a 
    59     *  certain number of Clock ticks.
    60     *  Clock instances are either one-shot or periodic. Instances are started 
    61     *  when created or they are started later using the Clock_start()function. 
    62     *  Instances can be stopped using the Clock_stop() function. All Clock 
    63     *  Instances are executed when they expire in the context of a software 
    64     *  interrupt.
    65     *
    66     *  Clock objects are placed in the Clock object service list when 
    67     *  created/constructed and remain there until deleted/destructed.
    68     *  To minimize processing overhead, unused or expired Clock objects 
    69     *  should be deleted or destructed.
    70     *
    71     *  The getTicks() function returns number of clock ticks since startup.
    72     *
    73     *  By default, the Clock module statically configures a 
    74     *  {@link ti.sysbios.hal.Timer}
    75     *  timer instance to provide the periodic 1 ms tick interrupt. If you
    76     *  want to use a custom configured timer for the Clock module's tick source,
    77     *  use the following example configuration as a guide:
    78     *
    79     *  @p(code)
    80     *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    81     *
    82     *  // Tell the Clock module that YOU are providing the periodic interrupt
    83     *  Clock.tickSource = Clock.TickSource_USER;
    84     *
    85     *  // this example uses the ti.sysbios.timers.dmtimer.Timer module
    86     *  var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
    87     *
    88     *  // create a dmtimer config parameter object
    89     *  var timerParams = new Timer.Params();
    90     *
    91     *  // make sure you set the period to 1000 us (1ms)
    92     *  timerParams.period = 1000;
    93     *
    94     *  // custom dmtimer config parameters here...
    95     *  timerParams.twer.ovf_wup_ena = 1;
    96     *
    97     *  // Create the timer.
    98     *  // This example uses timer id 3.
    99     *  // The timer interrupt handler must be set to 'Clock.tick'. 
   100     *  Timer.create(3, Clock.tick, timerParams);
   101     *  @p
   102     *
   103     *  @p(html)
   104     *  <h3> Calling Context </h3>
   105     *  <table border="1" cellpadding="3">
   106     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   107     *    </colgroup>
   108     *
   109     *    <tr><th> Function                </th><th>  Hwi   </th><th>  Swi   </th>
   110     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   111     *    <!--                                                                -->
   112     *    <tr><td> {@link #getTicks}       </td><td>   Y    </td><td>   Y    </td>
   113     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   114     *    <tr><td> {@link #getTimerHandle} </td><td>   Y    </td><td>   Y    </td>
   115     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   116     *    <tr><td> {@link #Params_init}    </td><td>   Y    </td><td>   Y    </td>
   117     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   118     *    <tr><td> {@link #tick}           </td><td>   Y    </td><td>   Y    </td>
   119     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   120     *    <tr><td> {@link #tickReconfig}   </td><td>   Y    </td><td>   Y    </td>
   121     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   122     *    <tr><td> {@link #tickStart}      </td><td>   Y    </td><td>   Y    </td>
   123     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   124     *    <tr><td> {@link #tickStop}       </td><td>   Y    </td><td>   Y    </td>
   125     *    <td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   126     *    <tr><td> {@link #construct}      </td><td>   N    </td><td>   N    </td>
   127     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   128     *    <tr><td> {@link #create}         </td><td>   N    </td><td>   N    </td>
   129     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   130     *    <tr><td> {@link #delete}         </td><td>   N    </td><td>   N    </td>
   131     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   132     *    <tr><td> {@link #destruct}       </td><td>   N    </td><td>   N    </td>
   133     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   134     *    <tr><td> {@link #getTimeout}     </td><td>   Y    </td><td>   Y    </td>
   135     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   136     *    <tr><td> {@link #setFunc}        </td><td>   Y    </td><td>   Y    </td>
   137     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   138     *    <tr><td> {@link #setPeriod}      </td><td>   Y    </td><td>   Y    </td>
   139     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   140     *    <tr><td> {@link #setTimeout}     </td><td>   Y    </td><td>   Y    </td>
   141     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   142     *    <tr><td> {@link #start}          </td><td>   Y    </td><td>   Y    </td>
   143     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   144     *    <tr><td> {@link #stop}           </td><td>   Y    </td><td>   Y    </td>
   145     *    <td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   146     *    <tr><td colspan="6"> Definitions: <br />
   147     *       <ul>
   148     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   149     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   150     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   151     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   152     *           <ul>
   153     *             <li> In your module startup after this module is started 
   154     *    (e.g. Clock_Module_startupDone() returns TRUE). </li>
   155     *             <li> During 
   156     *    {@link xdc.runtime.Startup#lastFxns Startup.lastFxns}. </li>
   157     *             <li> During main().</li>
   158     *             <li> During 
   159     *    {@link ti.sysbios.BIOS#startupFxns BIOS.startupFxns}.</li>
   160     *           </ul>
   161     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   162     *           <ul>
   163     *             <li> During 
   164     *    {@link xdc.runtime.Startup#firstFxns Startup.firstFxns}.</li>
   165     *             <li> In your module startup before this module is started 
   166     *    (e.g. Clock_Module_startupDone() returns FALSE).</li>
   167     *           </ul>
   168     *       </ul>
   169     *    </td></tr>
   170     *
   171     *  </table>
   172     *  @p
   173     */
   174    
   175    @ModuleStartup
   176    @InstanceFinalize   /* generate call to Clock_Instance_finalize on delete */
   177    @Template("./Clock.xdt")
   178    
   179    module Clock
   180    {
   181        /*! Clock Tick Source. */
   182        enum  TickSource {
   183            TickSource_TIMER,       /*! Timer Instance used to generate tick */
   184            TickSource_USER,        /*! Clock_tick() run in user's ISR */
   185            TickSource_NULL         /*! No clock tick */
   186        };
   187    
   188        metaonly struct BasicView {
   189            String          label;
   190            UInt32          timeout;
   191            UInt            period;
   192            String          fxn[];
   193            UArg            arg;
   194            Bool            started;        /* Instance running? */
   195            UInt32          tRemaining;     /* Remaining timeout */
   196            Bool            periodic;       /* Periodic? (vs. one-shot) */
   197        }
   198        
   199        metaonly struct ModuleView {
   200            volatile UInt32         ticks;
   201            String                  tickSource;
   202            String                  timerHandle;
   203            UInt                    timerId;
   204            UInt                    swiPriority;
   205            UInt32                  tickPeriod;
   206        }
   207    
   208        /*! @_nodoc */
   209        @Facet
   210        metaonly config ViewInfo.Instance rovViewInfo = 
   211            ViewInfo.create({
   212                viewMap: [
   213                  ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',  structName: 'BasicView'}],
   214                  ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule', structName: 'ModuleView'}],
   215                ]
   216            });
   217            
   218        /*! Instance function prototype. */
   219        typedef Void (*FuncPtr)(UArg);
   220    
   221        /*! Logged if Clock Swi delayed by >= 1 tick */
   222        config Log.Event LW_delayed = {
   223            mask: Diags.USER3,
   224            msg: "LW_delayed: delay: %d"
   225        };
   226    
   227        /*! Logged in every Clock tick interrupt */
   228        config Log.Event LM_tick = {
   229            mask: Diags.USER1 | Diags.USER2,
   230            msg: "LM_tick: tick: %d"
   231        };
   232    
   233        /*! Logged just prior to calling each Clock function */
   234        config Log.Event LM_begin = {
   235            mask: Diags.USER1 | Diags.USER2,
   236            msg: "LM_begin: clk: 0x%x, func: 0x%x"
   237        };
   238    
   239        /*! Asserted in Clock_create() */
   240        config Assert.Id A_clockDisabled = {
   241            msg: "A_clockDisabled: Cannot create a clock instance when BIOS.clockEnabled is false."
   242        };
   243    
   244        /*! Asserted in Clock_create and Clock_delete */
   245        config Assert.Id A_badThreadType = {
   246            msg: "A_badThreadType: Cannot create/delete a Clock from Hwi or Swi thread."
   247        };
   248    
   249        /*!
   250         *  ======== tickSource ========
   251         *  Default is TickSource_TIMER.
   252         */
   253        config TickSource tickSource = TickSource_TIMER;
   254    
   255        /*!
   256         *  ======== timerId ========
   257         *  Timer Id for Timer Instance created by Clock. 
   258         *
   259         *  The default value is Timer.ANY (~0).
   260         *  The maximum timerId possible is family-specific.
   261         */
   262        config UInt timerId = ~0;
   263    
   264        /*!
   265         *  ======== swiPriority ========
   266         *  Set the priority of Swi used by Clock module to process its instances.
   267         *
   268         *  Default is Swi.numPriorities - 1;
   269         */
   270        metaonly config UInt swiPriority;
   271    
   272        /*!
   273         *  ======== tickPeriod ========
   274         *  Tick period specified in microseconds.
   275         *  
   276         *  Default value is family dependent. For example, linux86 supports a 
   277         *  minimum of 10000us and supports only multiples of 10000us. TI 
   278         *  targets have a default of 1000 microseconds.
   279         */
   280        config UInt32 tickPeriod;
   281    
   282        /*!
   283         *  ======== getTicks ========
   284         *  Time in Clock ticks
   285         *
   286         *  The value returned will wrap back to zero after it reaches the max
   287         *  value that can be stored in 32 bits.
   288         *
   289         *  @b(returns)     time in clock ticks
   290         */
   291        @DirectCall
   292        UInt32 getTicks();
   293    
   294        /*!
   295         *  ======== getTimerHandle ========
   296         *  Get timer Handle. 
   297         *
   298         *  Used when is it necessary to change family 
   299         *  specific options for the timer and its Hwi Object.
   300         *
   301         *  @b(returns)     Timer Handle
   302         */
   303        @DirectCall
   304        ti.sysbios.hal.Timer.Handle getTimerHandle();
   305    
   306        /*!
   307         *  ======== tickStop ========
   308         *  Stop clock for reconfiguration.
   309         *
   310         *  This function is used to stop the timer used for generation of
   311         *  clock ticks. It is used along with Clock_tickStart() and 
   312         *  Clock_tickReconfig() to allow reconfiguration of timer at runtime.
   313         *
   314         *  @a(constraints)
   315         *  This function is non-reentrant and appropriate locks must be used to
   316         *  protect against  re-entrancy.
   317         */
   318        @DirectCall
   319        Void tickStop();
   320    
   321        /*!
   322         *  ======== tickReconfig ========
   323         *  Reconfigure clock for new cpu frequency.
   324         *  
   325         *  This function uses the new cpu frequency to reconfigure the timer used 
   326         *  for generation of clock ticks such that tick period is 
   327         *  accurate.  This function is used along with Clock_tickStop() and 
   328         *  Clock_tickStart() to allow reconfiguration of timer at runtime.
   329         *
   330         *  When calling Clock_tickReconfig outside of main(), you must also call
   331         *  Clock_tickStop and Clock_tickStart to stop and restart the timer. 
   332         *  Use the following call sequence:
   333         *
   334         *  @p(code)
   335         *  // disable interrupts if an interrupt could lead to
   336         *  // another call to Clock_tickReconfig or if interrupt
   337         *  // processing relies on having a running timer
   338         *  Hwi_disable() or Swi_disable();
   339         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   340         *  Clock_tickStop();
   341         *  Clock_tickReconfig();
   342         *  Clock_tickStart();
   343         *  Hwi_restore() or Swi_enable()
   344         *  @p
   345         *
   346         *  When calling Clock_tickReconfig from main(), the timer has not yet
   347         *  been started because the timer is started as part of BIOS_start().
   348         *  As a result, you can use the following simplified call sequence 
   349         *  in main():
   350         *
   351         *  @p(code)
   352         *  BIOS_setCpuFrequency(Types.FreqHz *freq);
   353         *  Clock_tickReconfig(Void);
   354         *  @p
   355         *
   356         *  The return value is false if the timer cannot support the new 
   357         *  frequency
   358         *
   359         *  @b(returns)     true if successful
   360         *
   361         *  @a(constraints)
   362         *  This function is non-reentrant and appropriate locks must be used to
   363         *  protect against  re-entrancy.
   364         */
   365        @DirectCall
   366        Bool tickReconfig();
   367    
   368        /*!
   369         *  ======== tickStart ========
   370         *  Start clock after reconfiguration.
   371         *
   372         *  This function starts the timer used for generation of clock ticks
   373         *  It is used along with Clock_tickStop() and Clock_tickReconfig() to allow
   374         *  reconfiguration of timer at runtime. The new timer configuration 
   375         *  reflects changes caused by a call to reconfig().
   376         *
   377         *  @a(constraints)
   378         *  This function is non-reentrant and appropriate locks must be used to
   379         *  protect against  re-entrancy.
   380         */
   381        @DirectCall
   382        Void tickStart();
   383    
   384        /*!
   385         *  ======== tick ========
   386         *  Function called by the timer ISR when {@link #tickSource} is
   387         *  {@link #TickSource_TIMER}. 
   388         *
   389         *  When {@link #tickSource} is set to
   390         *  {@link #TickSource_USER}, Clock_tick() is called by a user isr, 
   391         *  Swi or Task. Note that this function is not re-entrant and 
   392         *  appropriate locks should be used.
   393         *
   394         *  This function posts a Swi that processes the clock instances.
   395         */
   396        @DirectCall
   397        Void tick();
   398    
   399        /*! @_nodoc 
   400         *  ======== workFunc ========
   401         *  Clock Q service routine
   402         *  
   403         *  @param(arg0)    Unused. required to match Swi.FuncPtr
   404         *  @param(arg1)    Unused. required to match Swi.FuncPtr
   405         */
   406        @DirectCall
   407        Void workFunc(UArg arg0, UArg arg1);
   408    
   409        /*!
   410         *  @_nodoc
   411         *  ======= logTock ========
   412         *  Log the LD_tick from within Clock module scope
   413         */
   414        @DirectCall
   415        Void logTick();
   416    
   417    instance:
   418    
   419        /*!
   420         *  ======== create ========
   421         *  Creates a Clock Instance. 
   422         *
   423         *  The first parameter is the function that gets called when the timeout 
   424         *  expires. 
   425         *
   426         *  The timeout parameter is used to specify the initial timeout 
   427         *  for both one-shot and periodic Clock instances (in Clock ticks).
   428         *
   429         *  The {@link #period} parameter is used to set the subsequent timeout
   430         *  interval (in Clock ticks) for periodic instances. 
   431         *
   432         *  For one-shot instances, the period parameter must be set to zero.
   433         *
   434         *  @param(clockFxn)        function that runs upon timeout
   435         *  @param(timeout)         timeout in clock ticks
   436         */
   437        @DirectCall
   438        create(FuncPtr clockFxn, UInt timeout);
   439    
   440        /*!
   441         *  ======== startFlag ========
   442         *  Set if instance needs to be started. 
   443         *
   444         *  The default is false.
   445         *
   446         *  When this flag is set to true, the instance created will be started 
   447         *  and the instance function will get called after an interval
   448         *  equal to its timeout. When set to false, the user has to call
   449         *  Clock_start() to start the instance.
   450         */
   451        config Bool startFlag = false;
   452    
   453        /*!
   454         *  ======== period ========
   455         *  Instance period. 
   456         *
   457         *  The default is 0.
   458         *
   459         *  For periodic Clock instances, this parameter specifies the periodic
   460         *  timeout interval (in Clock ticks).
   461         * 
   462         *  For one-shot Clock instances, this parameter must be set to zero.
   463         */
   464        config UInt period = 0;
   465    
   466        /*!
   467         *  ======== arg ========
   468         *  UArg for Clock Instance function. 
   469         *
   470         *  The default is null.
   471         */
   472        config UArg arg = null;
   473    
   474        /*!
   475         *  ======== start ========
   476         *  Start instance.
   477         *
   478         *  The {@link #timeout} and {@link #period} values set during create() 
   479         *  or by calling Clock_setTimeout() and Clock_setPeriod() are used and 
   480         *  the expiry is recomputed. 
   481         *  Note that for periodic instances, the first expiry is 
   482         *  computed using the timeout specified. All subsequent expiries use the 
   483         *  period value. 
   484         *
   485         *  @a(constraints)
   486         *  Timeout of instance cannot be zero
   487         */
   488        @DirectCall
   489        Void start();
   490    
   491        /*!
   492         *  @_nodoc
   493         *  ======== startI ========
   494         *  Internal start function which assumes Hwis disabled.
   495         */
   496        @DirectCall
   497        Void startI();
   498    
   499        /*!
   500         *  ======== stop ========
   501         *  Stop instance.
   502         */
   503        @DirectCall
   504        Void stop();
   505    
   506        /*!
   507         *  ======== setPeriod ========
   508         *  Set periodic interval.
   509         * 
   510         *  @param(period)          periodic interval in Clock ticks
   511         * 
   512         *  @a(constraints)
   513         *  Cannot change period of instance that has been started.
   514         */
   515        @DirectCall
   516        Void setPeriod(UInt period);
   517    
   518        /*!
   519         *  ======== setTimeout ========
   520         *  Set the initial timeout.
   521         *
   522         *  @param(timeout)         initial timeout in Clock ticks
   523         *
   524         *  @a(constraints)
   525         *  Cannot change the initial timeout of instance that has been started.
   526         */
   527        @DirectCall
   528        Void setTimeout(UInt timeout);
   529    
   530        /*!
   531         *  ======== setFunc ========
   532         *  Overwrite Clock function and arg.
   533         *
   534         *  Replaces a Clock object's clockFxn function originally
   535         *  provided in {@link #create}.
   536         *
   537         *  @param(clockFxn)        function of type FuncPtr
   538         *  @param(arg)             argument to clockFxn
   539         *
   540         *  @a(constraints)
   541         *  Cannot change function and arg of Clock object that has been started.
   542         */
   543        @DirectCall
   544        Void setFunc(FuncPtr fxn, UArg arg);
   545    
   546        /*!
   547         *  ======== getTimeout ========
   548         *  Get timeout of instance. 
   549         *
   550         *  Returns the remaining time if instance has been started.
   551         *
   552         *  @b(returns)             returns timeout in clock ticks
   553         */
   554        @DirectCall
   555        UInt getTimeout();
   556    
   557    internal:
   558    
   559        /*!
   560         *  ======== doTick ========
   561         *  Function called by the timer interrupt handler. 
   562         *
   563         *  @param(arg)     Unused. Required to match signature of Hwi.FuncPtr
   564         */
   565        Void doTick(UArg arg);
   566    
   567        struct Instance_State {
   568            Queue.Elem      elem;           // required for clock queue
   569            UInt32          timeout;        // in clock ticks
   570            UInt32          currTimeout;    // working timeout
   571            UInt32          period;         // periodic instance if > 0
   572            volatile Bool   active;         // active/idle flag
   573            FuncPtr         fxn;            // instance function
   574            UArg            arg;            // function arg
   575        };
   576    
   577        struct Module_State {
   578            volatile UInt32 ticks;          // ticks
   579            UInt            swiCount;       // num of Swi posts before Swi runs
   580            Timer.Handle    timer;          // timer used
   581            Void            (*doTickFunc)(UArg); 
   582                                            // points to generated Clock_doTick()
   583            Queue.Object    clockQ;         // clock que
   584            Swi.Handle      swi;            // clock swi
   585        };
   586    }
   587    /*
   588     *  @(#) ti.sysbios.knl; 2, 0, 0, 0,451; 2-2-2011 15:07:12; /db/vtree/library/trees/avala/avala-o27x/src/ xlibrary
   589    
   590     */
   591