1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 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")
103 @ModuleStartup
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
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
149
150
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
169
170 /*! Assert when bad maskSetting parameter provided */
171 config Assert.Id A_unsupportedMaskingOption = {
172 msg: "A_unsupportedMaskingOption: unsupported maskSetting."
173 };
174
175
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
198
199 /*!
200 * ======== fillVectors ========
201 * Plug all unused interrupt vectors
202 *
203 * This parameter allows one to plug all unused interrupt vectors
204 * with a spin loop, to catch unexpected interrupts and "run away" code.
205 */
206 metaonly config Bool fillVectors = true;
207
208 /*!
209 * ======== resetFunc ========
210 * Reset handler
211 *
212 * This parameter specifies the interrupt service routine triggered on
213 * reset. The default is c_int00.
214 */
215 metaonly config VectorFuncPtr resetFunc;
216
217 /*!
218 * ======== alwaysWake ========
219 * Always keep the CPU awake upon return from interrupt?
220 *
221 * This parameter serves as a global 'switch' to control whether the
222 * CPU is kept awake (i.e., not allowed to return to a low power mode) at
223 * the end of servicing a hardware interrupt (Hwi) managed by SYS/BIOS.
224 * The behavior of each interrupt instance can be controlled individually
225 * (see {@link #keepAwakeEnabled}); when set to true, this parameter serves
226 * as an override of the individual instance selection, to force keep awake
227 * of the CPU. This parameter is provided to assist with debug, and to
228 * ease use and transition of legacy code to work with SYS/BIOS.
229 */
230 metaonly config Bool alwaysWake = false;
231
232 /*!
233 * ======== alwaysLog ========
234 * Always emit Log messages from interrupt stubs?
235 *
236 * This parameter serves as a global 'switch' to control whether Log
237 * begin and end messages will be emitted from interrupt stubs.
238 * Note that the behavior of each interrupt instance can be controlled
239 * individually (see {@link #loggingEnabled}); when set to true, alwaysLog
240 * serves as an override of the individual instance selections, forcing
241 * logging from the stubs of all configured interrupts.
242 */
243 metaonly config Bool alwaysLog = false;
244
245
246
247 /*!
248 * ======== disable ========
249 */
250 @Macro
251 override UInt disable();
252
253 /*!
254 * ======== enable ========
255 */
256 @Macro
257 override UInt enable();
258
259 /*!
260 * ======== restore ========
261 */
262 @Macro
263 override Void restore(UInt key);
264
265 /*!
266 * ======== inUseMeta ========
267 * @_nodoc
268 * Check for Hwi already in use
269 *
270 * For internal SYS/BIOS use only.
271 * Should be called prior to any internal Hwi.create().
272 *
273 * @param(intNum) interrupt number
274 */
275 metaonly Bool inUseMeta(UInt intNum);
276
277 /*!
278 * ======== plugMeta ========
279 * Statically plug an interrupt vector with an ISR address
280 *
281 * @param(intNum) interrupt number
282 * @param(fxn) pointer to ISR function
283 */
284 metaonly Void plugMeta(UInt intNum, Fxn fxn);
285
286 /*!
287 * @_nodoc
288 * ======= logBegin ========
289 * Log the LM_begin from within Hwi module scope
290 */
291 @DirectCall
292 Void logBegin(Log.Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
293
294 /*!
295 * @_nodoc
296 * ======= logEnd ========
297 * Log the LD_end from within Hwi module scope
298 */
299 @DirectCall
300 Void logEnd(Log.Event evt, IArg a1);
301
302 instance:
303
304 /*! override maskSetting - Hwi does not manage nesting on 430 */
305 override config IHwi.MaskingOption maskSetting = IHwi.MaskingOption_ALL;
306
307 /*!
308 * Does this interrupt support posting of Swis? Default is true.
309 *
310 * If "true", the interrupt stub will disable the Swi scheduler upon stub
311 * entry, and restore it upon interrupt completion.
312 *
313 * If no Swi-scheduling APIs (for example, Swi_post()) are called from
314 * within this interrupt's ISR function, then swiEnabled can be set to
315 * "false".
316 */
317 metaonly config Bool swiEnabled = true;
318
319 /*!
320 * Does this interrupt support task pre-emption? Default is true.
321 *
322 * If "true", the interrupt stub will disable the Task scheduler upon
323 * stub entry, and restore it upon interrupt completion.
324 *
325 * If no Task-scheduling APIs (e.g., Semaphore_post()) are called from
326 * within this interrupt's ISR function, then taskEnabled can be set to
327 * "false".
328 */
329 metaonly config Bool taskEnabled = true;
330
331 /*!
332 * Switch to ISR stack for this interrupt? Default is true.
333 *
334 * If "true", the SYS/BIOS interrupt/system stack will be used when
335 * running this interrupt's ISR function (instead of the interrupted
336 * Task's dedicated stack). If "false", no switching to the
337 * interrupt/system stack will occur for this interrupt.
338 *
339 * Note that this parameter is only relevant for the Task module; if
340 * the Task module is not enabled in the application only a single stack
341 * is used (i.e., the "system/interrupt stack").
342 */
343 metaonly config Bool isrStackEnabled = true;
344
345 /*!
346 * Does this interrupt allow nesting by other interrupts? Default is
347 * false.
348 *
349 * Set to "true" if the configured ISR function will enable global
350 * interrupts temporarily within the function, to allow other interrupts
351 * to nest on top of this interrupt. If the ISR does not enable other
352 * interrupts, then leave as the default of "false".
353 *
354 */
355 metaonly config Bool nestingEnabled = false;
356
357 /*!
358 * Does this interrupt support logging?
359 *
360 * If set to true, {@link xdc.runtime.Log Log} statements are inserted
361 * into the generated interrupt stub that calls the user's interrupt
362 * function. The stub posts an {@link #LM_begin} event at the beginning
363 * of the interrupt service routine and a {@link #LD_end} event after
364 * the user's function returns.
365 *
366 * In addition to enabling this flag, you must also enable USER1 and/or
367 * USER2 logging for this module. Otherwise, the events posted by the
368 * inserted Log statments will be ignored.
369 */
370 metaonly config Bool loggingEnabled = false;
371
372 /*!
373 * Does this interrupt support thread-type tracking? Default is true.
374 *
375 * If "true", this stub will enable full tracking of the execution
376 * context. For example, if the ISR function (or one of the functions
377 * it calls) were to call BIOS_getThreadType(), the returned value would be
378 * BIOS_ThreadType_Hwi.
379 *
380 * Setting this parameter to "false" will slightly reduce the interrupt
381 * stub overhead, but may result in an incorrect thread type being
382 * reported during the processing of the interrupt.
383 */
384 metaonly config Bool threadTypeEnabled = true;
385
386 /*!
387 * Should keep CPU awake following this interrupt? Default is false.
388 *
389 * If "true", this interrupt stub will modify the status register (SR)
390 * value that was pushed onto the stack (automatically, at the start of
391 * servicing the interrupt), so that when it is restored by the RETI
392 * instruction, the CPU will stay in the Active mode.
393 *
394 * If left as "false", the unmodified SR value will be restored by the
395 * RETI instruction, and the CPU may return to a previous low power mode
396 * (LPM) that was in effect when the interrupt was triggered.
397 */
398 metaonly config Bool keepAwakeEnabled = false;
399
400 internal:
401
402 403 404 405
406 Int postInit(Object *hwi, Error.Block *eb);
407
408 /*!
409 * ======== init ========
410 * Setup Hwi stack
411 */
412 Void init();
413
414 /*!
415 * const array to hold all HookSet objects.
416 */
417 config HookSet hooks[length] = [];
418
419 /*! Meta World Only Hwi Configuration Object. */
420 metaonly struct InterruptObj {
421 String name;
422 Bool used;
423 Bool generateStub;
424 Bool swiEnabled;
425 Bool taskEnabled;
426 Bool nestingEnabled;
427 Bool isrStackEnabled;
428 Bool lmBeginEnabled;
429 Bool ldEndEnabled;
430 Bool threadTypeEnabled;
431 Bool keepAwakeEnabled;
432 String handle;
433 FuncPtr fxn;
434 Fxn pfxn;
435 UArg arg;
436 };
437
438 /*!
439 * Meta-only array of interrupt objects.
440 *
441 * This meta-only array of Hwi config objects is initialized
442 * in Hwi.xs:module$meta$init().
443 */
444 metaonly config InterruptObj interrupt[];
445
446 struct Instance_State {
447 Int intNum;
448 Irp irp;
449 Ptr hookEnv[];
450 };
451
452 struct Module_State {
453 Char *taskSP;
454
455
456 Char *isrStack;
457 };
458 }