1    /*
     2     * Copyright (c) 2019, 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    package ti.sysbios.family.arm.f2838x;
    37    
    38    import xdc.rov.ViewInfo;
    39    
    40    import xdc.runtime.Error;
    41    import xdc.runtime.Assert;
    42    import xdc.runtime.Types;
    43    import ti.sysbios.interfaces.ITimer;
    44    import ti.sysbios.family.arm.m3.Hwi;
    45    
    46    /*!
    47     *  ======== Timer ========
    48     *  Timer peripheral manager for the CPU timers (the C28-type timers
    49     *  provisioned for the CM).
    50     *
    51     *  @p(html)
    52     *  <h3> CPU Timers </h3>
    53     *  @p(blist)
    54     *  - The CM has three 32-bit CPU timers.
    55     *  - The CPU timers count downward from 'period' to 0; however, Timer_getCount
    56     *    will count upward.
    57     *  - The CPU timer supports an optional 16-bit prescaler. The prescaler
    58     *    effectively sets the period of the timer tick; the prescaler 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 #reconfig}                </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    83     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    85     *    <tr><td> {@link #setPrescale}             </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #start}                   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    87     *    <tr><td> {@link #stop}                    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    88     *    <tr><td colspan="6"> Definitions: <br />
    89     *       <ul>
    90     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    91     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    92     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    93     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    94     *           <ul>
    95     *             <li> In your module startup after this module is started (e.g. Timer_Module_startupDone() returns TRUE). </li>
    96     *             <li> During xdc.runtime.Startup.lastFxns. </li>
    97     *             <li> During main().</li>
    98     *             <li> During BIOS.startupFxns.</li>
    99     *           </ul>
   100     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   101     *           <ul>
   102     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   103     *             <li> In your module startup before this module is started (e.g. Timer_Module_startupDone() returns FALSE).</li>
   104     *           </ul>
   105     *       </ul>
   106     *    </td></tr>
   107     *  </table>
   108     *  @p
   109     */
   110    
   111    @ModuleStartup          /* To configure static timers */
   112    @InstanceInitStatic
   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        prescaler;
   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        };
   150    
   151        /*! @_nodoc */
   152        @Facet
   153        metaonly config ViewInfo.Instance rovViewInfo =
   154            ViewInfo.create({
   155                viewMap: [
   156                    ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
   157                    ['Device', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitDevice', structName: 'DeviceView'}],
   158                ]
   159            });
   160    
   161        /*!
   162         *  Assert raised in Timer_create when timer id specified is not supported.
   163         */
   164        config Assert.Id A_invalidTimer = {
   165            msg: "A_invalidTimer: Timer id must be 0-2"
   166        };
   167    
   168        /*!
   169         *  Error raised in Timer_create when timer requested is in use.
   170         */
   171        config Error.Id E_notAvailable = {
   172            msg: "E_notAvailable: Timer not available %d"
   173        };
   174    
   175        /*!
   176         *  Assert raised in Timer_create if an invalid RunMode is requested.
   177         */
   178        config Assert.Id A_invalidRunMode = {
   179            msg: "A_invalidRunMode: Invalid RunMode"
   180        };
   181    
   182        /*!
   183         *  Assert raised when period requested is not supported.
   184         */
   185        config Assert.Id E_cannotSupport = {
   186            msg: "E_cannotSupport: Timer cannot support requested period"
   187        };
   188    
   189        /*!
   190         *  ======== anyMask ========
   191         *  Available mask to be used when select = Timer_ANY
   192         */
   193        config UInt anyMask = 0x7;
   194    
   195        /*! Timer enable function type definition. */
   196        typedef Void (*TimerEnableFuncPtr)(Int);
   197    
   198        /*! Timer disable function type definition. */
   199        typedef Void (*TimerDisableFuncPtr)(Int);
   200    
   201        /*!
   202         *  ======== enableFunc ========
   203         *  Pointer to Timer enable callback function
   204         *
   205         *  Timer enable callback function enables the timer.
   206         */
   207        config TimerEnableFuncPtr enableFunc = null;
   208    
   209        /*!
   210         *  ======== disableFunc ========
   211         *  Pointer to Timer disable callback function
   212         *
   213         *  Timer disable callback function disables the timer.
   214         */
   215        config TimerDisableFuncPtr disableFunc = null;
   216    
   217    instance:
   218    
   219        /*!
   220         *  ======== emulationModeInit ========
   221         *  Initial timer emulation mode. Default hard stop.
   222         *
   223         *  Determines timer state at a software breakpoint. If 'free' is 1, the
   224         *  timer will continue to run, and the value of 'soft' doesn't matter.
   225         *  When 'free' is 0 and 'soft' is 1, the timer runs down to 0 then stops.
   226         *  When 'free' is 0 and 'soft' is 0, the timer halts.
   227         *
   228         *  @p(html)
   229         *  <pre>
   230         *  FREE   SOFT
   231         *  0      0      Stop after next timer decrement. (Hard stop)
   232         *  0      1      Stop after timer runs down to 0. (Soft stop)
   233         *  1      x      Continue running the timer.
   234         *  </pre>
   235         */
   236        config EmulationMode emulationModeInit = {free: 0, soft: 0};
   237    
   238        /*!
   239         *  ======== prescale ========
   240         *  Prescale factor.
   241         *
   242         *  The prescale factor determines the length of a timer tick.
   243         *  If a prescale of 10 is specified, a timer tick will occur
   244         *  every 11 cycles.
   245         *
   246         *  If the timer is used as a counter, the prescale factor determines
   247         *  the period between counts. Otherwise, the prescale factor can be used
   248         *  to achieve longer timer periods: with a prescale specified, the actual
   249         *  period is (period * prescale+1).
   250         */
   251        config UInt16 prescale = 0;
   252    
   253        /*!
   254         *  ======== hwiParams ========
   255         *  Parameters for the Hwi object created for the Timer ISR.
   256         *
   257         *  The mask setting for the Hwi object should include SELF to prevent
   258         *  nested timer interrupts.
   259         */
   260        config Hwi.Params *hwiParams = null;
   261    
   262        /*!
   263         *  ======== getCount ========
   264         *  Returns the number of counts that have passed.
   265         *
   266         *  The 28x timer counts downward from the period to 0, but getCount
   267         *  subtracts the timer counter value from the period so that getCount
   268         *  counts upward instead of downward.
   269         *
   270         *  @b(returns) timer counts, counting upward from 0
   271         */
   272        override UInt32 getCount();
   273    
   274        /*!
   275         *  ======== setPreScale ========
   276         *  Set timer prescale value.
   277         *
   278         *  This function sets the value of the prescaler, and will also reload
   279         *  the timer counter and prescale registers.
   280         *
   281         *  The prescaler decrements with each timer clock source cycle until it
   282         *  reaches zero, then the timer's count is decremented by one. The
   283         *  prescaler has the effect of setting the rate of the timer tick.
   284         *
   285         *  @param(preScaler) The value to set the prescale period to.
   286         */
   287        Void setPrescale(UInt16 preScaler);
   288    
   289        /*!
   290         *  ======== getPrescale ========
   291         *  Get timer prescale value.
   292         *
   293         *  This is not the prescale count, but the period of the prescaler.
   294         *
   295         *  @b(returns) prescale value
   296         */
   297        UInt16 getPrescale();
   298    
   299        /*!
   300         *  ======== getPrescaleCount ========
   301         *  Reads timer prescale counter.
   302         *
   303         *  The prescale counter counts down from prescale to 0, but
   304         *  getPrescaleCount subtracts the counter value from the period so that
   305         *  this function counts upward instead of downward.
   306         *
   307         *  @b(returns) prescale counter, counting upward from 0
   308         */
   309        UInt16 getPrescaleCount();
   310    
   311        /*!
   312         *  ======== reconfig ========
   313         *  Used to modify timer instances at runtime.
   314         *
   315         *  @param(timerParams)     timer Params
   316         *  @param(tickFxn)         functions that runs when timer expires
   317         */
   318        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   319    
   320    internal:   /* not for client use */
   321    
   322        /*!
   323         *  ======== enableCM ========
   324         */
   325        Void enableCM(Int id);
   326    
   327        /*!
   328         *  ======== disableCM ========
   329         */
   330        Void disableCM(Int id);
   331    
   332        /*
   333         *  ======== postInit ========
   334         *  finish initializing static and dynamic Timers
   335         */
   336        Int postInit(Object *timer, Error.Block *eb);
   337    
   338        /*
   339         *  ======== stopAndClear ========
   340         */
   341        Void stopAndClear(Object *timer);
   342    
   343        /*
   344         *  ======== checkOverflow ========
   345         */
   346        Bool checkOverflow(UInt32 a, UInt32 b);
   347    
   348        /*!
   349         *  ======== oneShotStub ========
   350         *  This stub implements oneShot mode by stopping the timer and clearing
   351         *  the CPU IFR bit.
   352         *
   353         *  @param(arg) The timer object
   354         */
   355        Void oneShotStub(UArg arg);
   356    
   357        /*!
   358         *  ======== startupNeeded ========
   359         *  Flag used to prevent Module_startup and Timer_startup code from being
   360         *  brought in unnecessarily. Flag is set if there are any static Timer
   361         *  instances.
   362         */
   363        config UInt startupNeeded = false;
   364    
   365        config UInt8 intNumDef[3];
   366    
   367        struct Instance_State {
   368            Int                id;             /* timer id. */
   369            EmulationMode      emulationModeInit; /* initial emu mode */
   370            ITimer.RunMode     runMode;        /* timer mode */
   371            ITimer.StartMode   startMode;      /* timer mode */
   372            UInt32             period;         /* period */
   373            ITimer.PeriodType  periodType;
   374            UInt16             prescale;       /* prescale */
   375            UInt               intNum;         /* intr num */
   376            UArg               arg;            /* tickFxn arg*/
   377            Hwi.FuncPtr        tickFxn;        /* tickFxn */
   378            Types.FreqHz       extFreq;
   379            Hwi.Handle         hwi;
   380        }
   381    
   382        struct Module_State {
   383            Char   availMask;                       /* Available peripherals */
   384            Handle staticTimers[NUM_TIMER_DEVICES]; /* Array of statically created
   385                                                     * timer handles based on id */
   386        }
   387    }