1    /*
     2     * Copyright (c) 2019, 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.v8m.mtl;
    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    import ti.sysbios.family.arm.v8m.Hwi;
    46    
    47    /*!
    48     *  ======== Timer ========
    49     *  MTL Timer Peripheral Manager
    50     *
    51     *  This Timer module manages the SystemTimer peripheral on MTL devices.
    52     *
    53     *  @p(html)
    54     *  <h3> Calling Context </h3>
    55     *  <table border="1" cellpadding="3">
    56     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    57     *  </colgroup>
    58     *
    59     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    60     *  <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    61     *    <!--                                                          -->
    62     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
    63     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    64     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
    65     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    66     *    <tr><td> {@link #Params_init}             </td><td>   N    </td>
    67     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    68     *    <tr><td> {@link #construct}               </td><td>   N    </td>
    69     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    70     *    <tr><td> {@link #create}                  </td><td>   N    </td>
    71     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    72     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
    73     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    74     *    <tr><td> {@link #destruct}                </td><td>   N    </td>
    75     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    76     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
    77     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    78     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
    79     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    80     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
    81     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    82     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
    83     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
    85     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
    87     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    88     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
    89     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    90     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
    91     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    92     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
    93     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    94     *    <tr><td colspan="6"> Definitions: <br />
    95     *       <ul>
    96     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    97     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    98     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    99     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   100     *           <ul>
   101     *             <li> In your module startup after this module is started
   102     *  (e.g. Timer_Module_startupDone() returns TRUE). </li>
   103     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   104     *             <li> During main().</li>
   105     *             <li> During BIOS.startupFxns.</li>
   106     *           </ul>
   107     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   108     *           <ul>
   109     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   110     *             <li> In your module startup before this module is started
   111     *  (e.g. Timer_Module_startupDone() returns FALSE).</li>
   112     *           </ul>
   113     *       </ul>
   114     *    </td></tr>
   115     *
   116     *  </table>
   117     *  @p
   118     */
   119    @ModuleStartup          /* To configure static timers */
   120    @InstanceInitStatic
   121    
   122    module Timer inherits ti.sysbios.interfaces.ITimer
   123    {
   124        /*! initially this Timer does not support RunMode_DYNAMIC */
   125        override metaonly config Bool supportsDynamic = false;
   126    
   127        /*! use RunMode_PERIODIC by default */
   128        override metaonly config Bool defaultDynamic = false;
   129    
   130        // -------- Module Types --------
   131    
   132        /*! Max value of Timer period for PeriodType_COUNTS */
   133        const UInt MAX_PERIOD = 0xFFFFFFFF;
   134    
   135        /*! @_nodoc
   136         *  Min instructions to use in trigger().
   137         */
   138        const Int MIN_SWEEP_PERIOD = 1;
   139    
   140        /*! @_nodoc */
   141        @XmlDtd
   142        metaonly struct BasicView {
   143            Ptr         halTimerHandle;
   144            String      label;
   145            UInt        id;
   146            UInt        channelId;
   147            String      startMode;
   148            String      runMode;
   149            UInt        period;
   150            String      periodType;
   151            UInt        intNum;
   152            String      tickFxn[];
   153            UArg        arg;
   154            String      hwiHandle;
   155        };
   156    
   157        /*! @_nodoc */
   158        metaonly struct DeviceView {
   159            UInt        id;
   160            UInt        channelId;
   161            String      device;
   162            String      devAddr;
   163            UInt        intNum;
   164            String      runMode;
   165            UInt32      period;
   166            UInt32      currCount;
   167            UInt32      remainingCount;
   168            UInt32      prevThreshold;
   169            UInt32      nextThreshold;
   170            String      state;
   171        };
   172    
   173        /*! @_nodoc */
   174        metaonly struct ModuleView {
   175            String      availMask;
   176        }
   177    
   178        /*! @_nodoc */
   179        @Facet
   180        metaonly config ViewInfo.Instance rovViewInfo =
   181            ViewInfo.create({
   182                viewMap: [
   183                [
   184                    'Basic',
   185                    {
   186                        type: ViewInfo.INSTANCE,
   187                        viewInitFxn: 'viewInitBasic',
   188                        structName: 'BasicView'
   189                    }
   190                ],
   191                [
   192                    'Device',
   193                    {
   194                        type: ViewInfo.INSTANCE,
   195                        viewInitFxn: 'viewInitDevice',
   196                        structName: 'DeviceView'
   197                    }
   198                ],
   199                [
   200                    'Module',
   201                    {
   202                        type: ViewInfo.MODULE,
   203                        viewInitFxn: 'viewInitModule',
   204                        structName: 'ModuleView'
   205                    }
   206                ],
   207                ]
   208            });
   209    
   210        /*!
   211         *  ======== E_invalidTimer ========
   212         *  Error raised when specified timer id is not supported
   213         */
   214        config Error.Id E_invalidTimer = {
   215            msg: "E_invalidTimer: Invalid Timer Id %d"
   216        };
   217    
   218        /*!
   219         *  ======== E_notAvailable ========
   220         *  Error raised when requested timer is in use
   221         */
   222        config Error.Id E_notAvailable = {
   223            msg: "E_notAvailable: Timer not available %d"
   224        };
   225    
   226        /*!
   227         *  ======== E_cannotSupport ========
   228         *  Error raised when requested period is not supported
   229         */
   230        config Error.Id E_cannotSupport = {
   231            msg: "E_cannotSupport: Timer cannot support requested period %d"
   232        };
   233    
   234        /*!
   235         *  ======== anyMask ========
   236         *  Mask of available timers
   237         *
   238         *  This mask is used to identify the timers that can be used when
   239         *  Timer_create() is called with an id equal to
   240         *  {@link Timer#ANY Timer_ANY}.
   241         */
   242        config UInt anyMask = 0x3;
   243    
   244        /*!
   245         *  ======== stopFreeRun ========
   246         *  @_nodoc
   247         *  Stop timer during debug halt.
   248         */
   249        config Bool stopFreeRun = true;
   250    
   251        /*!
   252         *  ======== getAvailMask ========
   253         *  Returns the availMask.
   254         *
   255         *  @b(returns)     Mask of available timers
   256         */
   257        UInt getAvailMask();
   258    
   259        /*!
   260         *  ======== oneShotStub ========
   261         *  @_nodoc
   262         *
   263         *  @param(arg)     Unused.
   264         */
   265        Void oneShotStub(UArg arg);
   266    
   267        /*!
   268         *  ======== periodicStub ========
   269         *  @_nodoc
   270         *
   271         *  @param(arg)     Unused.
   272         */
   273        Void periodicStub(UArg arg);
   274    
   275        /*!
   276         *  ======== setAvailMask ========
   277         *  Set the availMask to given mask.
   278         *
   279         *  This function validates the given mask to ensure it does not mark
   280         *  any currently used timer as available. If validation is successful,
   281         *  the mask overwrites the current availMask and the function returns
   282         *  TRUE. Otherwise, the mask is discarded and the function returns
   283         *  FALSE.
   284         *
   285         *  @param(mask)    Mask used to write to availMask
   286         */
   287        Bool setAvailMask(UInt mask);
   288    
   289        /*!
   290         *  ======== getHandle ========
   291         *  @_nodoc
   292         *  Used by TimestampProvider module to get hold of timer handle used by
   293         *  Clock.
   294         *
   295         *  @param(id)      timer Id.
   296         */
   297        Handle getHandle(UInt id);
   298    
   299    instance:
   300    
   301        /*! Hwi Params for Hwi Object. Default is null. */
   302        config Hwi.Params *hwiParams = null;
   303        
   304    internal:   /* not for client use */
   305    
   306        /*!
   307         *  ======== noStartupNeeded ========
   308         *  Flag used to prevent misc code from being brought in
   309         *  un-necessarily
   310         */
   311        config UInt startupNeeded = false;
   312    
   313        /*
   314         *  ======== initDevice ========
   315         *  reset timer to its resting state
   316         */
   317        Void initDevice(Object *timer);
   318    
   319        /*
   320         *  ======== postInit ========
   321         *  finish initializing static Timers
   322         */
   323        Int postInit(Object *timer, Error.Block *eb);
   324    
   325        /*
   326         *  ======== setThreshold ========
   327         *  set the compare threshold in RTC register
   328         */
   329        Void setThreshold(Object *timer, UInt32 next, Bool wrap);
   330    
   331        /*! Information about timer */
   332        struct TimerDevice {
   333            UInt intNum;
   334            UInt channelId;
   335        };
   336    
   337        /*!
   338         *  ======== numTimerDevices ========
   339         *  The number of physical timers on the device
   340         */
   341        config Int numTimerDevices;
   342    
   343        struct Instance_State {
   344            Bool                    staticInst;
   345            Int                     id;
   346            UInt32                  channelId;
   347            RunMode                 runMode;
   348            ITimer.StartMode        startMode;
   349            UInt32                  period;
   350            PeriodType              periodType;
   351            UInt                    intNum;
   352            UArg                    arg;
   353            Hwi.FuncPtr             tickFxn;
   354            Types.FreqHz            extFreq;
   355            Hwi.Handle              hwi;
   356            UInt32                  savedCurrCount;
   357            UInt32                  prevThreshold;
   358            UInt32                  nextThreshold;
   359        }
   360    
   361        struct Module_State {
   362            UInt            availMask;      /* available peripherals */
   363            TimerDevice     device[];       /* timer device info */
   364            Handle          handles[];      /* array of handles based on id */
   365        }
   366    }