1    /*
     2     * Copyright (c) 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     *  ======== Timer.xdc ========
    34     *
    35     *
    36     */
    37    
    38    package ti.sysbios.timers.gptimer;
    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 general purpose timer (gptimer) 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 gptimer Timer  module supports the timer in 'one shot' and 'continuous'
    57     *  modes.
    58     *
    59     *  In 'one shot' mode, a timer function will "fire" (run) when the timer period
    60     *  expires (counts down to zero). In 'one shot' mode this will only happen
    61     *  once.  In 'continuous' mode, the specified timer function will "fire" every
    62     *  time the period expires, throughout the lifetime of the program.  When the
    63     *  period expires in 'continuous mode', the period is then reset to its
    64     *  original value and then begins counting down to zero again.  At this point
    65     *  the timer function will fire again and the cycle repeats itself.
    66     *
    67     *  @p(html)
    68     *  <h3> Calling Context </h3>
    69     *  <table border="1" cellpadding="3">
    70     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    71     *    </colgroup>
    72     *
    73     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    74     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    75     *    <!--                                    -->
    76     *    <tr><td> {@link #getNumTimers}            </td><td>   Y    </td>
    77     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    78     *    <tr><td> {@link #getStatus}               </td><td>   Y    </td>
    79     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    80     *    <tr><td> {@link #Params_init}             </td><td>   Y    </td>
    81     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    82     *    <tr><td> {@link #construct}               </td><td>   Y    </td>
    83     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    84     *    <tr><td> {@link #create}                  </td><td>   N    </td>
    85     *    <td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    86     *    <tr><td> {@link #delete}                  </td><td>   N    </td>
    87     *    <td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    88     *    <tr><td> {@link #destruct}                </td><td>   Y    </td>
    89     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    90     *    <tr><td> {@link #getCount}                </td><td>   Y    </td>
    91     *    <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    92     *    <tr><td> {@link #getFreq}                 </td><td>   Y    </td>
    93     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    94     *    <tr><td> {@link #getFunc}                 </td><td>   Y    </td>
    95     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    96     *    <tr><td> {@link #getPeriod}               </td><td>   Y    </td>
    97     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    98     *    <tr><td> {@link #reconfig}                </td><td>   Y    </td>
    99     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   100     *    <tr><td> {@link #setFunc}                 </td><td>   Y    </td>
   101     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   102     *    <tr><td> {@link #setPeriod}               </td><td>   Y    </td>
   103     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   104     *    <tr><td> {@link #setPeriodMicroSecs}      </td><td>   Y    </td>
   105     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
   106     *    <tr><td> {@link #start}                   </td><td>   Y    </td>
   107     *    <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   108     *    <tr><td> {@link #stop}                    </td><td>   Y    </td>
   109     *    <td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
   110     *    <tr><td colspan="6"> Definitions: <br />
   111     *       <ul>
   112     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   113     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   114     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   115     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   116     *           <ul>
   117     *             <li> In your module startup after this module is started
   118     *    (e.g. Timer_Module_startupDone() returns TRUE). </li>
   119     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   120     *             <li> During main().</li>
   121     *             <li> During BIOS.startupFxns.</li>
   122     *           </ul>
   123     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   124     *           <ul>
   125     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   126     *             <li> In your module startup before this module is started
   127     *    (e.g. Timer_Module_startupDone() returns FALSE).</li>
   128     *           </ul>
   129     *       </ul>
   130     *    </td></tr>
   131     *
   132     *  </table>
   133     *  @p
   134     *
   135     *  @p(html)
   136     *  <h3> Timer Mapping Tables </h3>
   137     *  <p>
   138     *  The Timer module allows the user to use and configure the various timers
   139     *  that exist on a particular device.  This is achieved by specifying a timer
   140     *  ID when calling {@link ti.sysbios.hal.Timer#Timer_create}.
   141     *  However, the timer ID
   142     *  specified may not always map to that timer; for example, specifying an ID
   143     *  value of 1 does not necessarily mean that this will map to "GPTimer1".
   144     *  These tables are provided to show which timers map to which timer IDs.
   145     *  </p>
   146     *  {@link ./doc-files/TimerTables.html Timer Mapping Tables}
   147     *  @p
   148     *
   149     */
   150    @InstanceFinalize       /* To cleanup */
   151    @InstanceInitError      /* To report unavailability of timer */
   152    @ModuleStartup          /* to configure static timers */
   153    
   154    module Timer inherits ti.sysbios.interfaces.ITimer
   155    {
   156        /*! Max value of Timer period for PeriodType_COUNTS*/
   157        const UInt MAX_PERIOD = 0xffffffff;
   158    
   159        /*! L4 interface Configuration Register (TIOCP_CFG). */
   160        struct TiocpCfg {
   161            Bits8 autoidle;  /*! 0=L4 interface is free running; 1=Automatic */
   162            Bits8 softreset; /*! 0=normal mode; 1=soft reset */
   163            Bits8 enawakeup; /*! 0=no wakeup; 1=wake-up line assertion enabled */
   164            Bits16 idlemode; /*! 0=force-idle; 1=no-idle; 2=Smart-idle */
   165            Bits8 emufree;   /*! 0=counter frozen; 1=counter free-running */
   166            Bits16 clockactivity; /*! Clock activity during wakeup mode period */
   167        };
   168    
   169        /*! Interrupt Enable Register (TIER). */
   170        struct Tier {
   171            Bits8 mat_it_ena;  /*! Enable match interrupt */
   172            Bits8 ovf_it_ena;  /*! Enable overflow interrupt */
   173            Bits8 tcar_it_ena; /*! Enable capture interrupt */
   174        };
   175    
   176        /*! WakepUp Enable Register (TWER). */
   177        struct Twer {
   178            Bits8 mat_wup_ena;  /*! Enable match wake-up */
   179            Bits8 ovf_wup_ena;  /*! Enable overflow wake-up */
   180            Bits8 tcar_wup_ena; /*! Enable capture wake-up */
   181        };
   182    
   183        /*! Control Register (TCLR). */
   184        struct Tclr {
   185            Bits32 ptv; /*! Trigger output mode */
   186            Bits8 pre;  /*! Prescalar enable */
   187            Bits8 ce;   /*! Compare enable */
   188            Bits8 scpwm;/*! Pulse-width modulation */
   189            Bits16 tcm; /*! Transition capture mode */
   190            Bits16 trg; /*! Trigger output mode */
   191            Bits8 pt;   /*! Pulse or toggle select bit */
   192            Bits8 captmode; /*! Capture mode select bit */
   193            Bits8 gpocfg; /*! PWM output/event detection input pin */
   194        };
   195    
   196        /*! L4 Interface Synchronization Control Register (TSICR). */
   197        struct Tsicr {
   198            Bits8 sft;    /*! Reset software functional registers */
   199            Bits8 posted; /*! Posted mode selection */
   200        };
   201    
   202        /*! Timer Settings. */
   203        metaonly struct TimerSetting {
   204            Bool master;    /*! specifies whether this is the master */
   205            Ptr baseAddr;   /*! specify the base address  */
   206            Int intNum;     /*! specify which interrupt vector */
   207            String name;    /*! specify the timer name */
   208        };
   209    
   210        /*!
   211         *  ======== BasicView ========
   212         *  @_nodoc
   213         */
   214        metaonly struct BasicView {
   215            Ptr         halTimerHandle;
   216            String      label;
   217            UInt        id;
   218            String      name;
   219            String      startMode;
   220            String      runMode;
   221            UInt        period;
   222            String      periodType;
   223            UInt        intNum;
   224            String      tickFxn[];
   225            UArg        arg;
   226            String      extFreqLow;
   227            String      extFreqHigh;
   228            String      hwiHandle;
   229        };
   230    
   231        /*!
   232         *  ======== DeviceView ========
   233         *  @_nodoc
   234         */
   235        metaonly struct DeviceView {
   236            UInt        id;
   237            String      deviceAddr;
   238            UInt        intNum;
   239            String      runMode;
   240            String      timerState;
   241            UInt        period;
   242            String      currCount;
   243            String      remainingCount;
   244        };
   245    
   246        /*!
   247         *  ======== ModuleView ========
   248         *  @_nodoc
   249         */
   250        metaonly struct ModuleView {
   251            String          availMask;      /* avaliable 32-bit timer halves */
   252            String intFrequency;    /* internal frequency in Hz */
   253        }
   254    
   255        /*!
   256         *  ======== rovViewInfo ========
   257         *  @_nodoc
   258         */
   259        @Facet
   260        metaonly config ViewInfo.Instance rovViewInfo =
   261            ViewInfo.create({
   262                viewMap: [
   263                [
   264                    'Basic',
   265                    {
   266                        type: ViewInfo.INSTANCE,
   267                        viewInitFxn: 'viewInitBasic',
   268                        structName: 'BasicView'
   269                    }
   270                ],
   271                [
   272                    'Device',
   273                    {
   274                        type: ViewInfo.INSTANCE,
   275                        viewInitFxn: 'viewInitDevice',
   276                        structName: 'DeviceView'
   277                    }
   278                ],
   279                [
   280                    'Module',
   281                    {
   282                        type: ViewInfo.MODULE,
   283                        viewInitFxn: 'viewInitModule',
   284                        structName: 'ModuleView'
   285                    }
   286                ],
   287                ]
   288            });
   289    
   290        /*!
   291         *  Error raised when timer id specified is not supported.
   292         */
   293        config Error.Id E_invalidTimer = {
   294            msg: "E_invalidTimer: Invalid Timer Id %d"
   295        };
   296    
   297        /*!
   298         *  Error raised when timer requested is in use
   299         */
   300        config Error.Id E_notAvailable  = {
   301            msg: "E_notAvailable: Timer not available %d"
   302        };
   303    
   304        /*!
   305         *  Error raised when period requested is not supported
   306         */
   307        config Error.Id E_cannotSupport = {
   308            msg: "E_cannotSupport: Timer cannot support requested period %d"
   309        };
   310    
   311        /*!
   312         *  ======== anyMask ========
   313         *  Available mask to be used when select = Timer_ANY.
   314         *
   315         *  Default value is device specific.
   316         */
   317        config Bits32 anyMask;
   318    
   319        /*!
   320         *  ======== timerSettings ========
   321         *  Global Control configuration for each physical timer.
   322         */
   323        metaonly config TimerSetting timerSettings[] = [];
   324    
   325        /*!
   326         *  ======== intFreq ========
   327         *  Default internal timer input clock frequency.
   328         */
   329        metaonly config Types.FreqHz intFreq = {lo: 0, hi: 0};
   330    
   331        /*!
   332         *  ======== stub  ========
   333         *  @_nodoc
   334         *  Timer requires acknowledgement
   335         *
   336         *  @param(arg)     timer object passed in as argument.
   337         */
   338        @DirectCall
   339        Void stub(UArg arg);
   340    
   341    
   342    instance:
   343    
   344        /*!
   345         *  ======== tiocpCfg ========
   346         */
   347        config TiocpCfg tiocpCfg = {autoidle: 0, softreset: 1, enawakeup: 0,
   348            idlemode: 0, emufree: 0, clockactivity: 0};
   349    
   350        /*!
   351         *  ======== tier ========
   352         */
   353        config Tier tier = {mat_it_ena: 0, ovf_it_ena: 1, tcar_it_ena: 0};
   354    
   355        /*!
   356         *  ======== twer ========
   357         */
   358        config Twer twer = {mat_wup_ena: 0, ovf_wup_ena: 0, tcar_wup_ena: 0};
   359    
   360        /*!
   361         *  ======== tclr ========
   362         */
   363        config Tclr tclr = {ptv: 0, pre: 0, ce: 0, scpwm: 0, tcm: 0, trg: 0,
   364            pt: 0, captmode: 0, gpocfg: 0};
   365    
   366        /*!
   367         *  ======== tsicr ========
   368         */
   369        config Tsicr tsicr = {sft: 0, posted: 1};
   370    
   371        /*!
   372         *  ======== tmar ========
   373         */
   374        config UInt32 tmar = 0;
   375    
   376        /*! Hwi Params for Hwi Object. Default is null. */
   377        config Hwi.Params *hwiParams = null;
   378    
   379        /*!
   380         *  ======== reconfig ========
   381         *  Used to modify static timer instances at runtime.
   382         *
   383         *  @param(timerParams)     timer Params
   384         *  @param(tickFxn)         functions that runs when timer expires
   385         */
   386        @DirectCall
   387        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   388    
   389    
   390    internal:   /* not for client use */
   391    
   392        /*! Information about timer */
   393        struct TimerDevice {
   394            UInt intNum;
   395            UInt eventId;
   396            Ptr  baseAddr;
   397        };
   398    
   399        /*! Device-specific Timer implementation. */
   400        proxy TimerSupportProxy inherits ti.sysbios.interfaces.ITimerSupport;
   401    
   402        /*!
   403         *  ======== startupNeeded ========
   404         *  This flag is use to prevent Timer_startup code (includes postInit(),
   405         *  deviceConfig(), initDevice() to be brought in un-necessarily.
   406         */
   407        config Bool startupNeeded = false;
   408    
   409        /*!
   410         *  ======== numTimerDevices ========
   411         *  The number of logical timers on a device.
   412         */
   413        config Int numTimerDevices;
   414    
   415        /*
   416         *  ======== deviceConfig ========
   417         *  Configure the timer.
   418         */
   419        Int deviceConfig(Object *timer, Error.Block *eb);
   420    
   421        /*
   422         *  ======== initDevice ========
   423         *  reset timer to its resting state
   424         */
   425        Void initDevice(Object *timer, Error.Block *eb);
   426    
   427        /*
   428         *  ======== initObj ========
   429         *  Initialize the instance state object
   430         */
   431        Void initObj(Object *timer, FuncPtr tickFxn, const Params *timerParams);
   432    
   433        /*
   434         *  ======== postInit ========
   435         *  finish initializing static and dynamic Timers
   436         */
   437        Int postInit(Object *timer, Error.Block *eb);
   438    
   439        /*
   440         *  ======== checkOverflow ========
   441         */
   442        Bool checkOverflow(UInt32 a, UInt32 b);
   443    
   444        /*!
   445         *  ======== spinLoop ========
   446         *  used by trigger function.
   447         */
   448        Void spinLoop(UInt count);
   449    
   450        /*! Instance state structure */
   451        struct Instance_State {
   452            Bool                    staticInst;     /* statically created or not */
   453            Int                     id;             /* logical timer id. */
   454            UInt                    tiocpCfg;
   455            UInt                    tmar;
   456            UInt                    tier;
   457            UInt                    twer;
   458            UInt                    tclr;
   459            UInt                    tsicr;
   460            ITimer.RunMode          runMode;        /* timer mode */
   461            ITimer.StartMode        startMode;      /* timer mode */
   462            UInt                    period;         /* period */
   463            ITimer.PeriodType       periodType;     /* type (microsecs, inst) */
   464            UInt                    intNum;         /* intr num */
   465            UArg                    arg;            /* isrFxn arg */
   466            Hwi.FuncPtr             tickFxn;        /* Timer fxn plugged into Hwi */
   467            Types.FreqHz            extFreq;        /* ext freq */
   468            Hwi.Handle              hwi;            /* hwi inst */
   469        }
   470    
   471        /*! Module state structure */
   472        struct Module_State {
   473            Bits32          availMask;      /* avaliable 32-bit timer halves */
   474            Types.FreqHz    intFreq;        /* internal frequency in Hz */
   475            TimerDevice     device[];       /* timer device information */
   476            Handle          handles[];      /* handles based on logical id */
   477        }
   478    }