1    /*
     2     * Copyright (c) 2013, 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.arm.m3;
    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    /*!
    48     *  ======== Timer ========
    49     *  Cortex M3 Timer Peripherals Manager.
    50     *
    51     *  The Cortex M3 Timer Manager utilizes the M3's internal NVIC SysTick Timer.
    52     *  The SysTick timer is clocked at the CPU clock rate, nominally 200MHz.
    53     *  The SysTick timer has only 24 bits of period resolution and is therefore
    54     *  limited to a maximum period of 83ms.
    55     *
    56     *
    57     *  @p(html)
    58     *  <h3> Calling Context </h3>
    59     *  <table border="1" cellpadding="3">
    60     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    61     *
    62     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    63     *    <!--                                                                                                                 -->
    64     *    <tr><td> {@link #getNumTimers}            </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    65     *    <tr><td> {@link #getStatus}               </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    66     *    <tr><td> {@link #Params_init}             </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    67     *    <tr><td> {@link #construct}               </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    68     *    <tr><td> {@link #create}                  </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    69     *    <tr><td> {@link #delete}                  </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    70     *    <tr><td> {@link #destruct}                </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    71     *    <tr><td> {@link #getCount}                </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    72     *    <tr><td> {@link #getFreq}                 </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    73     *    <tr><td> {@link #getPeriod}               </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    74     *    <tr><td> {@link #reconfig}                </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    75     *    <tr><td> {@link #setPeriod}               </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    76     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    77     *    <tr><td> {@link #start}                   </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    78     *    <tr><td> {@link #stop}                    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td><td>   -    </td></tr>
    79     *    <tr><td colspan="6"> Definitions: <br />
    80     *       <ul>
    81     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    82     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    83     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    84     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    85     *           <ul>
    86     *             <li> In your module startup after this module is started (e.g. Cache_Module_startupDone() returns TRUE). </li>
    87     *             <li> During xdc.runtime.Startup.lastFxns. </li>
    88     *             <li> During main().</li>
    89     *             <li> During BIOS.startupFxns.</li>
    90     *           </ul>
    91     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
    92     *           <ul>
    93     *             <li> During xdc.runtime.Startup.firstFxns.</li>
    94     *             <li> In your module startup before this module is started (e.g. Cache_Module_startupDone() returns FALSE).</li>
    95     *           </ul>
    96     *       </ul>
    97     *    </td></tr>
    98     *
    99     *  </table>
   100     *  @p
   101     */
   102    @ModuleStartup          /* to configure static timers */
   103    @InstanceInitStatic
   104    
   105    module Timer inherits ti.sysbios.interfaces.ITimer
   106    {
   107        /*! Max value of Timer period for PeriodType_COUNTS */
   108        const UInt MAX_PERIOD = 0x00ffffff;
   109    
   110        /*! Number of timer peripherals on chip */
   111        const Int NUM_TIMER_DEVICES = 1;
   112    
   113        /*! Timer clock divider wrt cpu clock */
   114        const Int TIMER_CLOCK_DIVIDER = 1;
   115    
   116        /*! @_nodoc
   117         *  Min instructions to use in trigger().
   118         */
   119        const Int MIN_SWEEP_PERIOD = 1;
   120    
   121        /*! @_nodoc */
   122        @XmlDtd
   123        metaonly struct BasicView {
   124            Ptr         halTimerHandle;
   125            String      label;
   126            UInt        id;
   127            String      device;
   128            String      startMode;
   129            String      runMode;
   130            UInt        period;
   131            String      periodType;
   132            UInt        intNum;
   133            String      tickFxn[];
   134            UArg        arg;
   135            String      extFreq;
   136            String      hwiHandle;
   137        };
   138    
   139    
   140        /*! @_nodoc */
   141        metaonly struct ModuleView {
   142            String      availMask;
   143            UInt        tickCount;
   144        }
   145    
   146        /*! @_nodoc */
   147        metaonly struct DeviceView {
   148            UInt        id;
   149            String      device;
   150            String      devAddr;
   151            UInt        intNum;
   152            String      runMode;
   153            UInt        period;
   154            UInt        currCount;
   155            UInt        remainingCount;
   156        };
   157    
   158        /*! @_nodoc */
   159        @Facet
   160        metaonly config ViewInfo.Instance rovViewInfo =
   161            ViewInfo.create({
   162                viewMap: [
   163                [
   164                    'Basic',
   165                    {
   166                        type: ViewInfo.INSTANCE,
   167                        viewInitFxn: 'viewInitBasic',
   168                        structName: 'BasicView'
   169                    }
   170                ],
   171                [
   172                    'Device',
   173                    {
   174                        type: ViewInfo.INSTANCE,
   175                        viewInitFxn: 'viewInitDevice',
   176                        structName: 'DeviceView'
   177                    }
   178                ],
   179                [
   180                    'Module',
   181                    {
   182                        type: ViewInfo.MODULE,
   183                        viewInitFxn: 'viewInitModule',
   184                        structName: 'ModuleView'
   185                    }
   186                ],
   187                ]
   188            });
   189        /*!
   190    
   191         *  Error raised when timer id specified is not supported.
   192         */
   193        config Error.Id E_invalidTimer  = {msg: "E_invalidTimer: Invalid Timer Id %d"};
   194    
   195        /*!
   196         *  Error raised when timer requested is in use
   197         */
   198        config Error.Id E_notAvailable  =
   199            {msg: "E_notAvailable: Timer not available %d"};
   200    
   201        /*!
   202         *  Error raised when period requested is not supported
   203         */
   204        config Error.Id E_cannotSupport  =
   205            {msg: "E_cannotSupport: Timer cannot support requested period %d"};
   206    
   207        /*!
   208         *  ======== anyMask ========
   209         *  Available mask to be used when select = Timer_ANY
   210         */
   211        config UInt anyMask = 0x1;
   212    
   213        /*!
   214         *  ======== getHandle ========
   215         *  @_nodoc
   216         *  Used by TimestampProvider module to get hold of timer handle.
   217         *
   218         *  @param(id)      timer Id.
   219         */
   220        Handle getHandle(UInt id);
   221    
   222        /*!
   223         *  ======== getTickCount ========
   224         *  @_nodoc
   225         *  Used by TimestampProvider.
   226         */
   227        UInt32 getTickCount();
   228    
   229    instance:
   230    
   231        /*! Hwi Params for Hwi Object. Default is null. */
   232        config Hwi.Params *hwiParams = null;
   233    
   234        /*!
   235         *  ======== reconfig ========
   236         *  Used to modify static timer instances at runtime.
   237         *
   238         *  @param(timerParams)     timer Params
   239         *  @param(tickFxn)         function that runs when timer expires
   240         */
   241        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   242    
   243    
   244    internal:   /* not for client use */
   245    
   246        metaonly config Bool timerInUse = false;
   247    
   248        /*
   249         *  ======== initDevice ========
   250         *  reset timer to its resting state
   251         */
   252        Void initDevice(Object *timer);
   253    
   254        /*
   255         *  ======== postInit ========
   256         *  finish initializing static and dynamic Timers
   257         */
   258        Int postInit(Object *timer, Error.Block *eb);
   259    
   260        /*!
   261         *  ======== oneShotStub ========
   262         *  SysTick timer does not support one shot mode. This stub stops timer
   263         *  and clears the pending timer interrupt.
   264         *
   265         *  @param(arg)     Timer object.
   266         */
   267        Void oneShotStub(UArg arg);
   268    
   269        /*!
   270         *  ======== periodicStub ========
   271         *  SysTick timer interrupt must be acknowledged. This stub acknowledges timer
   272         *
   273         *  @param(arg)     Timer object.
   274         */
   275        Void periodicStub(UArg arg);
   276    
   277        /*!
   278         *  ======== noStartupNeeded ========
   279         *  Flag used to prevent misc code from being brought in
   280         *  un-necessarily
   281         */
   282        config UInt startupNeeded = false;
   283    
   284        struct Instance_State {
   285            Bool            staticInst;
   286            Int             id;
   287            RunMode         runMode;
   288            StartMode       startMode;
   289            UInt            period;
   290            PeriodType      periodType;
   291            UInt            intNum;
   292            UArg            arg;
   293            Hwi.FuncPtr     tickFxn;
   294            Types.FreqHz    extFreq;        /* external frequency in Hz */
   295            Hwi.Handle      hwi;
   296        }
   297    
   298        struct Module_State {
   299            volatile UInt   tickCount;      /* SysTick Rollover counter */
   300            UInt            availMask;      /* available peripherals */
   301            Handle          handle;         /* NVIC timer handle */
   302        }
   303    }
   304