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     *  ======== Timer.xdc ========
    34     *
    35     */
    36    
    37    package ti.sysbios.family.msp430;
    38    
    39    import xdc.rov.ViewInfo;
    40    
    41    import xdc.runtime.Types;
    42    import xdc.runtime.Error;
    43    
    44    import ti.sysbios.interfaces.ITimer;
    45    
    46    /*!
    47     *  ======== Timer ========
    48     *  MSP430 Timer Peripherals Manager
    49     *
    50     *  This module manages the timer peripherals available on MSP430 devices
    51     *  (see {@link ./doc-files/TimerTables.html Timer Mapping Tables} for
    52     *  supported device information).
    53     *
    54     *  The Timer module supports the timer in 'one shot', 'continuous', and
    55     *  'dynamic' modes.
    56     *
    57     *  In 'one shot' mode, a timer function will "fire" (run) when the timer
    58     *  period expires. In 'one shot' mode this will only happen once.
    59     *
    60     *  In 'continuous' mode, the specified timer function will "fire" every
    61     *  time the period expires, throughout the lifetime of the program.
    62     *
    63     *  In 'dynamic' mode, the specified timer function will "fire" every
    64     *  time the period expires.  But the period of the timer can be changed
    65     *  dynamically, to correspond to the next tick interrupt needed from the
    66     *  timer.  This mode is used by the SYS/BIOS 
    67     *  {@link ti.sysbios.knl.Clock Clock} module for implementing
    68     *  dynamic tick suppression, to reduce the number of interrupts from the
    69     *  timer to the minimum required for currently scheduled timeouts.
    70     *
    71     *  NOTE: In the current implementation on MSP430 Timers cannot be 
    72     *  created dynamically at runtime by the application.  Timers must be
    73     *  created statically in the application configuration.
    74     *
    75     *  @p(html)
    76     *  <h3> Calling Context </h3>
    77     *  <table border="1" cellpadding="3">
    78     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    79     *  </colgroup>
    80     *
    81     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    82     *  <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    83     *    <!--                                                          -->
    84     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
    85     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
    87     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    88     *    <tr><td> {@link #Params_init}             </td><td>   N    </td>
    89     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    90     *    <tr><td> {@link #construct}               </td><td>   N    </td>
    91     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    92     *    <tr><td> {@link #create}                  </td><td>   N    </td>
    93     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    94     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
    95     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    96     *    <tr><td> {@link #destruct}                </td><td>   N    </td>
    97     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    98     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
    99     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   100     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
   101     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   102     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
   103     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   104     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
   105     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   106     *    <tr><td> {@link #reconfig}                </td><td>   Y    </td>
   107     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   108     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   109     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   110     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   111     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   112     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   113     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   114     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   115     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   116     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   117     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   118     *    <tr><td colspan="6"> Definitions: <br />
   119     *       <ul>
   120     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   121     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   122     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   123     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   124     *           <ul>
   125     *             <li> In your module startup after this module is started
   126     *  (e.g. Timer_Module_startupDone() returns TRUE). </li>
   127     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   128     *             <li> During main().</li>
   129     *             <li> During BIOS.startupFxns.</li>
   130     *           </ul>
   131     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   132     *           <ul>
   133     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   134     *             <li> In your module startup before this module is started
   135     *  (e.g. Timer_Module_startupDone() returns FALSE).</li>
   136     *           </ul>
   137     *       </ul>
   138     *    </td></tr>
   139     *
   140     *  </table>
   141     *  @p
   142     *
   143     *  @p(html)
   144     *  <h3> Timer Mapping Tables </h3>
   145     *  <p>
   146     *  The Timer module allows the user to use and configure the various timers
   147     *  that exist on a particular device.  This is achieved by specifying a timer
   148     *  ID when statically creating the Timer instance.
   149     *  A convention is used to assign logical IDs to physical timers.  ID '0' 
   150     *  corresponds to the first Timer_A peripheral (TA0).  ID '1' is assigned to
   151     *  the next Timer_A (TA1), until there are no more Timer_A peripherals.  Then
   152     *  the next ID is assigned to the first Timer_B peripheral (if present), and
   153     *  so on.  
   154     *  These tables are provided to show which timers map to which timer IDs.
   155     *  </p>
   156     *  {@link ./doc-files/TimerTables.html Timer Mapping Tables}
   157     *  @p
   158     */
   159    @InstanceFinalize       /* To cleanup */
   160    @InstanceInitError      /* To report unavailability of timer */
   161    @ModuleStartup          /* To configure static timers */
   162    
   163    module Timer inherits ti.sysbios.interfaces.ITimer
   164    {
   165        /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
   166        override metaonly config Bool supportsDynamic = true;
   167    
   168        /*! override defaultMode - use RunMode_DYNAMIC by default */
   169        override metaonly config Bool defaultDynamic = true;
   170    
   171        // -------- Module Types --------
   172    
   173        /*! Lists of input clock sources for timers */
   174        enum Source {
   175            Source_ACLK,                    /*! ACLK */
   176            Source_SMCLK,                   /*! SMCLK */
   177            Source_EXTERNAL,                /*! External clock */
   178            Source_EXTERNAL_INVERTED        /*! Inverted external clock */
   179        };
   180    
   181        /*! Max value of Timer period for PeriodType_COUNTS */
   182        const UInt MAX_PERIOD = 0x0000ffff;
   183    
   184        /*! @_nodoc
   185         *  Min instructions to use in trigger().
   186         */
   187        const Int MIN_SWEEP_PERIOD = 1;
   188    
   189        /*! Timer Configuration struct.
   190         *
   191         *  @field(source)  Timer clock source.
   192         */
   193        struct Control {
   194            UInt source;   /*! 0x100=ACLK, 0x200=SMCLK, 0=EXT, 0x300=EXT_INVERT */
   195        };
   196    
   197        /*! @_nodoc */
   198        @XmlDtd
   199        metaonly struct BasicView {
   200            Ptr         halTimerHandle;
   201            String      label;
   202            UInt        id;
   203            Control     configuration;
   204            String      startMode;
   205            String      runMode;
   206            UInt        period;
   207            String      periodType;
   208            Bool        synchronous;
   209            UInt        intNum;
   210            String      tickFxn[];
   211            UArg        arg;
   212            UInt        frequency;
   213            String      hwiHandle;
   214        };
   215    
   216        /*! @_nodoc */
   217        metaonly struct DeviceView {
   218            UInt        id;
   219            String      device;
   220            String      devAddr;
   221            UInt        intNum;
   222            String      runMode;
   223            UInt        period;
   224            UInt        currCount;
   225            UInt        remainingCount;
   226            UInt        prevThreshold;
   227            String      state;
   228        };
   229    
   230        /*! @_nodoc */
   231        metaonly struct ModuleView {
   232            String      availMask;      /* available 32-bit timer halves */
   233        }
   234    
   235        /*! @_nodoc */
   236        @Facet
   237        metaonly config ViewInfo.Instance rovViewInfo = 
   238            ViewInfo.create({
   239                viewMap: [
   240                [
   241                    'Basic',
   242                    {
   243                        type: ViewInfo.INSTANCE,
   244                        viewInitFxn: 'viewInitBasic',
   245                        structName: 'BasicView'
   246                    }
   247                ],
   248                [
   249                    'Device',
   250                    {
   251                        type: ViewInfo.INSTANCE,
   252                        viewInitFxn: 'viewInitDevice',
   253                        structName: 'DeviceView'
   254                    }
   255                ],
   256                [
   257                    'Module',
   258                    {
   259                        type: ViewInfo.MODULE,
   260                        viewInitFxn: 'viewInitModule',
   261                        structName: 'ModuleView'
   262                    }
   263                ],
   264                ]
   265            });
   266    
   267        /*!
   268         *  ======== E_invalidTimer ========
   269         *  Error raised when specified timer id is not supported
   270         */
   271        config Error.Id E_invalidTimer = {
   272            msg: "E_invalidTimer: Invalid Timer Id %d"
   273        };
   274    
   275        /*!
   276         *  ======== E_notAvailable ========
   277         *  Error raised when requested timer is in use
   278         */
   279        config Error.Id E_notAvailable = {
   280            msg: "E_notAvailable: Timer not available %d"
   281        };
   282    
   283        /*!
   284         *  ======== E_cannotSupport ========
   285         *  Error raised when requested period is not supported
   286         */
   287        config Error.Id E_cannotSupport = {
   288            msg: "E_cannotSupport: Timer cannot support requested period %d"
   289        };
   290    
   291        /*!
   292         *  ======== E_runtimeCreate ========
   293         *  Error raised when dynamic Timer create is attempted
   294         */
   295        config Error.Id E_runtimeCreate = {
   296            msg: "E_runtimeCreate: Runtime Timer create is not supported %d"
   297        };
   298    
   299        /*!
   300         *  ======== anyMask ========
   301         *  Mask of available timers
   302         *
   303         *  This mask is used to identify the timers that can be used when
   304         *  Timer_create() is called with an id equal to
   305         *  {@link Timer#ANY Timer_ANY}.
   306         */
   307        config UInt anyMask = 0x7;
   308    
   309        /*!
   310         *  ======== keepAwake ========
   311         *  Wakeup (enable) CPU when Timer ISR returns
   312         *
   313         *  If set to `true`, all Timer instances keep the CPU awake upon
   314         *  return from interrupt.
   315         */
   316        config Bool keepAwake = false;
   317    
   318        /*!
   319         *  ======== oneShotStub ========
   320         *  @_nodoc
   321         *
   322         *  @param(arg)     Unused.
   323         */
   324        Void oneShotStub(UArg arg);
   325    
   326        /*!
   327         *  ======== oneShotNestStub ========
   328         *  @_nodoc
   329         *
   330         *  @param(arg)     Unused.
   331         */
   332        Void oneShotNestStub(UArg arg);
   333    
   334        /*!
   335         *  ======== periodicStub ========
   336         *  @_nodoc
   337         *
   338         *  @param(arg)     Unused.
   339         */
   340        Void periodicStub(UArg arg);
   341    
   342        /*!
   343         *  ======== periodicNestStub ========
   344         *  @_nodoc
   345         *
   346         *  @param(arg)     Unused.
   347         */
   348        Void periodicNestStub(UArg arg);
   349    
   350        /*!
   351         *  ======== getHandle ========
   352         *  @_nodoc
   353         *  Used by TimestampProvider module to get hold of timer handle used by
   354         *  Clock.
   355         *
   356         *  @param(id)      timer Id.
   357         */
   358        Handle getHandle(UInt id);
   359    
   360    instance:
   361    
   362        /*! Hwi Params for Hwi Object. Default is null. */
   363        config Hwi.Params *hwiParams = null;
   364    
   365        /*! Clock source input select. Default is ACLK. */
   366        config Source clockSource = Source_ACLK;
   367    
   368        /*! Selected clock source is synchronous to CPU clock? Default is false. */
   369        config Bool synchronous = false;
   370    
   371        /*! Enable nesting of other interrupts on top of this Timer's ISR? */
   372        config Bool nesting = false;
   373    
   374        /*! Previous threshold count value. */
   375        config UInt prevThreshold = 0;
   376    
   377        /*! Control register configuration. Default source = ACLK. */
   378        config Control controlRegInit = {source: Source_ACLK};
   379    
   380        /*!
   381         *  ======== reconfig ========
   382         *  Modify timer instances at runtime
   383         *
   384         *  @param(timerParams)     timer Params
   385         *  @param(tickFxn)         function that runs when timer expires.
   386         */
   387        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   388    
   389    
   390    internal:   /* not for client use */
   391    
   392        /*!
   393         *  ======== noStartupNeeded ========
   394         *  Flag used to prevent misc code from being brought in
   395         *  un-necessarily
   396         */
   397        config UInt startupNeeded = false;
   398    
   399        /*! Information about timer */
   400        struct TimerDevice {
   401            UInt intNum;
   402            Ptr  baseAddr;
   403        };
   404    
   405        /*!
   406         *  ======== numTimerDevices ========
   407         *  The number of physical timers on the device
   408         */
   409        config Int numTimerDevices;
   410    
   411        struct Instance_State {
   412            Bool                    staticInst;
   413            Int                     id;
   414            UInt                    controlRegInit;
   415            ITimer.RunMode          runMode;
   416            ITimer.StartMode        startMode;
   417            UInt                    period;
   418            ITimer.PeriodType       periodType;
   419            UInt                    intNum;
   420            UArg                    arg;
   421            Hwi.FuncPtr             tickFxn;
   422            Types.FreqHz            frequency;
   423            Hwi.Handle              hwi;
   424            UInt                    prevThreshold;
   425            Bool                    synchronous;
   426        }
   427    
   428        struct Module_State {
   429            UInt            availMask;      /* available peripherals */
   430            TimerDevice     device[];       /* timer device information */
   431            Handle          handles[];      /* array of handles based on id */
   432        }
   433    }
   434    /*
   435     *  @(#) ti.sysbios.family.msp430; 1, 0, 0, 0,205; 2-24-2012 11:40:25; /db/vtree/library/trees/avala/avala-q28x/src/ xlibrary
   436    
   437     */
   438