1    /*
     2     * Copyright (c) 2014, 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.timer64;
    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 timer64 peripheral available on many devices.
    53     *  It is supported on the ARM and c64x+ DSP targets. This module supports the
    54     *  timer in '32-bit chained' and '32-bit unchained' mode.  In the
    55     *  '32-bit unchained' mode, specify the lower or upper half to be used.
    56     *  The physical timer being used will be taken out of reset, only when
    57     *  its specified to be the master.
    58     *
    59     *  For shared timers on a homogeneous multicore device (ie. c6472), each
    60     *  core can create the timer, but only one core will initialize the timer
    61     *  and take it out of reset.  The core that does the initialization can be
    62     *  specified by the module configuration parameter
    63     *  timerSettings[].ownerCoreId in the *.cfg file.
    64     *  By default, Core 0 is the owner for all shared timers.
    65     *
    66     *  Note:  Creating a timer with 'Timer.ANY' specified as the id will not
    67     *         return a shared timer on a homogeneous multicore device.  To use
    68     *         a shared timer, specify the timer id explicitly when creating it.
    69     *         On these devices Timer.ANY specifies the local timer id.  This
    70     *         allows a single image to run on multiple cores since each core
    71     *         will program a different local timer.
    72     *
    73     *  The following sample .cfg code sets core 1 to initialize a shared timer
    74     *  with id 4.
    75     *
    76     *  @p(code)
    77     *  var Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    78     *
    79     *  // sets core 1 to init and release Timer 4.
    80     *  Timer.timerSettings[4].ownerCoreId = 1;
    81     *  @p
    82     *
    83     *  The following sample .cfg code sets core 0 to initialize a shared timer
    84     *  with id 4.  It also configures the Clock module to use this timer.
    85     *  This allows multiple cores to share timer 4 for the Clock module's
    86     *  interrupt source.
    87     *
    88     *  @p(code)
    89     *  // sets core 0 to init and release Timer 4.
    90     *  var Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
    91     *  Timer.timerSettings[4].ownerCoreId = 0;
    92     *
    93     *  var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    94     *  Clock.timerId = 4;
    95     *  @p
    96     *
    97     *  @p(html)
    98     *  <h3> Calling Context </h3>
    99     *  <table border="1" cellpadding="3">
   100     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   101     *    </colgroup>
   102     *
   103     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
   104     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   105     *    <!--                                                                -->
   106     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
   107     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   108     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
   109     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   110     *    <tr><td> {@link #Params_init}             </td><td>   Y    </td>
   111     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   112     *    <tr><td> {@link #construct}               </td><td>   Y    </td>
   113     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   114     *    <tr><td> {@link #create}                  </td><td>   N    </td>
   115     *    <td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   116     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
   117     *    <td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   118     *    <tr><td> {@link #destruct}                </td><td>   Y    </td>
   119     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   120     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
   121     *    <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   122     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
   123     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   124     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
   125     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   126     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
   127     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   128     *    <tr><td> {@link #reconfig}                </td><td>   Y    </td>
   129     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   130     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   131     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   132     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   133     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   134     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   135     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   136     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   137     *    <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   138     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   139     *    <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   140     *    <tr><td colspan="6"> Definitions: <br />
   141     *       <ul>
   142     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   143     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   144     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   145     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   146     *           <ul>
   147     *             <li> In your module startup after this module is started
   148     *    (e.g. Timer_Module_startupDone() returns TRUE). </li>
   149     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   150     *             <li> During main().</li>
   151     *             <li> During BIOS.startupFxns.</li>
   152     *           </ul>
   153     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   154     *           <ul>
   155     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   156     *             <li> In your module startup before this module is started
   157     *   (e.g. Timer_Module_startupDone() returns FALSE).</li>
   158     *           </ul>
   159     *       </ul>
   160     *    </td></tr>
   161     *
   162     *  </table>
   163     *  @p
   164     *
   165     *  @p(html)
   166     *  <h3> Timer Mapping Tables </h3>
   167     *  <p>
   168     *  The Timer module allows the user to use and configure the various timers
   169     *  that exist on a particular device.  This is achieved by specifying a timer
   170     *  ID when calling {@link ti.sysbios.hal.Timer#Timer_create}.
   171     *  However, the timer ID
   172     *  specified may not always map to that timer; for example, specifying an ID
   173     *  value of 1 does not necessarily mean that this will map to "GPTimer1".
   174     *  These tables are provided to show which timers map to which timer IDs.
   175     *  </p>
   176     *  {@link ./doc-files/TimerTables.html Timer Mapping Tables}
   177     *  @p
   178     *
   179     */
   180    @ModuleStartup                /* to configure static timers */
   181    @InstanceInitStatic
   182    
   183    module Timer inherits ti.sysbios.interfaces.ITimer
   184    {
   185        /*! In 32-bit modes, used to specify which half of Timer to use */
   186        enum Half {
   187            Half_LOWER,
   188            Half_UPPER,
   189            Half_DEFAULT
   190        };
   191    
   192        /*!
   193         *  The different modes of the Timer. These values match the TIMMODE
   194         *  bit fields of the Timer Global Control Register.
   195         */
   196        enum Mode {
   197            Mode_64BITGPTIMER = 0,
   198            Mode_UNCHAINED = 1,
   199            Mode_WATCHDOG = 2,
   200            Mode_CHAINED = 3
   201        };
   202    
   203        /*! Max value of Timer period for PeriodType_COUNTS*/
   204        const UInt MAX_PERIOD = 0xffffffff;
   205    
   206        /*! Timer Control Register struct. */
   207        struct Control {
   208            Bits8 tien;      /*! 0=Clock not gated by TINP; 1=Clock gated */
   209            Bits8 invout;    /*! 0=Uninverted TSTAT drives TOUT; 1=Inverted TSTAT */
   210            Bits8 invin;     /*! 0=Uninverted TINP drives Timer; 1=Inverted TINP */
   211            UInt8 pwid;      /*! TSTATx goes inactive after pwid cycles (CP=0) */
   212            Bits8 cp;        /*! 0=pulse mode; 1=clock mode */
   213        };
   214    
   215        /*! Timer Emulation Management Register struct. */
   216        struct EmuMgt {
   217            Bool free;        /*! 0=suspend for emu halt; 1=don't suspend */
   218            Bool soft;        /*! 0=stop immediately; 1=stop when count==period */
   219        };
   220    
   221        /*! Timer GPIO interrupt control and enable Management Register struct. */
   222        struct GpioIntEn {
   223            Bits8 gpint12_eni;  /*! 0=source by timer; 1=input to source event */
   224            Bits8 gpint12_eno;  /*! 0=source by timer; 1=output to source event */
   225            Bits8 gpint12_invi; /*! 0=don't invert invput; 1=invert input */
   226            Bits8 gpint12_invo; /*! 0=don't invert output; 1=invert output */
   227            Bits8 gpint34_eni;  /*! 0=source by timer; 1=input to source event */
   228            Bits8 gpint34_eno;  /*! 0=source by timer; 1=output to source event */
   229            Bits8 gpint34_invi; /*! 0=don't invert invput; 1=invert input */
   230            Bits8 gpint34_invo; /*! 0=don't invert output; 1=invert output */
   231            Bits8 gpio_eni12;   /*! 0=TINP12 as timer input; 1=TINP12 as GPIO */
   232            Bits8 gpio_eno12;   /*! 0=TOUTP12 as timer output; 1=TOUTP12 as GPIO */
   233            Bits8 gpio_eni34;   /*! 0=TINP34 as timer input; 1=TINP34 as GPIO */
   234            Bits8 gpio_eno34;   /*! 0=TOUTP34 as timer output; 1=TOUTP12 as GPIO */
   235        };
   236    
   237        /*! Timer GPIO Data and Direction Management Register struct. */
   238        struct GpioDatDir {
   239            Bits8 gpio_dati12; /*! 0=TINP12 is input; 1=TINP12 is output */
   240            Bits8 gpio_dato12; /*! 0=TOUTP12 is input; 1=TOUTP12 is output */
   241            Bits8 gpio_dati34; /*! 0=TINP34 is input; 1=TINP34 is output */
   242            Bits8 gpio_dato34; /*! 0=TOUTP34 is input; 1=TOUTP34 is output */
   243            Bits8 gpio_diri12; /*! 0=input as GPIO input; 1=input as GPIO output */
   244            Bits8 gpio_diro12; /*! 0=output as GPIO input;1=output as GPIO output */
   245            Bits8 gpio_diri34; /*! 0=input as GPIO input; 1=input as GPIO output */
   246            Bits8 gpio_diro34; /*! 0=output as GPIO input;1=output as GPIO output */
   247        };
   248    
   249        /*! Timer interrupt control struct. */
   250        struct IntCtl {
   251            Bool prdinten_hi;  /*! 0=Disable interrupt; 1=Enable interrupt */
   252            Bool prdinten_lo;  /*! 0=Disable interrupt; 1=Enable interrupt */
   253        };
   254    
   255        /*! Timer Settings. */
   256        struct TimerSetting {
   257            Mode mode ;         /*! mode to put each Timer into */
   258            Bool master;        /*! for 'unchained' mode; 1=set mode and reset */
   259            UInt16 ownerCoreId; /*! used only for homogeneous multicore DSPs */
   260        };
   261    
   262        /*! @_nodoc */
   263        @XmlDtd
   264        metaonly struct BasicView {
   265            Ptr         halTimerHandle;
   266            String      label;
   267            UInt        id;
   268            String      startMode;
   269            String      runMode;
   270            UInt        period;
   271            String      periodType;
   272            String      half;
   273            UInt        prescalar;
   274            UInt        intNum;
   275            String      tickFxn[];
   276            UArg        arg;
   277            String      extFreqLow;
   278            String      extFreqHigh;
   279            String      hwiHandle;
   280        };
   281    
   282    
   283        /*! @_nodoc */
   284        metaonly struct ModuleView {
   285            String      availMaskHigh;     /* available 32-bit timer halves with
   286                                              timer id  >= 16 */
   287            String      availMask;         /* available 32-bit timer halves with
   288                                              timer id  < 16 */
   289            String      intFrequency[];    /* internal frequency in Hz */
   290        }
   291    
   292        /*! @_nodoc */
   293        metaonly struct Device_View {
   294            UInt        id;
   295            Bool        inUse;
   296            UInt32      intFreq;
   297            UInt        intNum;
   298            UInt        eventId;
   299            String      baseAddress;
   300        };
   301    
   302        /*! @_nodoc */
   303        @Facet
   304        metaonly config ViewInfo.Instance rovViewInfo =
   305            ViewInfo.create({
   306                viewMap: [
   307                [
   308                    'Basic',
   309                    {
   310                        type: ViewInfo.INSTANCE,
   311                        viewInitFxn: 'viewInitBasic',
   312                        structName: 'BasicView'
   313                    }
   314                ],
   315                [
   316                    'Module',
   317                    {
   318                        type: ViewInfo.MODULE,
   319                        viewInitFxn: 'viewInitModule',
   320                        structName: 'ModuleView'
   321                    }
   322                ],
   323                ]
   324            });
   325    
   326        /*!
   327         *  Assert raised when static created timer is not available
   328         */
   329        config xdc.runtime.Assert.Id A_notAvailable =
   330            {msg: "A_notAvailable: static created timer not available"};
   331    
   332        /*!
   333         *  Error raised when timer id specified is not supported.
   334         */
   335        config Error.Id E_invalidTimer = {
   336            msg: "E_invalidTimer: Invalid Timer Id %d"
   337        };
   338    
   339        /*!
   340         *  Error raised when timer requested is in use
   341         */
   342        config Error.Id E_notAvailable  = {
   343            msg: "E_notAvailable: Timer not available %d"
   344        };
   345    
   346        /*!
   347         *  Error raised when period requested is not supported
   348         */
   349        config Error.Id E_cannotSupport = {
   350            msg: "E_cannotSupport: Timer cannot support requested period %d"
   351        };
   352    
   353        /*!
   354         *  ======== anyMask ========
   355         *  Available mask to be used when select = Timer_ANY for timer id < 16.
   356         *  Set in xs file.
   357         */
   358        config Bits32 anyMask;
   359    
   360        /*!
   361         *  ======== anyMaskHigh ========
   362         *  Available mask to be used when select = Timer_ANY for timer id >= 16.
   363         *  Set in xs file.
   364         */
   365        config Bits32 anyMaskHigh;
   366    
   367        /*!
   368         *  ======== defaultHalf ========
   369         *        The default 32-bit half of the timer to be used.
   370         */
   371        config Half defaultHalf = Half_LOWER;
   372    
   373        /*!
   374         *  ======== timerSettings ========
   375         *  Global Control configuration for each physical timer.
   376         *
   377         *  mode: Mode_UNCHAINED        32-bit unchained mode.
   378         *  master: TRUE                If TRUE, release Timer from reset.
   379         */
   380        config TimerSetting timerSettings[] = [];
   381    
   382        /*!
   383         *  ======== intFreq ========
   384         *  @_nodoc
   385         *  Internal frequency for Timer
   386         */
   387        metaonly config Types.FreqHz intFreq;
   388    
   389        /*!
   390         *  ======== intFreq ========
   391         *  Default internal timer input clock frequency array.
   392         *
   393         *  This array can be used to change the input clock frequency
   394         *  for a particular timer.
   395         *
   396         *  For example, if it is required to change the input clock frequency
   397         *  for timer id 2 to 32768Hz on a device that has 4 timers, the
   398         *  intFreqs[2] config param can be set to {hi:0, lo:32768} in the
   399         *  config script.
   400         *
   401         *  @p(code)
   402         *  var Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');
   403         *
   404         *  // Set Timer 2's frequency to 32.768 Khz
   405         *  Timer.intFreqs[2] = { hi:0, lo: 32768 };
   406         *  @p
   407         *
   408         *  For a list of default timer frequencies for different devices,
   409         *  please refer {@link ./doc-files/TimerTables.html Timer Mapping Tables}.
   410         */
   411        metaonly config Types.FreqHz intFreqs[];
   412    
   413        /*!
   414         *  @_nodoc
   415         *  ======== useTimer64pRegMap ========
   416         *  Latest Timer64P IP has a different register map than the older
   417         *  Timer64 IP. If this flag is set to TRUE, use the new register
   418         *  map.
   419         */
   420        config Bool useTimer64pRegMap = false;
   421    
   422    instance:
   423    
   424        /*!
   425         *  ======== controlInit ========
   426         *  Control configuration. Default is all fields 0 or false except:
   427         *
   428         *      pwid: 1
   429         */
   430        config Control controlInit = {tien: 0, invout: 0, invin: 0,
   431                                      pwid: 1, cp: 0};
   432    
   433        /*!
   434         *  ======== emuMgtInit ========
   435         *  Emulation Management configuration. Default is:
   436         *
   437         *      free: 0
   438         *      soft: 0
   439         */
   440        config EmuMgt emuMgtInit = {free: 0, soft: 0};
   441    
   442        /*!
   443         *  ======== gpioIntEn ========
   444         *  General Purpose IO interrupt control and enable Management
   445         *  configuration. The default for all fields is 0.
   446         */
   447        config GpioIntEn gpioIntEn = {
   448            gpint12_eni: 0, gpint12_eno: 0, gpint12_invi: 0, gpint12_invo: 0,
   449            gpint34_eni: 0, gpint34_eno: 0, gpint34_invi: 0, gpint34_invo: 0,
   450            gpio_eni12:  0, gpio_eno12:  0, gpio_eni34:   0, gpio_eno34:   0};
   451    
   452        /*!
   453         *  ======== gpioDatDir ========
   454         *  General Purpose IO data and direction Management configuration
   455         *  The default is all fields is 0.
   456         */
   457        config GpioDatDir gpioDatDir = {
   458            gpio_dati12: 0, gpio_dato12: 0, gpio_dati34: 0, gpio_dato34: 0,
   459            gpio_diri12: 0, gpio_diro12: 0, gpio_diri34: 0, gpio_diro34: 0};
   460    
   461        /*!
   462         *  ======== intCtl ========
   463         *  Timer interrupt control struct
   464         */
   465        config IntCtl intCtl = {prdinten_hi: 1, prdinten_lo: 1};
   466    
   467        /*!
   468         *  ======== half ========
   469         *  In 32-bit unchained mode, this field is used to specify which half
   470         *  of the timer to use.
   471         */
   472        config Half half = Half_DEFAULT;
   473    
   474        /*! Hwi Params for Hwi Object. Default is null. */
   475        config Hwi.Params *hwiParams = null;
   476    
   477        /*! Hwi interrupt number to be used by Timer. */
   478        config Int intNum = -1;
   479    
   480        /*!
   481         *  ======== prescalar ========
   482         *  32-bit pre-scalar to TIM12 in '32-bit chained' mode.
   483         *  The default is 0.
   484         */
   485        config UInt prescalar = 0;
   486    
   487        /*!
   488         *  ======== reconfig ========
   489         *  Used to modify static timer instances at runtime.
   490         *
   491         *  @param(timerParams)     timer Params
   492         *  @param(tickFxn)                functions that runs when timer expires
   493         */
   494        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   495    
   496    
   497    internal:   /* not for client use */
   498    
   499        /*! Information about timer */
   500        struct TimerDevice {
   501            UInt intNum;
   502            UInt eventId;
   503            Ptr  baseAddr;
   504        };
   505    
   506        /*! Device-specific Timer implementation. */
   507        proxy TimerSupportProxy inherits ti.sysbios.interfaces.ITimerSupport;
   508    
   509        /*!
   510         *  ======== staticAvailMask ========
   511         *  The number of statically available 32-bit timer halves with
   512         *  timerId < 16
   513         *
   514         *  This is required for supporting timers that are local to a
   515         *  particular processor.  The module availMask keeps track of
   516         *  what timers are available at runtime.  The two mask are the
   517         *  same if there is no concept of local timers.
   518         */
   519        metaonly config Int staticAvailMask;
   520    
   521        /*!
   522         *  ======== staticAvailMaskHigh ========
   523         *  The number of statically available 32-bit timer halves with
   524         *  timerId >= 16
   525         *
   526         *  This is required for supporting timers that are local to a
   527         *  particular processor.  The module availMask keeps track of
   528         *  what timers are available at runtime.  The two mask are the
   529         *  same if there is no concept of local timers.
   530         */
   531        metaonly config Int staticAvailMaskHigh;
   532    
   533        /*!
   534         *  ======== startupNeeded ========
   535         *  This flag is use to prevent Timer_startup code (includes postInit(),
   536         *  deviceConfig() & initDevice()) to be brought in un-necessarily.
   537         */
   538        config Bool startupNeeded = false;
   539    
   540        /*!
   541         *  ======== freqDivisor ========
   542         *  For some devices, the timer frequency is determined by the CPU
   543         *  frequency divided by a value.  This parameter captures that value
   544         *  and is used during runtime to re-calculate the timer frequency
   545         *  when the CPU frequency is changed and Timer_getFreq is called.
   546         *  For devices with a fix timer frequency, this value is 0.
   547         */
   548        config UInt freqDivisor = 0;
   549    
   550        /*!
   551         *  ======== numTimerDevices ========
   552         *  The number of logical timers on a device.
   553         */
   554        config Int numTimerDevices;
   555    
   556        /*!
   557         *  ======== numLocalTimers ========
   558         *  The number of physical local timers on a device.
   559         */
   560        config Int numLocalTimers = 0;
   561    
   562        /*!
   563         *  ======== localTimerBaseId ========
   564         *  Timer id of the first local timer.
   565         *
   566         *  All local timer are grouped and this field controls
   567         *  the id of the first local timer.
   568         */
   569        config UInt8 localTimerBaseId = 0;
   570    
   571        /*
   572         *  ======== deviceConfig ========
   573         *  Configure the timer.
   574         */
   575        Int deviceConfig(Object *timer, Error.Block *eb);
   576    
   577        /*
   578         *  ======== initDevice ========
   579         *  reset timer to its resting state
   580         */
   581        Void initDevice(Object *timer, Error.Block *eb);
   582    
   583        /*
   584         *  ======== initObj ========
   585         *  Initialize the instance state object
   586         */
   587        Void initObj(Object *timer, FuncPtr tickFxn, const Params *timerParams);
   588    
   589        /*
   590         *  ======== postInit ========
   591         *  finish initializing static and dynamic Timers
   592         */
   593        Int postInit(Object *timer, Error.Block *eb);
   594    
   595        /*
   596         *  ======== checkOverflow ========
   597         */
   598        Bool checkOverflow(UInt32 a, UInt32 b);
   599    
   600        /*!
   601         *  ======== spinLoop ========
   602         *  used by trigger function.
   603         */
   604        Void spinLoop(UInt count);
   605    
   606        /*! Instance state structure */
   607        struct Instance_State {
   608            Bool              staticInst;   /* statically created or not */
   609            Int               id;           /* logical timer id. */
   610            Half              half;         /* which half */
   611            UInt              tcrInit;      /* tcr  */
   612            UInt              emumgtInit;   /* emu mgt */
   613            UInt              gpioIntEn;    /* GPIO interrupt control */
   614            UInt              gpioDatDir;   /* GPIO data and direction */
   615            ITimer.RunMode    runMode;      /* timer mode */
   616            ITimer.StartMode  startMode;    /* timer mode */
   617            UInt              period;       /* period */
   618            ITimer.PeriodType periodType;   /* type (microsecs, inst) */
   619            UInt              prescalar;    /* pre-scalar for TIM12 */
   620            UInt              intNum;       /* intr num */
   621            UArg              arg;          /* isrFxn arg */
   622            Hwi.FuncPtr       tickFxn;      /* Timer fxn plugged into Hwi */
   623            Types.FreqHz      extFreq;      /* ext freq */
   624            Hwi.Handle        hwi;          /* hwi inst */
   625            UInt              intCtl;       /* Timer interrupt control */
   626        }
   627    
   628        /*! Module state structure */
   629        struct Module_State {
   630            Bits32        availMask;        /* avaliable 32-bit timer halves
   631                                               for timer id < 16 */
   632            Types.FreqHz  intFreqs[];       /* internal frequency in Hz */
   633            TimerSetting  gctrl[];          /* global control information */
   634            TimerDevice   device[];         /* timer device information */
   635            Handle        handles[];        /* handles based on logical id */
   636            Bits32        availMaskHigh;    /* avaliable 32-bit timer halves
   637                                               for timer id >= 16 */
   638        }
   639    }