1    /*
     2     * Copyright (c) 2014-2015, 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.cc32xx;
    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.m3.Hwi;
    46    import ti.sysbios.knl.Clock;
    47    
    48    /*!
    49     *  ======== Timer ========
    50     *  CC3200 Timer Peripheral Manager
    51     *
    52     *  This module manages the 32Khz RTC timer available on CC3200 devices.
    53     *  The RTC timer uses 2 32-bit words, with the upper 16 bits of the MSW
    54     *  reserved, resulting in a 48-bit counter.
    55     *
    56     *  The Timer module supports the timer in 'one shot', 'continuous', and
    57     *  'dynamic' modes.
    58     *
    59     *  In 'one shot' mode, a timer function will "fire" (run) when the timer
    60     *  period expires. In 'one shot' mode this will only happen once.
    61     *
    62     *  In 'continuous' mode, the specified timer function will "fire" every
    63     *  time the period expires, throughout the lifetime of the program.
    64     *
    65     *  In 'dynamic' mode, the specified timer function will "fire" every
    66     *  time the period expires.  But the period of the timer can be changed
    67     *  dynamically, to correspond to the next tick interrupt needed from the
    68     *  timer.  This mode is used by the SYS/BIOS
    69     *  {@link ti.sysbios.knl.Clock Clock} module for implementing
    70     *  dynamic tick suppression, to reduce the number of interrupts from the
    71     *  timer to the minimum required for currently scheduled timeouts.
    72     *
    73     *  @a(Warning)
    74     *  Some of the RTC timer registers are accessed from the 32KHz clock
    75     *  domain, making reads/writes to these registers on the order of 100
    76     *  microseconds.
    77     *  If using the RTC timer for the {@link ti.sysbios.knl.Clock Clock}
    78     *  module's tick source, the interrupt latency will be as high as 200
    79     *  microseconds, as the {@link ti.sysbios.knl.Clock Clock} ISR makes two
    80     *  RTC register accesses on the 32KHz clock domain.
    81     *
    82     *  @p(html)
    83     *  <h3> Calling Context </h3>
    84     *  <table border="1" cellpadding="3">
    85     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    86     *  </colgroup>
    87     *
    88     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    89     *  <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    90     *    <!--                                                          -->
    91     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
    92     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    93     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
    94     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    95     *    <tr><td> {@link #Params_init}             </td><td>   N    </td>
    96     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    97     *    <tr><td> {@link #construct}               </td><td>   N    </td>
    98     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
    99     *    <tr><td> {@link #create}                  </td><td>   N    </td>
   100     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   101     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
   102     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   103     *    <tr><td> {@link #destruct}                </td><td>   N    </td>
   104     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   105     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
   106     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   107     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
   108     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   109     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
   110     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   111     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
   112     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   113     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   114     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   115     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   116     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   117     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   118     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   119     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   120     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   121     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   122     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   123     *    <tr><td colspan="6"> Definitions: <br />
   124     *       <ul>
   125     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   126     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   127     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   128     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   129     *           <ul>
   130     *             <li> In your module startup after this module is started
   131     *  (e.g. Timer_Module_startupDone() returns TRUE). </li>
   132     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   133     *             <li> During main().</li>
   134     *             <li> During BIOS.startupFxns.</li>
   135     *           </ul>
   136     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   137     *           <ul>
   138     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   139     *             <li> In your module startup before this module is started
   140     *  (e.g. Timer_Module_startupDone() returns FALSE).</li>
   141     *           </ul>
   142     *       </ul>
   143     *    </td></tr>
   144     *
   145     *  </table>
   146     *  @p
   147     */
   148    @ModuleStartup          /* To configure static timers */
   149    @InstanceInitStatic
   150    
   151    module Timer inherits ti.sysbios.interfaces.ITimer
   152    {
   153        /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
   154        override metaonly config Bool supportsDynamic = true;
   155    
   156        /*! override defaultMode - use RunMode_PERIODIC by default */
   157        override metaonly config Bool defaultDynamic = true;
   158    
   159        /*! Max value of Timer period for PeriodType_COUNTS */
   160        const UInt64 MAX_PERIOD = 0xFFFFFFFFFFFF;
   161    
   162    
   163        /*! @_nodoc */
   164        @XmlDtd
   165        metaonly struct BasicView {
   166            Ptr         halTimerHandle;
   167            String      label;
   168            UInt        id;
   169            String      startMode;
   170            UInt64      period;
   171            String      tickFxn[];
   172            UArg        arg;
   173            String      hwiHandle;
   174        };
   175    
   176        /*! @_nodoc */
   177        metaonly struct DeviceView {
   178            UInt        id;
   179            String      device;
   180            String      devAddr;
   181            UInt        intNum;
   182            UInt64      period64;
   183            UInt        currCount;
   184            UInt        remainingCount;
   185            UInt64      nextThreshold;
   186            String      state;
   187        };
   188    
   189        /*! @_nodoc */
   190        metaonly struct ModuleView {
   191            String      availMask;
   192        }
   193    
   194        /*! @_nodoc */
   195        @Facet
   196        metaonly config ViewInfo.Instance rovViewInfo =
   197            ViewInfo.create({
   198                viewMap: [
   199                [
   200                    'Basic',
   201                    {
   202                        type: ViewInfo.INSTANCE,
   203                        viewInitFxn: 'viewInitBasic',
   204                        structName: 'BasicView'
   205                    }
   206                ],
   207                [
   208                    'Device',
   209                    {
   210                        type: ViewInfo.INSTANCE,
   211                        viewInitFxn: 'viewInitDevice',
   212                        structName: 'DeviceView'
   213                    }
   214                ],
   215                [
   216                    'Module',
   217                    {
   218                        type: ViewInfo.MODULE,
   219                        viewInitFxn: 'viewInitModule',
   220                        structName: 'ModuleView'
   221                    }
   222                ],
   223                ]
   224            });
   225    
   226        /*!
   227         *  ======== E_invalidTimer ========
   228         *  Error raised when specified timer id is not supported
   229         */
   230        config Error.Id E_invalidTimer = {
   231            msg: "E_invalidTimer: Invalid Timer Id %d"
   232        };
   233    
   234        /*!
   235         *  ======== E_notAvailable ========
   236         *  Error raised when requested timer is in use
   237         */
   238        config Error.Id E_notAvailable = {
   239            msg: "E_notAvailable: Timer not available %d"
   240        };
   241    
   242        /*!
   243         *  ======== E_cannotSupport ========
   244         *  Error raised when requested period is not supported
   245         */
   246        config Error.Id E_cannotSupport = {
   247            msg: "E_cannotSupport: Timer cannot support requested period %d"
   248        };
   249    
   250        /*!
   251         *  ======== anyMask ========
   252         *  Mask of available timers
   253         *
   254         *  This mask is used to identify the timers that can be used when
   255         *  Timer_create() is called with an id equal to
   256         *  {@link Timer#ANY Timer_ANY}.
   257         */
   258        config UInt anyMask = 0x1;
   259    
   260    
   261        /*!
   262         *  Period of a tick
   263         *
   264         *  The RTC timer can take up to a 48-bit period.
   265         *  (The implementation of ITimer supports a period of UInt32
   266         *  timer counts).
   267         */
   268        config UInt64 period64 = 0;
   269    
   270        /*!
   271         *  ======== dynamicStub ========
   272         *  @_nodoc
   273         *
   274         *  @param(arg)     Unused.
   275         */
   276        Void dynamicStub(UArg arg);
   277    
   278        /*!
   279         *  ======== periodicStub ========
   280         *  @_nodoc
   281         *
   282         *  @param(arg)     Unused.
   283         */
   284        Void periodicStub(UArg arg);
   285    
   286       /*!
   287         *  ======== getCount64 ========
   288         *  Read the 64-bit timer counter register
   289         *
   290         *  @b(returns)     timer counter value
   291         */
   292        UInt64 getCount64(Object * timer);
   293    
   294        /*!
   295         *  ======== getAvailMask ========
   296         *  Returns the availMask.
   297         *
   298         *  @b(returns)     Mask of available timers
   299         */
   300        UInt getAvailMask();
   301    
   302        /*!
   303         *  ======== setAvailMask ========
   304         *  Set the availMask to given mask.
   305         *
   306         *  This function validates the given mask to ensure it does not mark
   307         *  any currently used timer as available. If validation is successful,
   308         *  the mask overwrites the current availMask and the function returns
   309         *  TRUE. Otherwise, the mask is discarded and the function returns
   310         *  FALSE.
   311         *
   312         *  @param(mask)    Mask used to write to availMask
   313         */
   314        Bool setAvailMask(UInt mask);
   315    
   316        /*!
   317         *  ======== getHandle ========
   318         *  @_nodoc
   319         *  Used by TimestampProvider module to get hold of timer handle used by
   320         *  Clock.
   321         *
   322         *  @param(id)      timer Id.
   323         */
   324        Handle getHandle(UInt id);
   325    
   326        /*!
   327         *  ======== setNextMaxTick ========
   328         *  @_nodoc
   329         *  Instead of using maxSkippable, this timer sets the next
   330         *  scheduled tick to the last tick just before the next rollover
   331         *  of the lower 32-bits of the counter.
   332         */
   333        Void setNextMaxTick(UArg arg);
   334    
   335    instance:
   336    
   337        /*! Hwi Params for Hwi Object. Default is null. */
   338        config Hwi.Params *hwiParams = null;
   339    
   340    internal:   /* not for client use */
   341    
   342        /*!
   343         *  ======== noStartupNeeded ========
   344         *  Flag used to prevent misc code from being brought in
   345         *  un-necessarily
   346         */
   347        config UInt startupNeeded = false;
   348    
   349        /*
   350         *  ======== initDevice ========
   351         *  reset timer to its resting state
   352         */
   353        Void initDevice(Object *timer);
   354    
   355        /*
   356         *  ======== postInit ========
   357         *  finish initializing static Timers
   358         */
   359        Int postInit(Object *timer, Error.Block *eb);
   360    
   361        /*
   362         *  ======== setThreshold ========
   363         *  set the compare threshold in RTC register
   364         */
   365        Void setThreshold(Object *timer, UInt64 next);
   366    
   367        struct Instance_State {
   368            Bool                    staticInst;
   369            Int                     id;
   370            ITimer.StartMode        startMode;
   371            UArg                    arg;
   372            Hwi.FuncPtr             tickFxn;
   373            Types.FreqHz            frequency;
   374            Hwi.Handle              hwi;
   375            UInt64                  period64;
   376            UInt64                  savedCurrCount;
   377            UInt64                  nextThreshold;
   378        }
   379    
   380        struct Module_State {
   381            UInt            availMask;  /* available peripherals */
   382            Handle          handle;     /* array of handles based on id */
   383    
   384            /*
   385             *  Clock object for setting the next interrupt to, when nothing else
   386             *  is on the clock queue.
   387             */
   388            Clock.Object    clockObj;
   389    
   390            /*
   391             *  The value of the upper 32 bits of timer counter register
   392             *  at, or a few Clock ticks after the time the Clock object was
   393             *  last started.
   394             */
   395            UInt32          timeUpper;
   396    
   397            /*
   398             *  We need the period for the Clock function.  There is only one
   399             *  timer, and this period will be the same as the Timer object's
   400             *  period.
   401             */
   402            UInt64          period64;
   403        }
   404    }