1    /*
     2     * Copyright (c) 2014-2017, 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.cc26xx;
    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    
    47    /*!
    48     *  ======== Timer ========
    49     *  CC26xx Timer Peripheral Manager
    50     *
    51     *  This Timer module manages the RTC timer peripheral on
    52     *  CC26XX/CC13XX devices.  This Timer operates in a dynamic tick mode
    53     *  (RunMode_DYNAMIC). Rather than interrupting on every fixed tick period,
    54     *  the Timer is dynamically reprogrammed to interrupt on the next required
    55     *  tick (as determined by work that has been scheduled with a future timeout).
    56     *
    57     *  By default, this Timer module is used by the SYS/BIOS
    58     *  {@link ti.sysbios.knl.Clock Clock} module for implementing timing services
    59     *  on CC26XX/CC13XX devices.  Operating in dynamic mode allows the Clock module
    60     *  to implement dynamic tick suppression, to reduce the number of interrupts
    61     *  from the timer, to the minimum required for any scheduled work.
    62     *
    63     *  The RTC peripheral is implemented as a 64-bit counter, with the upper
    64     *  32-bits of count representing seconds, and the lower 32-bits representing
    65     *  sub-seconds.  Three timer "channels" are provided for generating time match
    66     *  interrupt events.  The match compare value for each channel is a 32-bit
    67     *  value, spanning the lower 16-bits of the RTC seconds count, and the upper
    68     *  16-bits of the subsecond count.  There is a single interrupt line from the
    69     *  RTC to generate a CPU interrupt, for a match event occurring on any
    70     *  of these three channels.
    71     *
    72     *  Channel 0 of the RTC is dedicated to use by the Clock module.  This Timer
    73     *  module implementation is therefore responsible for overall management of
    74     *  the RTC, including resetting and starting the RTC during application boot,
    75     *  and providing the single interrupt service routine (ISR) for the RTC.
    76     *
    77     *  Channels 1 and 2 of the RTC are not used by the Clock module.  These
    78     *  channels may be available for use by some applications, depending upon the
    79     *  mix of software components being used.  For this purpose, this Timer
    80     *  module supports sharing of the RTC interrupt, to support usage
    81     *  of these other channels (in parallel with the usage of Channel 0 by the
    82     *  Clock module).
    83     *
    84     *  To use one of these other channels the application will need to explicitly
    85     *  configure an interrupt "hook" function for the channel. In this case, when
    86     *  an RTC interrupt triggers the ISR will check the status of each channel to
    87     *  see if the corresponding channel hook function should be called.
    88     *
    89     *  The time match values for Channel 0 will be automatically programmed by
    90     *  the Clock module.  To use Channels 1 (and/or Channel 2), the application
    91     *  will need to explicitly program the match value for the corresponding
    92     *  channel, for the desired time for the interrupt.  Also, the application
    93     *  will need to explicitly enable the additional channel(s).  Note that if a
    94     *  hook function is configured for Channel 1 or Channel 2, the corresponding
    95     *  events will be configured automatically when Channel 0 is started.  In
    96     *  other words, there is no need for the application to explicitly configure
    97     *  events for Channel 1 or Channel 2 by calling AONRTCCombinedEventConfig().
    98     *
    99     *  The below snippets show an example of using Channel 1, with Driverlib API
   100     *  calls to configure an RTC event at 4 seconds after boot.
   101     *
   102     *  First, in the application .cfg file a hook function is defined for
   103     *  Channel 1:
   104     *
   105     *  @p(code)
   106     *    var Timer = xdc.module('ti.sysbios.family.arm.cc26xx.Timer');
   107     *    Timer.funcHookCH1 = "&myHookCH1";
   108     *  @p
   109     *
   110     *  In main(), Channel 1 is first cleared, a compare (match) value of 4 seconds
   111     *  is set, the channel is enabled:
   112     *
   113     *  @p(code)
   114     *    AONRTCEventClear(AON_RTC_CH1);
   115     *    AONRTCCompareValueSet(AON_RTC_CH1, 0x40000);
   116     *    AONRTCChannelEnable(AON_RTC_CH1);
   117     *  @p
   118     *
   119     *  With the above, myHookCH1() will be called when the RTC reaches a count of
   120     *  4 seconds.  At that time, a new compare value can be written for the next
   121     *  interrupt that should occur for Channel 1.
   122     *
   123     *  @p(html)
   124     *  <h3> Calling Context </h3>
   125     *  <table border="1" cellpadding="3">
   126     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   127     *  </colgroup>
   128     *
   129     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
   130     *  <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   131     *    <!--                                                          -->
   132     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
   133     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   134     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
   135     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   136     *    <tr><td> {@link #Params_init}             </td><td>   N    </td>
   137     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   138     *    <tr><td> {@link #construct}               </td><td>   N    </td>
   139     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   140     *    <tr><td> {@link #create}                  </td><td>   N    </td>
   141     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   142     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
   143     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   144     *    <tr><td> {@link #destruct}                </td><td>   N    </td>
   145     *  <td>   N    </td><td>   N    </td><td>   N    </td><td>   N    </td></tr>
   146     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
   147     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   148     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
   149     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   150     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
   151     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   152     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
   153     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   154     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   155     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   156     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   157     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   158     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   159     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   160     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   161     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   162     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   163     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   164     *    <tr><td colspan="6"> Definitions: <br />
   165     *       <ul>
   166     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   167     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   168     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   169     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   170     *           <ul>
   171     *             <li> In your module startup after this module is started
   172     *  (e.g. Timer_Module_startupDone() returns TRUE). </li>
   173     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   174     *             <li> During main().</li>
   175     *             <li> During BIOS.startupFxns.</li>
   176     *           </ul>
   177     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   178     *           <ul>
   179     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   180     *             <li> In your module startup before this module is started
   181     *  (e.g. Timer_Module_startupDone() returns FALSE).</li>
   182     *           </ul>
   183     *       </ul>
   184     *    </td></tr>
   185     *
   186     *  </table>
   187     *  @p
   188     */
   189    @ModuleStartup          /* To configure static timers */
   190    @InstanceInitStatic
   191    
   192    module Timer inherits ti.sysbios.interfaces.ITimer
   193    {
   194        /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
   195        override metaonly config Bool supportsDynamic = true;
   196    
   197        /*! override defaultMode - use RunMode_PERIODIC by default */
   198        override metaonly config Bool defaultDynamic = true;
   199    
   200        // -------- Module Types --------
   201    
   202        /*! Max value of Timer period for PeriodType_COUNTS */
   203        const UInt MAX_PERIOD = 0xFFFFFFFF;
   204    
   205        /*! @_nodoc
   206         *  Min instructions to use in trigger().
   207         */
   208        const Int MIN_SWEEP_PERIOD = 1;
   209    
   210        /*! @_nodoc */
   211        @XmlDtd
   212        metaonly struct BasicView {
   213            Ptr         halTimerHandle;
   214            String      label;
   215            UInt        id;
   216            String      startMode;
   217            String      tickFxn[];
   218            UArg        arg;
   219            String      hwiHandle;
   220        };
   221    
   222        /*! @_nodoc */
   223        metaonly struct DeviceView {
   224            UInt        id;
   225            String      device;
   226            String      devAddr;
   227            UInt        intNum;
   228            UInt32      currCount;
   229            UInt32      nextCompareCount;
   230            UInt32      remainingCount;
   231            String      state;
   232        };
   233    
   234        /*! @_nodoc */
   235        metaonly struct ModuleView {
   236            String      availMask;
   237        }
   238    
   239        /*! @_nodoc */
   240        @Facet
   241        metaonly config ViewInfo.Instance rovViewInfo =
   242            ViewInfo.create({
   243                viewMap: [
   244                [
   245                    'Basic',
   246                    {
   247                        type: ViewInfo.INSTANCE,
   248                        viewInitFxn: 'viewInitBasic',
   249                        structName: 'BasicView'
   250                    }
   251                ],
   252                [
   253                    'Device',
   254                    {
   255                        type: ViewInfo.INSTANCE,
   256                        viewInitFxn: 'viewInitDevice',
   257                        structName: 'DeviceView'
   258                    }
   259                ],
   260                [
   261                    'Module',
   262                    {
   263                        type: ViewInfo.MODULE,
   264                        viewInitFxn: 'viewInitModule',
   265                        structName: 'ModuleView'
   266                    }
   267                ],
   268                ]
   269            });
   270    
   271        /*!
   272         *  ======== E_invalidTimer ========
   273         *  Error raised when specified timer id is not supported
   274         */
   275        config Error.Id E_invalidTimer = {
   276            msg: "E_invalidTimer: Invalid Timer Id %d"
   277        };
   278    
   279        /*!
   280         *  ======== E_notAvailable ========
   281         *  Error raised when requested timer is in use
   282         */
   283        config Error.Id E_notAvailable = {
   284            msg: "E_notAvailable: Timer not available %d"
   285        };
   286    
   287        /*!
   288         *  ======== E_cannotSupport ========
   289         *  Error raised when requested period is not supported
   290         */
   291        config Error.Id E_cannotSupport = {
   292            msg: "E_cannotSupport: Timer cannot support requested period %d"
   293        };
   294    
   295        /*!
   296         *  ======== anyMask ========
   297         *  Mask of available timers
   298         *
   299         *  This mask is used to identify the timers that can be used when
   300         *  Timer_create() is called with an id equal to
   301         *  {@link Timer#ANY Timer_ANY}.
   302         */
   303        config UInt anyMask = 0x1;
   304    
   305        /*!
   306         *  ======== funcHookCH1 ========
   307         *  Optional hook function for processing RTC channel 1 events
   308         *
   309         *  This function will be called when there is a timeout event on
   310         *  RTC Channel 1.  It will be called from hardware interrupt context,
   311         *  so any API calls from this function must be appropriate for
   312         *  execution from an ISR.
   313         *
   314         *  Function hooks are only supported with RunMode_DYNAMIC.
   315         */
   316        config FuncPtr funcHookCH1 = null;
   317    
   318        /*!
   319         *  ======== funcHookCH2 ========
   320         *  Optional hook function for processing RTC channel 2 events.
   321         *
   322         *  This function will be called when there is a timeout event on
   323         *  RTC Channel 2.  It will be called from hardware interrupt context,
   324         *  so any API calls from this function must be appropriate for
   325         *  execution from an ISR.
   326         *
   327         *  Function hooks are only supported with RunMode_DYNAMIC.
   328         */
   329        config FuncPtr funcHookCH2 = null;
   330    
   331        /*!
   332         *  ======== dynamicStub ========
   333         *  @_nodoc
   334         *
   335         *  @param(arg)     Unused.
   336         */
   337        Void dynamicStub(UArg arg);
   338    
   339        /*!
   340         *  ======== dynamicMultiStub ========
   341         *  @_nodoc
   342         *
   343         *  @param(arg)     Unused.
   344         */
   345        Void dynamicMultiStub(UArg arg);
   346    
   347        /*!
   348         *  ======== periodicStub ========
   349         *  @_nodoc
   350         *
   351         *  @param(arg)     Unused.
   352         */
   353        Void periodicStub(UArg arg);
   354    
   355       /*!
   356         *  ======== getCount64 ========
   357         *  Read the 64-bit timer counter register
   358         *
   359         *  @b(returns)     timer counter value
   360         */
   361        UInt64 getCount64(Object * timer);
   362    
   363       /*!
   364         *  ======== getExpiredCounts64 ========
   365         *  Returns expired counts (64-bits) since the last serviced interrupt.
   366         *
   367         *  @b(returns)     timer counter value
   368         */
   369        UInt64 getExpiredCounts64(Object * timer);
   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    instance:
   382    
   383        /*! Hwi Params for Hwi Object. Default is null. */
   384        config Hwi.Params *hwiParams = null;
   385        
   386    internal:   /* not for client use */
   387    
   388        /*!
   389         *  ======== noStartupNeeded ========
   390         *  Flag used to prevent misc code from being brought in
   391         *  un-necessarily
   392         */
   393        config UInt startupNeeded = false;
   394    
   395        /*
   396         *  ======== initDevice ========
   397         *  reset timer to its resting state
   398         */
   399        Void initDevice(Object *timer);
   400    
   401        /*
   402         *  ======== postInit ========
   403         *  finish initializing static Timers
   404         */
   405        Int postInit(Object *timer, Error.Block *eb);
   406    
   407        /*
   408         *  ======== setThreshold ========
   409         *  set the compare threshold in RTC register
   410         */
   411        Void setThreshold(Object *timer, UInt32 next, Bool wrap);
   412    
   413        struct Instance_State {
   414            Bool                    staticInst;
   415            Int                     id;
   416            ITimer.StartMode        startMode;
   417            UInt32                  period;
   418            UArg                    arg;
   419            Hwi.FuncPtr             tickFxn;
   420            Types.FreqHz            frequency;
   421            Hwi.Handle              hwi;
   422            UInt64                  period64;
   423            UInt64                  savedCurrCount;
   424            UInt64                  prevThreshold;
   425            UInt64                  nextThreshold;
   426        }
   427    
   428        struct Module_State {
   429            UInt            availMask;      /* available peripherals */
   430            Handle          handle;     /* array of handles based on id */
   431        }
   432    }