1    /* 
     2     * Copyright (c) 2011, 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     *  ======== Hwi.xdc ========
    34     *
    35     */
    36    package ti.sysbios.family.msp430;
    37    
    38    import xdc.rov.ViewInfo;
    39    import xdc.runtime.Diags;
    40    import xdc.runtime.Log;
    41    import xdc.runtime.Assert;
    42    import xdc.runtime.Error;
    43    
    44    import ti.sysbios.interfaces.IHwi;
    45    
    46    /*!
    47     *  ======== Hwi ========
    48     *  MSP430 Hardware Interrupt Manager
    49     *
    50     *  This module implements the generic Hwi module functions 
    51     *  Hwi_enable, Hwi_disable, and Hwi_restore as defined by
    52     *  {@link ti.sysbios.interfaces.IHwi IHwi}.
    53     *
    54     *  @p(html)
    55     *  <h3> Calling Context </h3>
    56     *  <table border="1" cellpadding="3">
    57     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center"></colgroup>
    58     *
    59     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th><th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    60     *    <!--                                                                                                                 -->
    61     *    <tr><td> {@link #clearInterrupt}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    62     *    <tr><td> {@link #create}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    63     *    <tr><td> {@link #disable}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    64     *    <tr><td> {@link #disableInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    65     *    <tr><td> {@link #enable}           </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td><td>   N    </td></tr>
    66     *    <tr><td> {@link #enableInterrupt}  </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    67     *    <tr><td> {@link #Params_init}      </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    68     *    <tr><td> {@link #restore}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    69     *    <tr><td> {@link #restoreInterrupt} </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    70     *    <tr><td> {@link #construct}        </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    71     *    <tr><td> {@link #delete}           </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    72     *    <tr><td> {@link #destruct}         </td><td>   N    </td><td>   N    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    73     *    <tr><td> {@link #getHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    74     *    <tr><td> {@link #setFunc}          </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    75     *    <tr><td> {@link #setHookContext}   </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   Y    </td><td>   N    </td></tr>
    76     *    <tr><td colspan="6"> Definitions: <br />
    77     *       <ul>
    78     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    79     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    80     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
    81     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
    82     *           <ul>
    83     *             <li> In your module startup after this module is started (e.g. Hwi_Module_startupDone() returns TRUE). </li>
    84     *             <li> During xdc.runtime.Startup.lastFxns. </li>
    85     *             <li> During main().</li>
    86     *             <li> During BIOS.startupFxns.</li>
    87     *           </ul>
    88     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
    89     *           <ul>
    90     *             <li> During xdc.runtime.Startup.firstFxns.</li>
    91     *             <li> In your module startup before this module is started (e.g. Hwi_Module_startupDone() returns FALSE).</li>
    92     *           </ul>
    93     *       </ul>
    94     *    </td></tr>
    95     *
    96     *  </table>
    97     *  @p
    98     *
    99     */
   100    
   101    
   102    @Template("./Hwi.xdt")  /* generates the vector table and the dispatcher */
   103    @ModuleStartup          /* generate a call to startup function */
   104    
   105    module Hwi inherits ti.sysbios.interfaces.IHwi 
   106    {
   107        /*! 
   108         *  The MSP430 supports up to 64 interrupts/exceptions.
   109         *
   110         *  The actual number supported is device specific and provided by
   111         *  the catalog device specification.
   112         */
   113        readonly config Int NUM_INTERRUPTS;
   114    
   115        // -------- Module Types --------
   116    
   117        /*! Hwi vector function type definition. */
   118        typedef Void (*VectorFuncPtr)(void);
   119    
   120         /*! @_nodoc */
   121        metaonly struct BasicView {
   122            Ptr         halHwiHandle;
   123            String      label;
   124            Int         intNum;
   125            String      fxn; 
   126            UArg        arg; 
   127            Ptr         irp; 
   128        };
   129        
   130        /*! @_nodoc */
   131        metaonly struct ModuleView {
   132            String      options[4];
   133            SizeT       hwiStackPeak;
   134            SizeT       hwiStackSize;
   135            Ptr         hwiStackBase;
   136        };
   137    
   138        /*! @_nodoc */
   139        @Facet
   140        metaonly config ViewInfo.Instance rovViewInfo = 
   141            ViewInfo.create({
   142                viewMap: [
   143                    ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',    structName: 'BasicView'}],
   144                    ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule',   structName: 'ModuleView'}]
   145                ]
   146            });
   147        
   148        // -------- Module Parameters --------
   149    
   150        // Logs
   151    
   152        /*!
   153         *  Issued just prior to Hwi function invocation (with interrupts disabled)
   154         */
   155        config Log.Event LM_begin = {
   156            mask: Diags.USER1 | Diags.USER2,
   157            msg: "LM_begin: hwi: 0x%x, func: 0x%x, preThread: %d, intNum: %d, irp: 0x%x"
   158        };
   159    
   160        /*!
   161         *  Issued just after return from Hwi function (with interrupts disabled)
   162         */
   163        config Log.Event LD_end = {
   164            mask: Diags.USER2,
   165            msg: "LD_end: hwi: 0x%x"
   166        };
   167    
   168        // Asserts
   169    
   170        /*! Assert when bad maskSetting parameter provided */
   171        config Assert.Id A_unsupportedMaskingOption = {
   172            msg: "A_unsupportedMaskingOption: unsupported maskSetting."
   173        };
   174    
   175        // Errors
   176    
   177        /*!
   178         *  Error raised when Hwi is already defined
   179         */
   180        config Error.Id E_alreadyDefined = {
   181            msg: "E_alreadyDefined: Hwi already defined: intr# %d"
   182        };
   183    
   184        /*!
   185         *  Error raised when an unimplemented Hwi function is called
   186         *
   187         *  The MSP430 does not implement all of the functions defined
   188         *  by {@link ti.sysbios.interfaces.IHwi}.  If applications
   189         *  call such a function, an E_notImplemented error is raised
   190         *  with the name of the unimplemented function passed as an
   191         *  argument.  See {@link xdc.runtime.Error#raise}.
   192         */
   193        config Error.Id E_notImplemented = {
   194            msg: "E_notImplemented: Function not implemented: %s"
   195        };
   196    
   197        // configs
   198    
   199        /*!
   200         *  ======== fillVectors ========
   201         *  Plug all unused interrupt vectors
   202         *
   203         *  This parameter allows one to plug all unused interrupt vectors
   204         *  a common "stub", {@link #nullIsrFunc}.  This allows one to more
   205         *  easily catch unexpected interrupts and "run away" code.
   206         */
   207        metaonly config Bool fillVectors = true;
   208    
   209        /*!
   210         *  ======== nullIsrFunc ========
   211         *  Unused vector handler
   212         *
   213         *  This parameter specifies the interrupt service routine used
   214         *  when filling unused interrupt vectors.  It defaults to a function
   215         *  that simply loops to itself.
   216         */
   217        metaonly config FuncPtr nullIsrFunc;
   218    
   219        /*!
   220         *  ======== resetFunc ========
   221         *  Reset handler
   222         *
   223         *  This parameter specifies the interrupt service routine triggered on
   224         *  reset. The default is c_int00.
   225         */
   226        metaonly config VectorFuncPtr resetFunc;
   227    
   228        /*!
   229         *  ======== alwaysWake ========
   230         *  Always keep the CPU awake upon return from interrupt?
   231         *
   232         *  This parameter serves as a global 'switch' to control whether the
   233         *  CPU is kept awake (i.e., not allowed to return to a low power mode) at
   234         *  the end of servicing a hardware interrupt (Hwi) managed by SYS/BIOS.  
   235         *  The behavior of each interrupt instance can be controlled individually
   236         *  (see {@link #keepAwakeEnabled}); when set to true, this parameter serves
   237         *  as an override of the individual instance selection, to force keep awake 
   238         *  of the CPU. This parameter is provided to assist with debug, and to 
   239         *  ease use and transition of legacy code to work with SYS/BIOS.
   240         */
   241        metaonly config Bool alwaysWake = false;
   242    
   243        /*!
   244         *  ======== alwaysLog ========
   245         *  Always emit Log messages from interrupt stubs?
   246         *
   247         *  This parameter serves as a global 'switch' to control whether Log
   248         *  begin and end messages will be emitted from interrupt stubs.
   249         *  Note that the behavior of each interrupt instance can be controlled
   250         *  individually (see {@link #loggingEnabled}); when set to true, alwaysLog
   251         *  serves as an override of the individual instance selections, forcing 
   252         *  logging from the stubs of all configured interrupts.
   253         */
   254        metaonly config Bool alwaysLog = false;
   255    
   256        // -------- Module Functions --------
   257    
   258        /*!
   259         *  ======== disable ========
   260         */
   261        @Macro
   262        override UInt disable();
   263    
   264        /*!
   265         *  ======== enable ========
   266         */
   267        @Macro
   268        override UInt enable();
   269    
   270        /*!
   271         *  ======== restore ========
   272         */
   273        @Macro
   274        override Void restore(UInt key);
   275    
   276        /*!
   277         *  ======== inUseMeta ========
   278         *  @_nodoc
   279         *  Check for Hwi already in use
   280         *
   281         *  For internal SYS/BIOS use only. 
   282         *  Should be called prior to any internal Hwi.create().
   283         *
   284         *  @param(intNum)  interrupt number
   285         */
   286        metaonly Bool inUseMeta(UInt intNum);
   287    
   288        /*!
   289         *  ======== plugMeta ========
   290         *  Statically plug an interrupt vector with an ISR address
   291         *
   292         *  @param(intNum)  interrupt number
   293         *  @param(fxn)     pointer to ISR function
   294         */
   295        metaonly Void plugMeta(UInt intNum, Fxn fxn);
   296    
   297        /*!
   298         *  @_nodoc
   299         *  ======= logBegin ========
   300         *  Log the LM_begin from within Hwi module scope
   301         */
   302        @DirectCall
   303        Void logBegin(Log.Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
   304    
   305        /*!
   306         *  @_nodoc
   307         *  ======= logEnd ========
   308         *  Log the LD_end from within Hwi module scope
   309         */
   310        @DirectCall
   311        Void logEnd(Log.Event evt, IArg a1);
   312    
   313    instance:
   314    
   315        /*! override maskSetting - Hwi does not manage nesting on 430 */
   316        override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_ALL;
   317    
   318        /*! Does this interrupt support posting of Swis? Default is true. */
   319        metaonly config Bool swiEnabled = true;
   320    
   321        /*! Does this interrupt support task pre-emption? Default is true. */
   322        metaonly config Bool taskEnabled = true;
   323    
   324        /*! Switch to ISR stack for this interrupt? Default is true. */
   325        metaonly config Bool isrStackEnabled = true;
   326    
   327        /*! Does this interrupt allow nesting by other interrupts? Default is false. */
   328        metaonly config Bool nestingEnabled = false;
   329    
   330        /*! Does this interrupt support logging?
   331         *
   332         *  If set to true, {@link xdc.runtime.Log Log} statements are inserted
   333         *  into the generated interrupt stub that calls the user's interrupt
   334         *  function.  The stub posts an {@link #LM_begin} event at the beginning
   335         *  of the interrupt service routine and a {@link #LD_end} event after
   336         *  the user's function returns.
   337         *
   338         *  In addition to enabling this flag, you must also enable USER1 and/or
   339         *  USER2 logging for this module.  Otherwise, the events posted by the
   340         *  inserted Log statments will be ignored.
   341         */
   342        metaonly config Bool loggingEnabled = false;
   343    
   344        /*! Does this interrupt support thread-type tracking? Default is true. */
   345        metaonly config Bool threadTypeEnabled = true;
   346    
   347        /*! Should keep CPU awake following this interrupt? Default is false. */
   348        metaonly config Bool keepAwakeEnabled = false;
   349    
   350    internal:   /* not for client use */
   351    
   352        /*!
   353         *  ======== init ========
   354         *  Setup Hwi stack
   355         */
   356        Void init();
   357    
   358        /*!
   359         *  ======== nonPluggedIsr ========
   360         *  Interrupt service routine that never returns
   361         *
   362         *  This function can be used to plug interrupts that should never
   363         *  occur.  If one does, rather than jumping to an undefined location
   364         *  the program stops with the CPU in a spin lock within this function.
   365         */
   366        Void nonPluggedIsr(UArg intNum);
   367    
   368        /*!
   369         *  const array to hold all HookSet objects.
   370         */
   371        config HookSet hooks[length] = [];
   372    
   373        /*! Meta World Only Hwi Configuration Object. */
   374        metaonly struct InterruptObj {
   375            String name;            /* symbol used for vector table entry */
   376            Bool used;              /* Interrupt already defined? */
   377            Bool generateStub;      /* handler is generated? */
   378            Bool swiEnabled;
   379            Bool taskEnabled;
   380            Bool nestingEnabled;
   381            Bool isrStackEnabled;
   382            Bool lmBeginEnabled;
   383            Bool ldEndEnabled;
   384            Bool threadTypeEnabled;
   385            Bool keepAwakeEnabled;
   386            String handle;
   387            FuncPtr fxn;            /* "wrapped" ISR function */
   388            Fxn pfxn;               /* non "wrapped" ISR function */
   389            UArg arg;               /* Argument to fxn */
   390        };
   391    
   392        /*!
   393         * Meta-only array of interrupt objects.
   394         *
   395         * This meta-only array of Hwi config objects is initialized
   396         * in Hwi.xs:module$meta$init().
   397         */
   398        metaonly config InterruptObj interrupt[];
   399    
   400        struct Instance_State {
   401            Int             intNum;         // Interrupt number
   402            Irp             irp;            // current IRP
   403            Ptr             hookEnv[];
   404        };
   405     
   406        struct Module_State {
   407            Char        *taskSP;        // Temporary storage of interrupted
   408                                        // Task's SP during ISR execution
   409            /* ROM */
   410            Char        *isrStack;      // Points to isrStack address
   411        };
   412    }
   413    /*
   414     *  @(#) ti.sysbios.family.msp430; 1, 0, 0, 0,197; 12-21-2011 15:08:19; /db/vtree/library/trees/avala/avala-q22x/src/ xlibrary
   415    
   416     */
   417