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.family.c28;
    39    
    40    import xdc.rov.ViewInfo;
    41    
    42    import xdc.runtime.Error;
    43    import xdc.runtime.Assert;
    44    import xdc.runtime.Types;
    45    import ti.sysbios.interfaces.ITimer;
    46    
    47    /*!
    48     *  ======== Timer ========
    49     *  Timer peripherals manager for the c28 family.
    50     *
    51     *  @p(html)
    52     *  <h3> 28x Timers </h3>
    53     *  @p(blist)
    54     *  - The 28x has three 32-bit timers.
    55     *  - The 28x timer counts downward from 'period' to 0; however, Timer_getCount
    56     *    will count upward.
    57     *  - The 28x timer supports an optional 16-bit prescalar. The prescalar 
    58     *    effectively sets the period of the timer tick; the prescalar counts down 
    59     *    from the prescale factor to 0, then a timer tick occurs. So, with a 
    60     *    prescale set, the actual timer period is (prescale * period).
    61     *  @p
    62     *
    63     *  @p(html)
    64     *  <h3> Calling Context </h3>
    65     *  <table border="1" cellpadding="3">
    66     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    67     *
    68     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    69     *    <!--                                                                                                                 -->
    70     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    71     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    72     *    <tr><td> {@link #Params_init}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    73     *    <tr><td> {@link #construct}               </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    74     *    <tr><td> {@link #create}                  </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    75     *    <tr><td> {@link #delete}                  </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    76     *    <tr><td> {@link #destruct}                </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    77     *    <tr><td> {@link #getCount}                </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    78     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    79     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    80     *    <tr><td> {@link #getPrescale}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    81     *    <tr><td> {@link #getPrescaleCount}        </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    82     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    83     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #setPrescale}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    85     *    <tr><td> {@link #start}                   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #stop}                    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    87     *    <tr><td colspan="6"> Definitions: <br />
    88     *       <ul>
    89     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    90     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    91     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    92     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    93     *           <ul>
    94     *             <li> In your module startup after this module is started (e.g. Timer_Module_startupDone() returns TRUE). </li>
    95     *             <li> During xdc.runtime.Startup.lastFxns. </li>
    96     *             <li> During main().</li>
    97     *             <li> During BIOS.startupFxns.</li>
    98     *           </ul>
    99     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   100     *           <ul>
   101     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   102     *             <li> In your module startup before this module is started (e.g. Timer_Module_startupDone() returns FALSE).</li>
   103     *           </ul>
   104     *       </ul>
   105     *    </td></tr>
   106     *  </table>
   107     *  @p
   108     */
   109    
   110    @InstanceFinalize       /* Clear the timer and delete its Hwi */
   111    @InstanceInitError      /* To report unavailability of a timer */
   112    @ModuleStartup          /* To configure static timers */
   113    
   114    module Timer inherits ti.sysbios.interfaces.ITimer
   115    {
   116        /*! Max value of Timer period for PeriodType_COUNTS*/
   117        const UInt MAX_PERIOD = 0xffffffff;
   118    
   119        /*! Number of timer peripherals on chip */
   120        const Int NUM_TIMER_DEVICES = 3;
   121    
   122        /*! Timer Emulation Mode. */
   123        struct EmulationMode {
   124            UInt free;      /*! At sw breakpoint, stop or free-run the timer. */
   125            UInt soft;      /*! At sw breakpoint, hard stop or run down timer. */
   126        };
   127        
   128        /*! @_nodoc */
   129        metaonly struct BasicView {
   130            Ptr         halTimerHandle;
   131            String      label;
   132            UInt        id;
   133            String      startMode;
   134            String      runMode;
   135            UInt        period;
   136            String      periodType;
   137            UInt        prescalar;
   138            UInt        intNum;
   139            UArg        arg;
   140            String      tickFxn[];
   141            String      hwiHandle;
   142        };
   143    
   144        /*! @_nodoc */
   145        metaonly struct DeviceView {
   146            UInt        id;
   147            String      deviceAddr;
   148            UInt        intNum;
   149            UInt        period;
   150            UInt        currCount;
   151            UInt        remainingCount;
   152        };
   153    
   154        /*! @_nodoc */
   155        @Facet
   156        metaonly config ViewInfo.Instance rovViewInfo = 
   157            ViewInfo.create({
   158                viewMap: [
   159                    ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
   160                    ['Device', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitDevice', structName: 'DeviceView'}],
   161                ]
   162            });
   163        
   164        /*! 
   165         *  Assert raised in Timer_create when timer id specified is not supported.
   166         */
   167        config Assert.Id A_invalidTimer = {
   168            msg: "A_invalidTimer: Timer id must be 0-2"
   169        }; 
   170        
   171        /*! 
   172         *  Error raised in Timer_create when timer requested is in use.
   173         */
   174        config Error.Id E_notAvailable = {
   175            msg: "E_notAvailable: Timer not available %d"
   176        };
   177    
   178        /*! 
   179         *  Assert raised in Timer_create if an invalid RunMode is requested.
   180         */
   181        config Assert.Id A_invalidRunMode = {
   182            msg: "A_invalidRunMode: Invalid RunMode"
   183        }; 
   184    
   185        /*! 
   186         *  Assert raised in Timer_create when Hwi Params does not mask 'self'.
   187         *  
   188         *  This is not allowed because the timers on this platform do not 
   189         *  inherently support one-shot mode. Instead, a stub is used to stop the
   190         *  timer, so it is important that the timer interrupt not occur again
   191         *  before the stub has stopped the timer.
   192         */
   193        config Assert.Id A_invalidHwiMask = {
   194            msg: "A_InvalidMask: Mask in hwiParams cannot enable self"
   195        }; 
   196    
   197        /*! 
   198         *  Assert raised when period requested is not supported.
   199         */
   200        config Assert.Id E_cannotSupport = {
   201            msg: "E_cannotSupport: Timer cannot support requested period"
   202        }; 
   203    
   204        /*!
   205         *  ======== anyMask ========
   206         *  Available mask to be used when select = Timer_ANY
   207         */
   208        config UInt anyMask = 0x7;
   209    
   210    instance:
   211    
   212        /*! 
   213         *  ======== emulationModeInit ========
   214         *  Initial timer emulation mode. Default hard stop. 
   215         *  
   216         *  Determines timer state at a software breakpoint. If 'free' is 1, the
   217         *  timer will continue to run, and the value of 'soft' doesn't matter.
   218         *  When 'free' is 0 and 'soft' is 1, the timer runs down to 0 then stops.
   219         *  When 'free' is 0 and 'soft' is 0, the timer halts.
   220         *  
   221         *  @p(html)
   222         *  <pre>
   223         *  FREE   SOFT    
   224         *  0      0      Stop after next timer decrement. (Hard stop)
   225         *  0      1      Stop after timer runs down to 0. (Soft stop)
   226         *  1      x      Continue running the timer.
   227         *  </pre>
   228         */
   229        config EmulationMode emulationModeInit = {free: 0, soft: 0};
   230    
   231        /*! 
   232         *  ======== prescale ======== 
   233         *  Prescale factor. 
   234         *
   235         *  The prescale factor determines the length of a timer tick. 
   236         *  If a prescale of 10 is specified, a timer tick will occur 
   237         *  every 11 cycles.
   238         *
   239         *  If the timer is used as a counter, the prescale factor determines
   240         *  the period between counts. Otherwise, the prescale factor can be used
   241         *  to achieve longer timer periods: with a prescale specified, the actual
   242         *  period is (period * prescale+1).
   243         */
   244        config UInt16 prescale = 0;
   245    
   246        /*! 
   247         *  ======== hwiParams ========
   248         *  Parameters for the Hwi object created for the Timer ISR. 
   249         * 
   250         *  The mask setting for the Hwi object should include SELF to prevent
   251         *  nested timer interrupts.
   252         */
   253        config Hwi.Params *hwiParams = null;
   254    
   255        /*! 
   256         *  ======== getCount ========
   257         *  Returns the number of counts that have passed.
   258         *
   259         *  The 28x timer counts downward from the period to 0, but getCount
   260         *  subtracts the timer counter value from the period so that getCount
   261         *  counts upward instead of downward.
   262         *
   263         *  @b(returns) timer counts, counting upward from 0
   264         */
   265        @DirectCall
   266        override UInt32 getCount();
   267    
   268        /*! 
   269         *  ======== setPreScale ========
   270         *  Set timer prescale value.
   271         *
   272         *  This function sets the value of the prescalar, and will also reload
   273         *  the timer counter and prescale registers.
   274         *
   275         *  The prescalar decrements with each timer clock source cycle until it 
   276         *  reaches zero, then the timer's count is decremented by one. The
   277         *  prescalar has the effect of setting the rate of the timer tick.
   278         *
   279         *  @param(preScalar) The value to set the prescale period to.
   280         */
   281        Void setPrescale(UInt16 preScalar);
   282    
   283        /*! 
   284         *  ======== getPrescale ========
   285         *  Get timer prescale value.
   286         *
   287         *  This is not the prescale count, but the period of the prescalar.
   288         *
   289         *  @b(returns) prescale value
   290         */
   291        UInt16 getPrescale();
   292    
   293        /*! 
   294         *  ======== getPrescaleCount ========
   295         *  Reads timer prescale counter.
   296         *
   297         *  The prescale counter counts down from prescale to 0, but 
   298         *  getPrescaleCount subtracts the counter value from the period so that 
   299         *  this function counts upward instead of downward.
   300         *
   301         *  @b(returns) prescale counter, counting upward from 0
   302         */
   303        UInt16 getPrescaleCount();
   304        
   305        /*!
   306         *  ======== getExpiredCounts64 ========
   307         *  @_nodoc
   308         *  Called by TimestampProvider to read the timer counter, accounting
   309         *  for counter rollover.
   310         *
   311         *  This version of the API returns a 64-bit count and is only used when
   312         *  the TimestampProvider is using a dedicated timer.
   313         *
   314         *  This function must be called with interrupts disabled.
   315         *  
   316         *  @b(returns) Timer counts, accounting for counter rollover.
   317         */
   318        @DirectCall 
   319        Void getExpiredCounts64(Types.Timestamp64 *result);
   320        
   321    internal:   /* not for client use */
   322        
   323        /*!
   324         *  ======== oneShotStub ========
   325         *  This stub implements oneShot mode by stopping the timer and clearing
   326         *  the CPU IFR bit. It does not clear the PIEIFR bit, so timer 0 does
   327         *  not support one shot mode.
   328         *
   329         *  @param(arg) The timer object
   330         */
   331        Void oneShotStub(UArg arg);
   332       
   333        /*!
   334         *  ======== startupNeeded ========
   335         *  Flag used to prevent Module_startup and Timer_startup code from being
   336         *  brought in unnecessarily. Flag is set if there are any static Timer
   337         *  instances.
   338         */
   339        config UInt startupNeeded = false;
   340        
   341        struct Instance_State {
   342            Int                id;             /* timer id. */
   343            EmulationMode      emulationModeInit; /* initial emu mode */
   344            ITimer.RunMode     runMode;        /* timer mode */
   345            ITimer.StartMode   startMode;      /* timer mode */
   346            UInt32             period;         /* period */
   347            ITimer.PeriodType  periodType;
   348            UInt16             prescale;       /* prescale */
   349            UInt               intNum;         /* intr num */
   350            UArg               arg;            /* tickFxn arg*/
   351            Hwi.FuncPtr        tickFxn;        /* tickFxn */
   352            Types.FreqHz       extFreq;
   353            Hwi.Handle         hwi;
   354        }
   355    
   356        struct Module_State {
   357            Char   availMask;                       /* Available peripherals */
   358            Handle staticTimers[NUM_TIMER_DEVICES]; /* Array of statically created
   359                                                     * timer handles based on id */
   360        }
   361    }
   362    /*
   363     *  @(#) ti.sysbios.family.c28; 2, 0, 0, 0,511; 2-24-2012 11:39:50; /db/vtree/library/trees/avala/avala-q28x/src/ xlibrary
   364    
   365     */
   366