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    @ModuleStartup          /* to configure static timers */
   151    @InstanceInitStatic
   152    
   153    module Timer inherits ti.sysbios.interfaces.ITimer
   154    {
   155        /*! Max value of Timer period for PeriodType_COUNTS*/
   156        const UInt MAX_PERIOD = 0xffffffff;
   157    
   158        /*! L4 interface Configuration Register (TIOCP_CFG). */
   159        struct TiocpCfg {
   160            Bits8 autoidle;  /*! 0=L4 interface is free running; 1=Automatic */
   161            Bits8 softreset; /*! 0=normal mode; 1=soft reset */
   162            Bits8 enawakeup; /*! 0=no wakeup; 1=wake-up line assertion enabled */
   163            Bits16 idlemode; /*! 0=force-idle; 1=no-idle; 2=Smart-idle */
   164            Bits8 emufree;   /*! 0=counter frozen; 1=counter free-running */
   165            Bits16 clockactivity; /*! Clock activity during wakeup mode period */
   166        };
   167    
   168        /*! Interrupt Enable Register (TIER). */
   169        struct Tier {
   170            Bits8 mat_it_ena;  /*! Enable match interrupt */
   171            Bits8 ovf_it_ena;  /*! Enable overflow interrupt */
   172            Bits8 tcar_it_ena; /*! Enable capture interrupt */
   173        };
   174    
   175        /*! WakepUp Enable Register (TWER). */
   176        struct Twer {
   177            Bits8 mat_wup_ena;  /*! Enable match wake-up */
   178            Bits8 ovf_wup_ena;  /*! Enable overflow wake-up */
   179            Bits8 tcar_wup_ena; /*! Enable capture wake-up */
   180        };
   181    
   182        /*! Control Register (TCLR). */
   183        struct Tclr {
   184            Bits32 ptv; /*! Trigger output mode */
   185            Bits8 pre;  /*! Prescalar enable */
   186            Bits8 ce;   /*! Compare enable */
   187            Bits8 scpwm;/*! Pulse-width modulation */
   188            Bits16 tcm; /*! Transition capture mode */
   189            Bits16 trg; /*! Trigger output mode */
   190            Bits8 pt;   /*! Pulse or toggle select bit */
   191            Bits8 captmode; /*! Capture mode select bit */
   192            Bits8 gpocfg; /*! PWM output/event detection input pin */
   193        };
   194    
   195        /*! L4 Interface Synchronization Control Register (TSICR). */
   196        struct Tsicr {
   197            Bits8 sft;    /*! Reset software functional registers */
   198            Bits8 posted; /*! Posted mode selection */
   199        };
   200    
   201        /*! Timer Settings. */
   202        metaonly struct TimerSetting {
   203            Bool master;    /*! specifies whether this is the master */
   204            Ptr baseAddr;   /*! specify the base address  */
   205            Int intNum;     /*! specify which interrupt vector */
   206            String name;    /*! specify the timer name */
   207        };
   208    
   209        /*!
   210         *  ======== BasicView ========
   211         *  @_nodoc
   212         */
   213        metaonly struct BasicView {
   214            Ptr         halTimerHandle;
   215            String      label;
   216            UInt        id;
   217            String      name;
   218            String      startMode;
   219            String      runMode;
   220            UInt        period;
   221            String      periodType;
   222            UInt        intNum;
   223            String      tickFxn[];
   224            UArg        arg;
   225            String      extFreqLow;
   226            String      extFreqHigh;
   227            String      hwiHandle;
   228        };
   229    
   230        /*!
   231         *  ======== DeviceView ========
   232         *  @_nodoc
   233         */
   234        metaonly struct DeviceView {
   235            UInt        id;
   236            String      deviceAddr;
   237            UInt        intNum;
   238            String      runMode;
   239            String      timerState;
   240            UInt        period;
   241            String      currCount;
   242            String      remainingCount;
   243        };
   244    
   245        /*!
   246         *  ======== ModuleView ========
   247         *  @_nodoc
   248         */
   249        metaonly struct ModuleView {
   250            String          availMask;      /* avaliable 32-bit timer halves */
   251            String intFrequency;    /* internal frequency in Hz */
   252        }
   253    
   254        /*!
   255         *  ======== rovViewInfo ========
   256         *  @_nodoc
   257         */
   258        @Facet
   259        metaonly config ViewInfo.Instance rovViewInfo =
   260            ViewInfo.create({
   261                viewMap: [
   262                [
   263                    'Basic',
   264                    {
   265                        type: ViewInfo.INSTANCE,
   266                        viewInitFxn: 'viewInitBasic',
   267                        structName: 'BasicView'
   268                    }
   269                ],
   270                [
   271                    'Device',
   272                    {
   273                        type: ViewInfo.INSTANCE,
   274                        viewInitFxn: 'viewInitDevice',
   275                        structName: 'DeviceView'
   276                    }
   277                ],
   278                [
   279                    'Module',
   280                    {
   281                        type: ViewInfo.MODULE,
   282                        viewInitFxn: 'viewInitModule',
   283                        structName: 'ModuleView'
   284                    }
   285                ],
   286                ]
   287            });
   288    
   289        /*!
   290         *  Error raised when timer id specified is not supported.
   291         */
   292        config Error.Id E_invalidTimer = {
   293            msg: "E_invalidTimer: Invalid Timer Id %d"
   294        };
   295    
   296        /*!
   297         *  Error raised when timer requested is in use
   298         */
   299        config Error.Id E_notAvailable  = {
   300            msg: "E_notAvailable: Timer not available %d"
   301        };
   302    
   303        /*!
   304         *  Error raised when period requested is not supported
   305         */
   306        config Error.Id E_cannotSupport = {
   307            msg: "E_cannotSupport: Timer cannot support requested period %d"
   308        };
   309    
   310        /*!
   311         *  ======== anyMask ========
   312         *  Available mask to be used when select = Timer_ANY.
   313         *
   314         *  Default value is device specific.
   315         */
   316        config Bits32 anyMask;
   317    
   318        /*!
   319         *  ======== timerSettings ========
   320         *  Global Control configuration for each physical timer.
   321         */
   322        metaonly config TimerSetting timerSettings[] = [];
   323    
   324        /*!
   325         *  ======== intFreq ========
   326         *  Default internal timer input clock frequency.
   327         */
   328        metaonly config Types.FreqHz intFreq = {lo: 0, hi: 0};
   329    
   330        /*!
   331         *  ======== stub  ========
   332         *  @_nodoc
   333         *  Timer requires acknowledgement
   334         *
   335         *  @param(arg)     timer object passed in as argument.
   336         */
   337        Void stub(UArg arg);
   338    
   339    
   340    instance:
   341    
   342        /*!
   343         *  ======== tiocpCfg ========
   344         */
   345        config TiocpCfg tiocpCfg = {autoidle: 0, softreset: 1, enawakeup: 0,
   346            idlemode: 0, emufree: 0, clockactivity: 0};
   347    
   348        /*!
   349         *  ======== tier ========
   350         */
   351        config Tier tier = {mat_it_ena: 0, ovf_it_ena: 1, tcar_it_ena: 0};
   352    
   353        /*!
   354         *  ======== twer ========
   355         */
   356        config Twer twer = {mat_wup_ena: 0, ovf_wup_ena: 0, tcar_wup_ena: 0};
   357    
   358        /*!
   359         *  ======== tclr ========
   360         */
   361        config Tclr tclr = {ptv: 0, pre: 0, ce: 0, scpwm: 0, tcm: 0, trg: 0,
   362            pt: 0, captmode: 0, gpocfg: 0};
   363    
   364        /*!
   365         *  ======== tsicr ========
   366         */
   367        config Tsicr tsicr = {sft: 0, posted: 1};
   368    
   369        /*!
   370         *  ======== tmar ========
   371         */
   372        config UInt32 tmar = 0;
   373    
   374        /*! Hwi Params for Hwi Object. Default is null. */
   375        config Hwi.Params *hwiParams = null;
   376    
   377        /*!
   378         *  ======== reconfig ========
   379         *  Used to modify static timer instances at runtime.
   380         *
   381         *  @param(timerParams)     timer Params
   382         *  @param(tickFxn)         functions that runs when timer expires
   383         */
   384        Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
   385    
   386    
   387    internal:   /* not for client use */
   388    
   389        /*! Information about timer */
   390        struct TimerDevice {
   391            UInt intNum;
   392            UInt eventId;
   393            Ptr  baseAddr;
   394        };
   395    
   396        /*! Device-specific Timer implementation. */
   397        proxy TimerSupportProxy inherits ti.sysbios.interfaces.ITimerSupport;
   398    
   399        /*!
   400         *  ======== startupNeeded ========
   401         *  This flag is use to prevent Timer_startup code (includes postInit(),
   402         *  deviceConfig(), initDevice() to be brought in un-necessarily.
   403         */
   404        config Bool startupNeeded = false;
   405    
   406        /*!
   407         *  ======== numTimerDevices ========
   408         *  The number of logical timers on a device.
   409         */
   410        config Int numTimerDevices;
   411    
   412        /*
   413         *  ======== deviceConfig ========
   414         *  Configure the timer.
   415         */
   416        Int deviceConfig(Object *timer, Error.Block *eb);
   417    
   418        /*
   419         *  ======== initDevice ========
   420         *  reset timer to its resting state
   421         */
   422        Void initDevice(Object *timer, Error.Block *eb);
   423    
   424        /*
   425         *  ======== initObj ========
   426         *  Initialize the instance state object
   427         */
   428        Void initObj(Object *timer, FuncPtr tickFxn, const Params *timerParams);
   429    
   430        /*
   431         *  ======== postInit ========
   432         *  finish initializing static and dynamic Timers
   433         */
   434        Int postInit(Object *timer, Error.Block *eb);
   435    
   436        /*
   437         *  ======== checkOverflow ========
   438         */
   439        Bool checkOverflow(UInt32 a, UInt32 b);
   440    
   441        /*!
   442         *  ======== spinLoop ========
   443         *  used by trigger function.
   444         */
   445        Void spinLoop(UInt count);
   446    
   447        /*! Instance state structure */
   448        struct Instance_State {
   449            Bool                    staticInst;     /* statically created or not */
   450            Int                     id;             /* logical timer id. */
   451            UInt                    tiocpCfg;
   452            UInt                    tmar;
   453            UInt                    tier;
   454            UInt                    twer;
   455            UInt                    tclr;
   456            UInt                    tsicr;
   457            ITimer.RunMode          runMode;        /* timer mode */
   458            ITimer.StartMode        startMode;      /* timer mode */
   459            UInt                    period;         /* period */
   460            ITimer.PeriodType       periodType;     /* type (microsecs, inst) */
   461            UInt                    intNum;         /* intr num */
   462            UArg                    arg;            /* isrFxn arg */
   463            Hwi.FuncPtr             tickFxn;        /* Timer fxn plugged into Hwi */
   464            Types.FreqHz            extFreq;        /* ext freq */
   465            Hwi.Handle              hwi;            /* hwi inst */
   466        }
   467    
   468        /*! Module state structure */
   469        struct Module_State {
   470            Bits32          availMask;      /* avaliable 32-bit timer halves */
   471            Types.FreqHz    intFreq;        /* internal frequency in Hz */
   472            TimerDevice     device[];       /* timer device information */
   473            Handle          handles[];      /* handles based on logical id */
   474        }
   475    }