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