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    
    38    package ti.sysbios.timers.dmtimer;
    39    
    40    import xdc.rov.ViewInfo;
    41    
    42    import xdc.runtime.Assert;
    43    import xdc.runtime.Error;
    44    import xdc.runtime.Types;
    45    import ti.sysbios.interfaces.ITimer;
    46    import ti.sysbios.hal.Hwi;
    47    
    48    /*!
    49     *  ======== Timer ========
    50     *  Timer Peripheral Manager.
    51     *
    52     *  This Timer module manages the Dual Mode timer (dmtimer) peripherals
    53     *  available on the ARM and C6000 devices (see
    54     *  {@link ./doc-files/TimerTables.html Timer Mapping Tables} for supported
    55     *  device information).
    56     *
    57     *  The dmtimer Timer module supports the timer in 'one shot', 'continuous',
    58     *  and 'dynamic' modes.
    59     *
    60     *  In 'one shot' mode, a timer function will "fire" (run) when the timer period
    61     *  expires (counts up to zero). In 'one shot' mode this will only happen
    62     *  once.  
    63     *
    64     *  In 'continuous' mode, the specified timer function will "fire" every
    65     *  time the period expires, throughout the lifetime of the program.  When the
    66     *  period expires in 'continuous mode', the period is then reset to its
    67     *  original value and then begins counting up to zero again.  At this point
    68     *  the timer function will fire again and the cycle repeats itself.
    69     *
    70     *  In 'dynamic' mode, the specified timer function will "fire" every
    71     *  time the period expires.  But the period of the timer can be changed 
    72     *  dynamically, to correspond to the next tick interrupt needed from the
    73     *  timer.  The timer will continually count upwards, and the timer's compare 
    74     *  mode is used to generate an interrupt when a specific threshold count is
    75     *  reached.  This mode is used by the SYS/BIOS Clock module, for implementing
    76     *  dynamic tick suppression, which reduces the number of interrupts from the 
    77     *  timer to the minimum required for currently scheduled timeouts.
    78     *
    79     *  @p(html)
    80     *  <h3> Calling Context </h3>
    81     *  <table border="1" cellpadding="3">
    82     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    83     *  </colgroup>
    84     *
    85     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    86     *  <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    87     *    <!--                                                          -->
    88     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
    89     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    90     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
    91     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    92     *    <tr><td> {@link #Params_init}             </td><td>   Y    </td>
    93     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    94     *    <tr><td> {@link #construct}               </td><td>   Y    </td>
    95     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    96     *    <tr><td> {@link #create}                  </td><td>   N    </td>
    97     *  <td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    98     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
    99     *  <td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   100     *    <tr><td> {@link #destruct}                </td><td>   Y    </td>
   101     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   102     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
   103     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   104     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
   105     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   106     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
   107     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   108     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
   109     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   110     *    <tr><td> {@link #reconfig}                </td><td>   Y    </td>
   111     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   112     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   113     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   114     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   115     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   116     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   117     *  <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   118     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   119     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   120     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   121     *  <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   122     *    <tr><td colspan="6"> Definitions: <br />
   123     *       <ul>
   124     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   125     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   126     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   127     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   128     *           <ul>
   129     *             <li> In your module startup after this module is started 
   130     *  (e.g. Timer_Module_startupDone() returns TRUE). </li>
   131     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   132     *             <li> During main().</li>
   133     *             <li> During BIOS.startupFxns.</li>
   134     *           </ul>
   135     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   136     *           <ul>
   137     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   138     *             <li> In your module startup before this module is started 
   139     *  (e.g. Timer_Module_startupDone() returns FALSE).</li>
   140     *           </ul>
   141     *       </ul>
   142     *    </td></tr>
   143     *
   144     *  </table>
   145     *  @p
   146     *
   147     *  @p(html)
   148     *  <h3> Timer Mapping Tables </h3>
   149     *  <p>
   150     *  The Timer module allows the user to use and configure the various timers
   151     *  that exist on a particular device.  This is achieved by specifying a timer
   152     *  ID when calling {@link ti.sysbios.hal.Timer#Timer_create}. 
   153     *  However, the timer ID
   154     *  specified may not always map to that timer; for example, specifying an ID
   155     *  value of 1 does not necessarily mean that this will map to "GPTimer1".
   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    @InstanceFinalize       /* To cleanup */
   162    @InstanceInitError      /* To report unavailability of timer */
   163    @ModuleStartup          /* to configure static timers */
   164    
   165    module Timer inherits ti.sysbios.interfaces.ITimer
   166    {
   167        /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
   168        override metaonly config Bool supportsDynamic = true;
   169    
   170        /*! Max value of Timer period for PeriodType_COUNTS*/
   171        const UInt MAX_PERIOD = 0xffffffff;
   172    
   173        /*! L4 interface Configuration Register (TIOCP_CFG). */
   174        struct TiocpCfg {
   175            Bits8 idlemode;  /*! 0=force-idle;1=no-idle;2=Smart-idle;3=Smart-idle */
   176            Bits8 emufree;   /*! 0=counter frozen; 1=counter free-running */
   177            Bits8 softreset; /*! 0=normal mode; 1=soft reset */
   178        };
   179    
   180        /*! Interrupt Enable Register (TIER). */
   181        struct Tier {
   182            Bits8 mat_it_ena;  /*! Enable match interrupt */
   183            Bits8 ovf_it_ena;  /*! Enable overflow interrupt */
   184            Bits8 tcar_it_ena; /*! Enable capture interrupt */
   185        };
   186    
   187        /*! WakepUp Enable Register (TWER). */
   188        struct Twer {
   189            Bits8 mat_wup_ena;  /*! Enable match wake-up */
   190            Bits8 ovf_wup_ena;  /*! Enable overflow wake-up */
   191            Bits8 tcar_wup_ena; /*! Enable capture wake-up */
   192        };
   193    
   194        /*! Control Register (TCLR). */
   195        struct Tclr {
   196            Bits32 ptv; /*! Trigger output mode */
   197            Bits8 pre;  /*! Prescalar enable */
   198            Bits8 ce;   /*! Compare enable */
   199            Bits8 scpwm;/*! Pulse-width modulation */
   200            Bits16 tcm; /*! Transition capture mode */
   201            Bits16 trg; /*! Trigger output mode */
   202            Bits8 pt;   /*! Pulse or toggle select bit */
   203            Bits8 captmode; /*! Capture mode select bit */
   204            Bits8 gpocfg; /*! PWM output/event detection input pin */
   205        };
   206    
   207        /*! L4 Interface Synchronization Control Register (TSICR). */
   208        struct Tsicr {
   209            Bits8 sft;    /*! Reset software functional registers */
   210            Bits8 posted; /*! Posted mode selection */
   211        };
   212    
   213        /*! Timer Settings. */
   214        metaonly struct TimerSetting {
   215            Bool master;    /*! specifies whether this is the master */
   216            Ptr baseAddr;   /*! specify the base address  */
   217            Int intNum;     /*! specify which interrupt vector */
   218            String name;    /*! specify the timer name */
   219        };
   220    
   221        /*!
   222         *  ======== BasicView ========
   223         *  @_nodoc
   224         */
   225        metaonly struct BasicView {
   226            Ptr         halTimerHandle;
   227            String      label;
   228            UInt        id;
   229            String      name;
   230            String      startMode;
   231            String      runMode;
   232            UInt        period;
   233            String      periodType;
   234            UInt        intNum;
   235            String      eventId;
   236            String      tickFxn[];
   237            UArg        arg;
   238            String      extFreqLow;
   239            String      extFreqHigh;
   240            String      hwiHandle;
   241        };
   242    
   243        /*!
   244         *  ======== DeviceView ========
   245         *  @_nodoc
   246         */
   247        metaonly struct DeviceView {
   248            UInt        id;
   249            String      deviceAddr;
   250            UInt        intNum;
   251            String      eventId;
   252            String      runMode;
   253            String      timerState;
   254            UInt        period;
   255            String      currCount;
   256            String      remainingCount;
   257        };
   258    
   259        /*!
   260         *  ======== ModuleView ========
   261         *  @_nodoc
   262         */
   263        metaonly struct ModuleView {
   264            String          availMask;      /* avaliable 32-bit timer halves */
   265            String          intFrequency;   /* internal frequency in Hz */
   266        }
   267    
   268        /*!
   269         *  ======== rovViewInfo ========
   270         *  @_nodoc
   271         */
   272        @Facet
   273        metaonly config ViewInfo.Instance rovViewInfo = 
   274            ViewInfo.create({
   275                viewMap: [
   276                [
   277                    'Basic',
   278                    {
   279                        type: ViewInfo.INSTANCE,
   280                        viewInitFxn: 'viewInitBasic',
   281                        structName: 'BasicView'
   282                    }
   283                ],
   284                [
   285                    'Device',
   286                    {
   287                        type: ViewInfo.INSTANCE,
   288                        viewInitFxn: 'viewInitDevice',
   289                        structName: 'DeviceView'
   290                    }
   291                ],
   292                [
   293                    'Module',
   294                    {
   295                        type: ViewInfo.MODULE,
   296                        viewInitFxn: 'viewInitModule',
   297                        structName: 'ModuleView'
   298                    }
   299                ],
   300                ]
   301            });
   302    
   303        /*!
   304         *  Assert raised when statically created timer is not available
   305         */
   306        config xdc.runtime.Assert.Id A_notAvailable = {
   307            msg: "A_notAvailable: statically created timer not available"
   308        };
   309    
   310        /*!
   311         *  Error raised when timer id specified is not supported.
   312         */
   313        config Error.Id E_invalidTimer = {
   314            msg: "E_invalidTimer: Invalid Timer Id %d"
   315        };
   316    
   317        /*!
   318         *  Error raised when timer requested is in use
   319         */
   320        config Error.Id E_notAvailable  = {
   321            msg: "E_notAvailable: Timer not available %d"
   322        };
   323    
   324        /*!
   325         *  Error raised when period requested is not supported
   326         */
   327        config Error.Id E_cannotSupport = {
   328            msg: "E_cannotSupport: Timer cannot support requested period %d"
   329        };
   330        
   331        /*!
   332         *  Error raised when timer frequency does not match expected frequency
   333         *
   334         *  BIOS does not configure the DMTimer clock source and expects this
   335         *  configuration to be performed via a GEL script or on the host OS.  This
   336         *  error is raised if BIOS detects a mismatch between {@link #intFreq} and
   337         *  the actual operating frequency.  The check is performed by comparing
   338         *  the timestamp operating frequency with the DMTimer frequency.
   339         * 
   340         *  To change the expected timer frequency to match the actual operating 
   341         *  frequency, use the following example configuration:
   342         *  @p(code)
   343         *      var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
   344         *      Timer.intFreq.lo = 20000000; //For 20Mhz
   345         *      Timer.intFreq.hi = 0;
   346         *  @p
   347         *
   348         *  This check can be skipped by setting {@link #checkFrequency} to FALSE.
   349         */
   350        config Error.Id E_freqMismatch  = {
   351            msg: "E_freqMismatch: Frequency mismatch: Expected %d Hz, actual: %d Hz.  You need to modify Timer.intFreq.lo to match the actual frequency."
   352        };
   353    
   354        /*!
   355         *  Error raised when intNum not supplied by user or device table
   356         */
   357        config Error.Id E_badIntNum = {
   358            msg: "E_badIntNum: Timer requires a valid intNum. Please use DMTimer module's timerSettings config param to assign a valid intNum for the selected timer."
   359        };
   360    
   361        /*!
   362         *  ======== anyMask ========
   363         *  Available mask to be used when select = Timer_ANY. 
   364         *
   365         *  Default value is device specific.
   366         */
   367        config Bits32 anyMask;
   368    
   369        /*!
   370         *  ======== checkFrequency ========
   371         *  Whether to check the timer operating frequency at startup
   372         *
   373         *  When this flag is set to 'TRUE', the Timer module will verify that the
   374         *  operating frequency equals the frequency at which BIOS expects the 
   375         *  timers to operate.  This check is performed by checking the timer count
   376         *  rate against the {@link xdc.runtime.Timestamp} count rate.
   377         */
   378        config Bool checkFrequency = true;
   379    
   380        /*!
   381         *  ======== timerSettings ========
   382         *  Global Control configuration for each physical timer.
   383         */
   384        metaonly config TimerSetting timerSettings[] = [];
   385        
   386        /*!
   387         *  ======== intFreq ========
   388         *  Default internal timer input clock frequency.
   389         */
   390        metaonly config Types.FreqHz intFreq = {lo: 0, hi: 0};
   391        
   392        /*!
   393         *  ======== stub  ========
   394         *  @_nodoc
   395         *  Timer requires acknowledgement
   396         *
   397         *  @param(arg)     timer object passed in as argument.
   398         */
   399        @DirectCall
   400        Void stub(UArg arg);
   401    
   402        /*!
   403         *  ======== dynStub  ========
   404         *  @_nodoc
   405         *  Acknowledges timer interrupt and sets next threshold for interrupt.
   406         *
   407         *  @param(arg)     timer object passed in as argument.
   408         */
   409        @DirectCall
   410        Void dynStub(UArg arg);
   411    
   412        /*!
   413         *  ======== getHandle ========
   414         *  Get Handle associated with a timer id.
   415         *
   416         *  @param(id)      timer Id
   417         *  @b(returns)     timer handle
   418         */
   419        @DirectCall
   420        Handle getHandle(UInt id);
   421    
   422    instance:
   423    
   424        /*! 
   425         *  ======== tiocpCfg ========
   426         *  Initial Timer TIOCP_CFG Register bit settings.
   427         *
   428         *  For a detailed description of this timer register, please
   429         *  refer to your device's Technical Reference Manual.
   430         */
   431        config TiocpCfg tiocpCfg = {idlemode: 0, emufree: 0, softreset: 1};
   432    
   433        /*! 
   434         *  ======== tier ========
   435         *  Initial Timer IRQSTATUS_SET Register bit settings.
   436         *
   437         *  For a detailed description of this timer register, please
   438         *  refer to your device's Technical Reference Manual.
   439         */
   440        config Tier tier = {mat_it_ena: 0, ovf_it_ena: 1, tcar_it_ena: 0};
   441    
   442        /*! 
   443         *  ======== twer ========
   444         *  Initial Timer IRQ Wakeup Enable Register bit settings.
   445         *
   446         *  For a detailed description of this timer register, please
   447         *  refer to your device's Technical Reference Manual.
   448         */
   449        config Twer twer = {mat_wup_ena: 0, ovf_wup_ena: 0, tcar_wup_ena: 0};
   450    
   451        /*! 
   452         *  ======== tclr ========
   453         *  Initial Timer Control Register bit settings.
   454         *
   455         *  For a detailed description of this timer register, please
   456         *  refer to your device's Technical Reference Manual.
   457         */
   458        config Tclr tclr = {ptv: 0, pre: 0, ce: 0, scpwm: 0, tcm: 0, trg: 0,
   459            pt: 0, captmode: 0, gpocfg: 0};
   460        
   461        /*! 
   462         *  ======== tsicr ========
   463         *  Initial Timer Synchronous Interface Control Register bit settings.
   464         *
   465         *  For a detailed description of this timer register, please
   466         *  refer to your device's Technical Reference Manual.
   467         */
   468        config Tsicr tsicr = {sft: 0, posted: 0};
   469    
   470        /*! 
   471         *  ======== tmar ========
   472         *  Initial Timer Match Register setting.
   473         *
   474         *  For a detailed description of this timer register, please
   475         *  refer to your device's Technical Reference Manual.
   476         */
   477        config UInt32 tmar = 0;
   478    
   479        /*! 
   480         *  ======== intNum ========
   481         *  Hwi interrupt number to be used by Timer.
   482         */
   483        config Int intNum = -1;
   484    
   485        /*! 
   486         *  ======== eventId ========
   487         *  Hwi event Id to be used by Timer.
   488         */
   489        config Int eventId = -1;
   490    
   491        /*! Hwi Params for Hwi Object. Default is null. */
   492        config Hwi.Params *hwiParams = null;
   493    
   494        /*!
   495         *  ======== reconfig ========
   496         *  Used to modify static timer instances at runtime.
   497         *
   498         *  @param(timerParams)     timer Params
   499         *  @param(tickFxn)         functions that runs when timer expires
   500         */
   501        @DirectCall
   502        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   503    
   504        /*!
   505         *  ======== getRollovers  ========
   506         *  @_nodoc
   507         *  Returns the total number of timer rollovers since the timer was 
   508         *  started.  This API is used internally for implementing timestamping 
   509         *  when the timer is shared with Clock, and running with RunMode_DYNAMIC.
   510         *  It has no other intended purpose.
   511         *
   512         *  @b(returns)     number of rollovers since timer was started
   513         */
   514        @DirectCall
   515        UInt32 getRollovers();
   516    
   517        /*!
   518         *  ======== enableTimestamping  ========
   519         *  @_nodoc
   520         *  Enables the timer to be used for timestamping purposes.  This API is 
   521         *  used internally for enabling timestamping when the timer is shared with
   522         *  Clock, and running with RunMode_DYNAMIC. It has no other intended 
   523         *  purpose.
   524         *
   525         */
   526        @DirectCall
   527        Void enableTimestamping();
   528        
   529        /*!
   530         *  ======== restoreRegisters ========
   531         *  Restore timer registers to their nominal state following a power down.
   532         *
   533         *  All registers are restored to their nominal operating state, except
   534         *  for those registers and bits associated with starting the timer.
   535         *  
   536         *  Following a power down, the user should do the following to restore
   537         *  and restart the timer:
   538         *
   539         *  @p(code)
   540         *      Timer_handle timer;
   541         *      Error_Block eb;
   542         *
   543         *      Timer_restoreRegisters(timer, &eb);
   544         *      Timer_start(timer);
   545         *  @p
   546         *
   547         */
   548        @DirectCall
   549        Void restoreRegisters(Error.Block *eb);
   550        
   551        /*! @_nodoc
   552         *  ======== getIntNum ========
   553         *  Get Timer's Interrupt number.
   554         *
   555         *  @b(returns)     Timer's Interrupt number
   556         */
   557        @DirectCall
   558        Int getIntNum();
   559    
   560    internal:   /* not for client use */
   561        
   562    
   563        /*! Information about timer */
   564        struct TimerDevice {
   565            Int  intNum;
   566            Int  eventId;
   567            Ptr  baseAddr;
   568        };
   569    
   570        /*! Device-specific Timer implementation. */
   571        proxy TimerSupportProxy inherits ti.sysbios.interfaces.ITimerSupport;
   572    
   573        /*!
   574         *  ======== startupNeeded ========
   575         *  This flag is use to prevent Timer_startup code (includes postInit(),
   576         *  deviceConfig(), initDevice() to be brought in un-necessarily.
   577         */
   578        config Bool startupNeeded = false;
   579    
   580        /*!
   581         *  ======== numTimerDevices ========
   582         *  The number of logical timers on a device.
   583         */
   584        config Int numTimerDevices;
   585    
   586        /*
   587         *  ======== deviceConfig ========
   588         *  Configure the timer.
   589         */
   590        Int deviceConfig(Object *timer, Error.Block *eb);
   591    
   592        /*
   593         *  ======== initDevice ========
   594         *  reset timer to its resting state
   595         */
   596        Void initDevice(Object *timer, Error.Block *eb);
   597    
   598        /*
   599         *  ======== initObj ========
   600         *  Initialize the instance state object
   601         */
   602        Void initObj(Object *timer, FuncPtr tickFxn, const Params *timerParams);
   603    
   604        /*
   605         *  ======== postInit ========
   606         *  finish initializing static and dynamic Timers
   607         */
   608        Int postInit(Object *timer, Error.Block *eb);
   609    
   610        /*
   611         *  ======== checkOverflow ========
   612         */
   613        Bool checkOverflow(UInt32 a, UInt32 b);
   614    
   615        /*
   616         *  ======== getNextAvailableTimerId ========
   617         */
   618        UInt getNextAvailableTimerId(Object *timer);
   619    
   620        /*!
   621         *  ======== spinLoop ========
   622         *  used by trigger function.
   623         */
   624        Void spinLoop(UInt count);
   625        
   626        /*!
   627         *  ======== checkFreq ========
   628         *  Used to verify that the DMTimer is operating at the right frequency.
   629         */
   630        Void checkFreq(Timer.Object *obj);
   631    
   632        /*! Instance state structure */
   633        struct Instance_State {
   634            Bool                staticInst;     /* statically created or not */
   635            Int                 id;             /* logical timer id. */
   636            UInt                tiocpCfg;
   637            UInt                tmar;
   638            UInt                tier;
   639            UInt                twer;
   640            UInt                tclr;
   641            UInt                tsicr;
   642            ITimer.RunMode      runMode;        /* timer mode */
   643            ITimer.StartMode    startMode;      /* timer mode */
   644            UInt                period;         /* period */
   645            ITimer.PeriodType   periodType;     /* type (microsecs, inst) */
   646            UInt                intNum;         /* intr num */
   647            Int                 eventId;        /* event Id */
   648            UArg                arg;            /* isrFxn arg */
   649            Hwi.FuncPtr         tickFxn;        /* Timer fxn plugged into Hwi */
   650            Types.FreqHz        extFreq;        /* ext freq */
   651            Hwi.Handle          hwi;            /* hwi inst */
   652            UInt                prevThreshold;  /* previous interrupt thresh */
   653            UInt                rollovers;      /* total timer rollovers */
   654            /* 
   655             * Used by Timer Startup to decide whether to use default Event Id 
   656             * from the device Table or use the User provided Event Id 
   657             */
   658            Bool                useDefaultEventId;
   659        }
   660    
   661        /*! Module state structure */
   662        struct Module_State {
   663            Bits32          availMask;      /* avaliable 32-bit timer halves */
   664            Types.FreqHz    intFreq;        /* internal frequency in Hz */
   665            TimerDevice     device[];       /* timer device information */
   666            Handle          handles[];      /* handles based on logical id */
   667            Bool            firstInit;
   668        }
   669    }