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