1    /*
     2     * Copyright (c) 2012-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     *  ======== ITimer.xdc ========
    34     *
    35     *
    36     */
    37    
    38    import xdc.runtime.Types;
    39    
    40    /*
    41     * See SequenceInTimerAPIs.txt for details on how to implement 
    42     * this interface
    43     */
    44    
    45    /*!
    46     *  ======== ITimer ========
    47     *  Interface for Timer Peripherals Manager.
    48     */
    49    
    50    interface ITimer
    51    {
    52        /*! Timer tick function prototype */
    53        typedef Void (*FuncPtr)(UArg);
    54    
    55        /*! Const used to specify any timer */
    56        const UInt ANY = ~0;
    57    
    58        /*! 
    59         *  Timer Start Modes
    60         *
    61         *  @c(StartMode_AUTO)
    62         *  Statically created/constructed Timers will be started in BIOS_start().
    63         *  Dynamically created Timers will start at create() time. This includes
    64         *  timers created before BIOS_start().
    65         *
    66         *  @c(StartMode_USER)
    67         *  Timer will be started by the user using start().
    68         */
    69        enum StartMode {
    70            StartMode_AUTO,         /*! timer starts automatically */
    71            StartMode_USER          /*! timer will be started by user */
    72        };
    73    
    74        /*! 
    75         *  Timer Run Modes
    76         *
    77         *  @c(RunMode_CONTINUOUS)
    78         *  Timer is periodic and runs continuously.
    79         *
    80         *  @c(RunMode_ONESHOT)
    81         *  Timer runs for a single period value and stops.
    82         *
    83         *  @c(RunMode_DYNAMIC)
    84         *  Timer is dynamically reprogrammed for the next required tick.
    85         *
    86         */
    87        enum RunMode {
    88            RunMode_CONTINUOUS,     /*! periodic and continuous */
    89            RunMode_ONESHOT,        /*! one-shot */
    90            RunMode_DYNAMIC         /*! dynamically reprogrammed (available on subset of devices) */
    91        };
    92    
    93        /*! 
    94         *  Timer Status
    95         *
    96         *  @c(Status_INUSE)
    97         *  Timer is in use. A timer is marked in use from the time it gets 
    98         *  created to the time it gets deleted.
    99         *
   100         *  @c(Status_FREE)
   101         *  Timer is free and can be acquired using create.
   102         */
   103        enum Status {
   104            Status_INUSE,           /*! timer in use */
   105            Status_FREE             /*! timer is free */
   106        };
   107    
   108        /*! 
   109         *  ======== PeriodType ========
   110         *  Timer period units
   111         *
   112         *  @c(PeriodType_MICROSECS)
   113         *  Period value is in microseconds.
   114         *
   115         *  @c(PeriodType_COUNTS)
   116         *  Period value is in counts.
   117         */
   118        enum PeriodType {
   119            PeriodType_MICROSECS,   /*! period in microsecs */
   120            PeriodType_COUNTS       /*! period in counts */
   121        };
   122    
   123        /*! 
   124         *  @_nodoc
   125         *  Timer supports RunMode_DYNAMIC?
   126         *
   127         *  Default is false.  Can be overriden by Timer drivers that indeed 
   128         *  support RunMode_DYNAMIC.
   129         */
   130        metaonly config Bool supportsDynamic = false;
   131    
   132        /*! 
   133         *  @_nodoc
   134         *  Default to RunMode_DYNAMIC?
   135         *
   136         *  Default is false.  Can be overriden by Timer drivers that support
   137         *  RunMode_DYNAMIC, who want DYNAMIC mode to be used by default.
   138         */
   139        metaonly config Bool defaultDynamic = false;
   140    
   141        /*! 
   142         *  ======== getNumTimers ========
   143         *  Returns number of timer peripherals on the platform.
   144         *
   145         *  @b(returns)     Number of timer peripherals.
   146         */
   147        @DirectCall
   148        UInt getNumTimers();
   149    
   150        /*! 
   151         *  ======== getStatus ========
   152         *  Returns timer status (free or in use).
   153         *
   154         *  @b(returns)     timer status
   155         */
   156        @DirectCall
   157        Status getStatus(UInt id);
   158    
   159        /*! 
   160         *  ======== startup ========
   161         *  @_nodoc
   162         *  Startup function to be called during BIOS_start
   163         *
   164         *  This function starts statically created timers with
   165         *  startMode = StartMode_AUTO.
   166         */
   167        @DirectCall
   168        Void startup();
   169    
   170        /*!
   171         *  @_nodoc
   172         *  ======== getFreqMeta ========
   173         *  Return timer frequency in Hz
   174         *
   175         *  This is the effective frequency of the clock incrementing the timer
   176         *  counter register after all scaling factors are taken into account.
   177         *  (including pre-scalars).
   178         */
   179        metaonly Types.FreqHz getFreqMeta(UInt id);
   180    
   181    instance:
   182    
   183        /*!
   184         *  ======== create ========
   185         *  Create a timer.
   186         *
   187         *  Create could fail if timer peripheral is unavailable. To
   188         *  request any available timer use {@link #ANY} as the id.
   189         *  TimerId's are logical ids. The family-specific implementations
   190         *  map the ids to physical peripherals.
   191         *
   192         *  @param(id)      Timer id ranging from 0 to a platform specific value,
   193         *                  or {@link #ANY}
   194         *  @param(tickFxn) function that runs upon timer expiry.
   195         */
   196        @DirectCall
   197        create(Int id, FuncPtr tickFxn);
   198    
   199        /*!
   200         *  Timer run mode
   201         *
   202         *  Default is {@link #RunMode_CONTINUOUS}.
   203         */
   204        config RunMode runMode = RunMode_CONTINUOUS;
   205    
   206        /*!
   207         *  Timer start mode
   208         *
   209         *  Default is {@link #StartMode_AUTO}.
   210         */
   211        config StartMode startMode = StartMode_AUTO;
   212    
   213        /*!
   214         *  Argument for tick function
   215         *
   216         *  Default is null.
   217         */
   218        config UArg arg = null;
   219    
   220        /*!
   221         *  Period of a tick
   222         *
   223         *  The period can be specified in timer counts or microseconds
   224         *  and its default value is 0.
   225         *
   226         *  The implementation of ITimer will support a period of UInt32
   227         *  timer counts and use pre-scalars if necessary.
   228         */
   229        config UInt32 period = 0;
   230    
   231        /*!
   232         *  Period type
   233         *
   234         *  Default is PeriodType_MICROSECS
   235         */
   236        config PeriodType periodType = PeriodType_MICROSECS;
   237    
   238        /*!
   239         *  Timer frequency
   240         *
   241         *  This parameter is meaningfull only on platforms where the timer's
   242         *  input clock can be changed. If value is left at zero, then input clock
   243         *  to the timer clock is assumed.
   244         *
   245         *  This value is used to convert timer ticks to real time units; seconds,
   246         *  milliseconds, etc.
   247         */
   248        config xdc.runtime.Types.FreqHz extFreq  = {lo:0, hi:0};
   249    
   250        /*!
   251         *  @_nodoc
   252         *  ======== getMaxTicks ========
   253         *  Gets the maximum number of timer ticks that can be skipped (for Clock
   254         *  tick suppression), given the current timer configuration.
   255         *
   256         *  This API is used internally by SYS/BIOS for dynamic Clock tick
   257         *  suppression.  It is not intended to be used for any other purpose.
   258         */
   259        @DirectCall
   260        UInt32 getMaxTicks(UInt32 periodCounts);
   261    
   262        /*!
   263         *  @_nodoc
   264         *  ======== setNextTick ========
   265         *  Dynamically reprograms the timer with a new period value,
   266         *  corresponding to the next required tick.  The timer is left running
   267         *  after the call, and it does not need to be stopped and restarted by
   268         *  the caller.
   269         *
   270         *  This API is used internally by SYS/BIOS for dynamic Clock tick
   271         *  suppression.  It is not intended to be used for any other purpose.
   272         *
   273         *  @param(newPeriod)       new timer period, in units of timer counts
   274         *  @param(countsPerTick)   timer counts corresponding to a single tick
   275         */
   276        @DirectCall
   277        Void setNextTick(UInt32 newPeriod, UInt32 countsPerTick);
   278    
   279        /*!
   280         *  ======== start ========
   281         *  Reload and start the timer
   282         *
   283         *  Thread safety must be observed when using the {@link #start}
   284         *  and {@link #stop} APIs to avoid possible miss-
   285         *  configuration of the timers and unintended behaviors.
   286         *  To protect against re-entrancy, surround the start/stop invocations
   287         *  with {@link ti.sysbios.hal.Hwi#disable Hwi_disable()} and
   288         *  {@link ti.sysbios.hal.Hwi#restore Hwi_restore()} calls:
   289         *
   290         *  @p(code)
   291         *  // disable interrupts if an interrupt could lead to
   292         *  // another call to Timer_start().
   293         *  key = Hwi_disable();
   294         *  Timer_stop();
   295         *  ...
   296         *  Timer_start();
   297         *  Hwi_restore(key);
   298         *  @p
   299         *
   300         *  @a(side effects)
   301         *  Enables the timer's interrupt.
   302         */
   303        @DirectCall
   304        Void start();
   305    
   306        /*!
   307         *  ======== stop ========
   308         *  Stop the timer
   309         *
   310         *  Thread safety must be observed when using the {@link #start}
   311         *  and {@link #stop} APIs to avoid possible miss-
   312         *  configuration of the timers and unintended behaviors.
   313         *  To protect against re-entrancy, surround the start/stop invocations
   314         *  with {@link ti.sysbios.hal.Hwi#disable Hwi_disable()} and
   315         *  {@link ti.sysbios.hal.Hwi#restore Hwi_restore()} calls:
   316         *
   317         *  @p(code)
   318         *  // disable interrupts if an interrupt could lead to
   319         *  // another call to Timer_start().
   320         *  key = Hwi_disable();
   321         *  Timer_stop();
   322         *  ...
   323         *  Timer_start();
   324         *  Hwi_restore(key);
   325         *  @p
   326         *
   327         *  @a(side effects)
   328         *  Disables the timer's interrupt.
   329         */
   330        @DirectCall
   331        Void stop();
   332    
   333        /*!
   334         *  ======== setPeriod ========
   335         *  Set timer period specified in timer counts
   336         *
   337         *  Timer_setPeriod() invokes Timer_stop() prior to setting the period
   338         *  and leaves the timer in the stopped state.
   339         *
   340         *  To dynamically change the period of a timer you must
   341         *  protect against re-entrancy by disabling interrupts.
   342         *  Use the following call sequence to guarantee proper results:
   343         *
   344         *  @p(code)
   345         *  // disable interrupts if an interrupt could lead to
   346         *  // another call to Timer_start().
   347         *  key = Hwi_disable();
   348         *  Timer_setPeriod(period);
   349         *  Timer_start();
   350         *  Hwi_restore(key);
   351         *  @p
   352         *
   353         *  ITimer implementation must support UInt32 and use pre-scalars whenever
   354         *  necessary
   355         *
   356         *  @a(side effects)
   357         *  Calls Timer_stop(), and disables the timer's interrupt.
   358         *
   359         *  @param(period)          period in timer counts
   360         */
   361        @DirectCall
   362        Void setPeriod(UInt32 period);
   363    
   364        /*!
   365         *  ======== setPeriodMicroSecs ========
   366         *  Set timer period specified in microseconds.
   367         *
   368         *  A best-effort method will be used to set the period register.
   369         *  There might be a slight rounding error based on resolution of timer
   370         *  period register. If the timer frequency cannot support the requested
   371         *  period, i.e. the timer period register cannot support the requested
   372         *  period, then this function returns false.
   373         *
   374         *  Timer_setPeriodMicroSecs() invokes Timer_stop() prior to setting
   375         *  the period and leaves the timer in the stopped state.
   376         *
   377         *  To dynamically change the period of a timer you must
   378         *  protect against re-entrancy by disabling interrupts.
   379         *  Use the following call sequence to guarantee proper results:
   380         *
   381         *  @p(code)
   382         *  // disable interrupts if an interrupt could lead to
   383         *  // another call to Timer_start().
   384         *  key = Hwi_disable();
   385         *  Timer_setPeriodMicroSecs(period);
   386         *  Timer_start();
   387         *  Hwi_restore(key);
   388         *  @p
   389         *
   390         *  @param(period)          period in microseconds
   391         */
   392        @DirectCall
   393        Bool setPeriodMicroSecs(UInt32 microsecs);
   394    
   395        /*!
   396         *  ======== getPeriod ========
   397         *  Get timer period in timer counts
   398         *
   399         *  @b(returns)     period in timer counts
   400         */
   401        @DirectCall
   402        UInt32 getPeriod();
   403    
   404        /*!
   405         *  ======== getCount ========
   406         *  Read timer counter register
   407         *
   408         *  @b(returns)     timer counter value
   409         */
   410        @DirectCall
   411        UInt32 getCount();
   412    
   413        /*!
   414         *  ======== getFreq ========
   415         *  Return timer frequency in Hz
   416         *
   417         *  This is the effective frequency of the clock incrementing the timer
   418         *  counter register after all scaling factors are taken into account.
   419         *  (including pre-scalars).
   420         *
   421         *  @param(freq)    frequency in Hz
   422         */
   423        @DirectCall
   424        Void getFreq(xdc.runtime.Types.FreqHz *freq);
   425    
   426        /*!
   427         *  ======== getFunc ========
   428         *  Get Timer function and arg
   429         *
   430         *  @param(arg)     pointer for returning Timer's function argument
   431         *  @b(returns)     Timer's function
   432         */
   433        @DirectCall
   434        FuncPtr getFunc(UArg *arg);
   435    
   436        /*!
   437         *  ======== setFunc ========
   438         *  Overwrite Timer function and arg
   439         *
   440         *  Replaces a Timer object's tickFxn function originally
   441         *  provided in {@link #create}.
   442         *
   443         *  @param(fxn)     pointer to function
   444         *  @param(arg)     argument to function
   445         */
   446        @DirectCall
   447        Void setFunc(FuncPtr fxn, UArg arg);
   448    
   449        /*!
   450         *  ======== trigger ========
   451         *  Trigger timer function
   452         *
   453         *  @_nodoc
   454         *  Timer runs for specified number of cycles. The runMode
   455         *  must be Mode_ONESHOT.
   456         *
   457         *  This function should interrupt the cpu after specified number of
   458         *  cpu cycles.
   459         *
   460         *  The last instruction of trigger will start the timer. Depending on how
   461         *  the code is compiled, there may be one or more instructions in between
   462         *  the timer start and client code. The number of instructions specified
   463         *  is counted from when the timer is started.
   464         *
   465         *  @param(instructions)    cpu cycles
   466         */
   467        @DirectCall
   468        Void trigger(UInt32 cycles);
   469    
   470        /*!
   471         *  ======== getExpiredCounts ========
   472         *  Get current timer counter
   473         *
   474         *  @_nodoc
   475         *  Reads timer counter and adds period if IFR was set 
   476         *  before counter read. Used exclusively by TimestampProvider.
   477         *
   478         *  Must be called with interrupts disabled.
   479         *
   480         *  @b(returns)     expired counts.
   481         */
   482        @DirectCall
   483        UInt32 getExpiredCounts();
   484    
   485    }