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 * 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
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 /*!
319 * Does this interrupt support posting of Swis? Default is true.
320 *
321 * If "true", the interrupt stub will disable the Swi scheduler upon stub
322 * entry, and restore it upon interrupt completion.
323 *
324 * If no Swi-scheduling APIs (for example, Swi_post()) are called from
325 * within this interrupt's ISR function, then swiEnabled can be set to
326 * "false".
327 */
328 metaonly config Bool swiEnabled = true;
329
330 /*!
331 * Does this interrupt support task pre-emption? Default is true.
332 *
333 * If "true", the interrupt stub will disable the Task scheduler upon
334 * stub entry, and restore it upon interrupt completion.
335 *
336 * If no Task-scheduling APIs (e.g., Semaphore_post()) are called from
337 * within this interrupt's ISR function, then taskEnabled can be set to
338 * "false".
339 */
340 metaonly config Bool taskEnabled = true;
341
342 /*!
343 * Switch to ISR stack for this interrupt? Default is true.
344 *
345 * If "true", the SYS/BIOS interrupt/system stack will be used when
346 * running this interrupt's ISR function (instead of the interrupted
347 * Task's dedicated stack). If "false", no switching to the
348 * interrupt/system stack will occur for this interrupt.
349 *
350 * Note that this parameter is only relevant for the Task module; if
351 * the Task module is not enabled in the application only a single stack
352 * is used (i.e., the "system/interrupt stack").
353 */
354 metaonly config Bool isrStackEnabled = true;
355
356 /*!
357 * Does this interrupt allow nesting by other interrupts? Default is
358 * false.
359 *
360 * Set to "true" if the configured ISR function will enable global
361 * interrupts temporarily within the function, to allow other interrupts
362 * to nest on top of this interrupt. If the ISR does not enable other
363 * interrupts, then leave as the default of "false".
364 *
365 */
366 metaonly config Bool nestingEnabled = false;
367
368 /*!
369 * Does this interrupt support logging?
370 *
371 * If set to true, {@link xdc.runtime.Log Log} statements are inserted
372 * into the generated interrupt stub that calls the user's interrupt
373 * function. The stub posts an {@link #LM_begin} event at the beginning
374 * of the interrupt service routine and a {@link #LD_end} event after
375 * the user's function returns.
376 *
377 * In addition to enabling this flag, you must also enable USER1 and/or
378 * USER2 logging for this module. Otherwise, the events posted by the
379 * inserted Log statments will be ignored.
380 */
381 metaonly config Bool loggingEnabled = false;
382
383 /*!
384 * Does this interrupt support thread-type tracking? Default is true.
385 *
386 * If "true", this stub will enable full tracking of the execution
387 * context. For example, if the ISR function (or one of the functions
388 * it calls) were to call BIOS_getThreadType(), the returned value would be
389 * BIOS_ThreadType_Hwi.
390 *
391 * Setting this parameter to "false" will slightly reduce the interrupt
392 * stub overhead, but may result in an incorrect thread type being
393 * reported during the processing of the interrupt.
394 */
395 metaonly config Bool threadTypeEnabled = true;
396
397 /*!
398 * Should keep CPU awake following this interrupt? Default is false.
399 *
400 * If "true", this interrupt stub will modify the status register (SR)
401 * value that was pushed onto the stack (automatically, at the start of
402 * servicing the interrupt), so that when it is restored by the RETI
403 * instruction, the CPU will stay in the Active mode.
404 *
405 * If left as "false", the unmodified SR value will be restored by the
406 * RETI instruction, and the CPU may return to a previous low power mode
407 * (LPM) that was in effect when the interrupt was triggered.
408 */
409 metaonly config Bool keepAwakeEnabled = false;
410
411 internal:
412
413 /*!
414 * ======== init ========
415 * Setup Hwi stack
416 */
417 Void init();
418
419 /*!
420 * ======== nonPluggedIsr ========
421 * Interrupt service routine that never returns
422 *
423 * This function can be used to plug interrupts that should never
424 * occur. If one does, rather than jumping to an undefined location
425 * the program stops with the CPU in a spin lock within this function.
426 */
427 Void nonPluggedIsr(UArg intNum);
428
429 /*!
430 * const array to hold all HookSet objects.
431 */
432 config HookSet hooks[length] = [];
433
434 /*! Meta World Only Hwi Configuration Object. */
435 metaonly struct InterruptObj {
436 String name;
437 Bool used;
438 Bool generateStub;
439 Bool swiEnabled;
440 Bool taskEnabled;
441 Bool nestingEnabled;
442 Bool isrStackEnabled;
443 Bool lmBeginEnabled;
444 Bool ldEndEnabled;
445 Bool threadTypeEnabled;
446 Bool keepAwakeEnabled;
447 String handle;
448 FuncPtr fxn;
449 Fxn pfxn;
450 UArg arg;
451 };
452
453 /*!
454 * Meta-only array of interrupt objects.
455 *
456 * This meta-only array of Hwi config objects is initialized
457 * in Hwi.xs:module$meta$init().
458 */
459 metaonly config InterruptObj interrupt[];
460
461 struct Instance_State {
462 Int intNum;
463 Irp irp;
464 Ptr hookEnv[];
465 };
466
467 struct Module_State {
468 Char *taskSP;
469
470
471 Char *isrStack;
472 };
473 }
474 475 476 477
478