1    /*
     2     * Copyright (c) 2014, 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 #getAvailMask}            </td><td>   Y    </td>
    85     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
    87     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    88     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
    89     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    90     *    <tr><td> {@link #Params_init}             </td><td>   N    </td>
    91     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    92     *    <tr><td> {@link #construct}               </td><td>   N    </td>
    93     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    94     *    <tr><td> {@link #create}                  </td><td>   N    </td>
    95     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    96     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
    97     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    98     *    <tr><td> {@link #destruct}                </td><td>   N    </td>
    99     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   100     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
   101     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   102     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
   103     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   104     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
   105     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   106     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
   107     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   108     *    <tr><td> {@link #reconfig}                </td><td>   Y    </td>
   109     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   110     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   111     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   112     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   113     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   114     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   115     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   116     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   117     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   118     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   119     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   120     *    <tr><td colspan="6"> Definitions: <br />
   121     *       <ul>
   122     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   123     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   124     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   125     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   126     *           <ul>
   127     *             <li> In your module startup after this module is started
   128     *  (e.g. Timer_Module_startupDone() returns TRUE). </li>
   129     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   130     *             <li> During main().</li>
   131     *             <li> During BIOS.startupFxns.</li>
   132     *           </ul>
   133     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   134     *           <ul>
   135     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   136     *             <li> In your module startup before this module is started
   137     *  (e.g. Timer_Module_startupDone() returns FALSE).</li>
   138     *           </ul>
   139     *       </ul>
   140     *    </td></tr>
   141     *
   142     *  </table>
   143     *  @p
   144     *
   145     *  @p(html)
   146     *  <h3> Timer Mapping Tables </h3>
   147     *  <p>
   148     *  The Timer module allows the user to use and configure the various timers
   149     *  that exist on a particular device.  This is achieved by specifying a timer
   150     *  ID when statically creating the Timer instance.
   151     *  A convention is used to assign logical IDs to physical timers.  ID '0' 
   152     *  corresponds to the first Timer_A peripheral (TA0).  ID '1' is assigned to
   153     *  the next Timer_A (TA1), until there are no more Timer_A peripherals.  Then
   154     *  the next ID is assigned to the first Timer_B peripheral (if present), and
   155     *  so on.  
   156     *  These tables are provided to show which timers map to which timer IDs.
   157     *  </p>
   158     *  {@link ./doc-files/TimerTables.html Timer Mapping Tables}
   159     *  @p
   160     */
   161    @ModuleStartup          /* To configure static timers */
   162    @InstanceInitStatic
   163    
   164    module Timer inherits ti.sysbios.interfaces.ITimer
   165    {
   166        /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
   167        override metaonly config Bool supportsDynamic = true;
   168    
   169        /*! override defaultMode - use RunMode_PERIODIC by default */
   170        override metaonly config Bool defaultDynamic = false;
   171    
   172        // -------- Module Types --------
   173    
   174        /*! Lists of input clock sources for timers */
   175        enum Source {
   176            Source_ACLK = 0x100,               /*! ACLK */
   177            Source_SMCLK = 0x200,              /*! SMCLK */
   178            Source_EXTERNAL = 0x000,           /*! External clock */
   179            Source_EXTERNAL_INVERTED = 0x300   /*! Inverted external clock */
   180        };
   181    
   182        /*! Input divider (ID) bit field values */
   183        enum ID {
   184            ID_1 = 0x0,                     /*! /1 */
   185            ID_2 = 0x40,                    /*! /2 */
   186            ID_4 = 0x80,                    /*! /4 */
   187            ID_8 = 0xC0                     /*! /8 */
   188        };
   189    
   190        /*! Input Divider Expansion (IDEX) bit field values */
   191        enum IDEX {
   192            IDEX_1 = 0x0,                   /*! /1 */
   193            IDEX_2 = 0x1,                   /*! /2 */
   194            IDEX_3 = 0x2,                   /*! /3 */
   195            IDEX_4 = 0x3,                   /*! /4 */
   196            IDEX_5 = 0x4,                   /*! /5 */
   197            IDEX_6 = 0x5,                   /*! /6 */
   198            IDEX_7 = 0x6,                   /*! /7 */
   199            IDEX_8 = 0x7                    /*! /8 */
   200        };
   201    
   202        /*! Max value of Timer period for PeriodType_COUNTS */
   203        const UInt MAX_PERIOD = 0x0000ffff;
   204    
   205        /*! @_nodoc
   206         *  Min instructions to use in trigger().
   207         */
   208        const Int MIN_SWEEP_PERIOD = 1;
   209    
   210        /*! Timer Configuration struct.
   211         *
   212         *  @field(source)  Timer clock source.
   213         */
   214        struct Control {
   215            UInt source;   /*! 0x100=ACLK, 0x200=SMCLK, 0=EXT, 0x300=EXT_INVERT */
   216        };
   217    
   218        /*! @_nodoc */
   219        @XmlDtd
   220        metaonly struct BasicView {
   221            Ptr         halTimerHandle;
   222            String      label;
   223            UInt        id;
   224            Control     configuration;
   225            String      startMode;
   226            String      runMode;
   227            UInt        period;
   228            String      periodType;
   229            Bool        synchronous;
   230            UInt        intNum;
   231            String      tickFxn[];
   232            UArg        arg;
   233            UInt        frequency;
   234            String      hwiHandle;
   235        };
   236    
   237        /*! @_nodoc */
   238        metaonly struct DeviceView {
   239            UInt        id;
   240            String      device;
   241            String      devAddr;
   242            UInt        intNum;
   243            String      runMode;
   244            UInt        period;
   245            UInt        currCount;
   246            UInt        remainingCount;
   247            UInt        prevThreshold;
   248            String      state;
   249        };
   250    
   251        /*! @_nodoc */
   252        metaonly struct ModuleView {
   253            String      availMask;      /* available 32-bit timer halves */
   254        }
   255    
   256        /*! @_nodoc */
   257        @Facet
   258        metaonly config ViewInfo.Instance rovViewInfo = 
   259            ViewInfo.create({
   260                viewMap: [
   261                [
   262                    'Basic',
   263                    {
   264                        type: ViewInfo.INSTANCE,
   265                        viewInitFxn: 'viewInitBasic',
   266                        structName: 'BasicView'
   267                    }
   268                ],
   269                [
   270                    'Device',
   271                    {
   272                        type: ViewInfo.INSTANCE,
   273                        viewInitFxn: 'viewInitDevice',
   274                        structName: 'DeviceView'
   275                    }
   276                ],
   277                [
   278                    'Module',
   279                    {
   280                        type: ViewInfo.MODULE,
   281                        viewInitFxn: 'viewInitModule',
   282                        structName: 'ModuleView'
   283                    }
   284                ],
   285                ]
   286            });
   287    
   288        /*!
   289         *  ======== E_invalidTimer ========
   290         *  Error raised when specified timer id is not supported
   291         */
   292        config Error.Id E_invalidTimer = {
   293            msg: "E_invalidTimer: Invalid Timer Id %d"
   294        };
   295    
   296        /*!
   297         *  ======== E_notAvailable ========
   298         *  Error raised when requested timer is in use
   299         */
   300        config Error.Id E_notAvailable = {
   301            msg: "E_notAvailable: Timer not available %d"
   302        };
   303    
   304        /*!
   305         *  ======== E_cannotSupport ========
   306         *  Error raised when requested period is not supported
   307         */
   308        config Error.Id E_cannotSupport = {
   309            msg: "E_cannotSupport: Timer cannot support requested period %d"
   310        };
   311    
   312        /*!
   313         *  ======== E_runtimeCreate ========
   314         *  Error raised when dynamic Timer create is attempted
   315         */
   316        config Error.Id E_runtimeCreate = {
   317            msg: "E_runtimeCreate: Runtime Timer create is not supported %d"
   318        };
   319    
   320        /*!
   321         *  ======== anyMask ========
   322         *  Mask of available timers
   323         *
   324         *  This mask is used to identify the timers that can be used when
   325         *  Timer_create() is called with an id equal to
   326         *  {@link Timer#ANY Timer_ANY}.
   327         */
   328        config UInt anyMask = 0x7;
   329    
   330        /*!
   331         *  ======== keepAwake ========
   332         *  Wakeup (enable) CPU when Timer ISR returns
   333         *
   334         *  If set to `true`, all Timer instances keep the CPU awake upon
   335         *  return from interrupt.
   336         */
   337        config Bool keepAwake = false;
   338    
   339        /*!
   340         *  ======== oneShotStub ========
   341         *  @_nodoc
   342         *
   343         *  @param(arg)     Unused.
   344         */
   345        Void oneShotStub(UArg arg);
   346    
   347        /*!
   348         *  ======== oneShotNestStub ========
   349         *  @_nodoc
   350         *
   351         *  @param(arg)     Unused.
   352         */
   353        Void oneShotNestStub(UArg arg);
   354    
   355        /*!
   356         *  ======== periodicStub ========
   357         *  @_nodoc
   358         *
   359         *  @param(arg)     Unused.
   360         */
   361        Void periodicStub(UArg arg);
   362    
   363        /*!
   364         *  ======== periodicNestStub ========
   365         *  @_nodoc
   366         *
   367         *  @param(arg)     Unused.
   368         */
   369        Void periodicNestStub(UArg arg);
   370    
   371        /*!
   372         *  ======== getHandle ========
   373         *  @_nodoc
   374         *  Used by TimestampProvider module to get hold of timer handle used by
   375         *  Clock.
   376         *
   377         *  @param(id)      timer Id.
   378         */
   379        Handle getHandle(UInt id);
   380    
   381        /*!
   382         *  ======== getAvailMask ========
   383         *  Returns the availMask.
   384         *
   385         *  @b(returns)     Mask of available timers
   386         */
   387        UInt getAvailMask();
   388    
   389    instance:
   390    
   391        /*! Hwi Params for Hwi Object. Default is null. */
   392        config Hwi.Params *hwiParams = null;
   393    
   394        /*! Clock source input select. Default is ACLK. */
   395        config Source clockSource = Source_ACLK;
   396    
   397        /*! Selected clock source is synchronous to CPU clock? Default is false. */
   398        config Bool synchronous = false;
   399    
   400        /*! Clock Input Divider (ID) select. Default is /1. */
   401        config ID inputDivider = ID_1;
   402    
   403        /*! Clock Input Divider Expansion (IDEX) select. Default is /1. */
   404        config IDEX inputDividerExp = IDEX_1;
   405    
   406        /*! Enable nesting of other interrupts on top of this Timer's ISR? */
   407        config Bool nesting = false;
   408    
   409        /*! Previous threshold count value. */
   410        config UInt prevThreshold = 0;
   411    
   412        /*! Control register configuration. Default source = ACLK. */
   413        config UInt controlRegInit = Source_ACLK;
   414    
   415        /*!
   416         *  ======== reconfig ========
   417         *  Modify timer instances at runtime
   418         *
   419         *  @param(timerParams)     timer Params
   420         *  @param(tickFxn)         function that runs when timer expires.
   421         */
   422        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   423    
   424    
   425    internal:   /* not for client use */
   426    
   427        /*!
   428         *  ======== noStartupNeeded ========
   429         *  Flag used to prevent misc code from being brought in
   430         *  un-necessarily
   431         */
   432        config UInt startupNeeded = false;
   433    
   434        /*
   435         *  ======== initDevice ========
   436         *  reset timer to its resting state
   437         */
   438        Void initDevice(Object *timer);
   439    
   440        /*
   441         *  ======== postInit ========
   442         *  finish initializing static and dynamic Timers
   443         */
   444        Int postInit(Object *timer, Error.Block *eb);
   445    
   446        /*
   447         *  ======== checkOverflow ========
   448         */
   449        Bool checkOverflow(UInt32 a, UInt32 b);
   450    
   451        /*! Information about timer */
   452        struct TimerDevice {
   453            UInt intNum;
   454            Ptr  baseAddr;
   455        };
   456    
   457        /*!
   458         *  ======== numTimerDevices ========
   459         *  The number of physical timers on the device
   460         */
   461        config Int numTimerDevices;
   462    
   463        struct Instance_State {
   464            Bool                    staticInst;
   465            Int                     id;
   466            UInt                    controlRegInit;
   467            ITimer.RunMode          runMode;
   468            ITimer.StartMode        startMode;
   469            UInt                    period;
   470            ITimer.PeriodType       periodType;
   471            UInt                    intNum;
   472            UArg                    arg;
   473            Hwi.FuncPtr             tickFxn;
   474            Types.FreqHz            frequency;
   475            Hwi.Handle              hwi;
   476            UInt                    prevThreshold;
   477            UInt                    savedCurrCount;
   478            UInt32                  rollovers;
   479            Bool                    synchronous;
   480            UInt                    inputDivider;
   481            UInt                    inputDividerExp;
   482        }
   483    
   484        struct Module_State {
   485            UInt            availMask;      /* available peripherals */
   486            TimerDevice     device[];       /* timer device information */
   487            Handle          handles[];      /* array of handles based on id */
   488        }
   489    }