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
37 package ti.sysbios.family.msp430;
38
39 import xdc.rov.ViewInfo;
40
41 import xdc.runtime.Types;
42 import xdc.runtime.Error;
43
44 import ti.sysbios.interfaces.ITimer;
45
46 /*!
47 * ======== Timer ========
48 * MSP430 Timer Peripherals Manager
49 *
50 * This module manages the timer peripherals available on MSP430 devices
51 * (see {@link ./doc-files/TimerTables.html Timer Mapping Tables} for
52 * supported device information).
53 *
54 * The Timer module supports the timer in 'one shot', 'continuous', and
55 * 'dynamic' modes.
56 *
57 * In 'one shot' mode, a timer function will "fire" (run) when the timer
58 * period expires. In 'one shot' mode this will only happen once.
59 *
60 * In 'continuous' mode, the specified timer function will "fire" every
61 * time the period expires, throughout the lifetime of the program.
62 *
63 * In 'dynamic' mode, the specified timer function will "fire" every
64 * time the period expires. But the period of the timer can be changed
65 * dynamically, to correspond to the next tick interrupt needed from the
66 * timer. This mode is used by the SYS/BIOS
67 * {@link ti.sysbios.knl.Clock Clock} module for implementing
68 * dynamic tick suppression, to reduce the number of interrupts from the
69 * timer to the minimum required for currently scheduled timeouts.
70 *
71 * NOTE: In the current implementation on MSP430 Timers cannot be
72 * created dynamically at runtime by the application. Timers must be
73 * created statically in the application configuration.
74 *
75 * @p(html)
76 * <h3> Calling Context </h3>
77 * <table border="1" cellpadding="3">
78 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
79 * </colgroup>
80 *
81 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
82 * <th> Task </th><th> Main </th><th> Startup </th></tr>
83 * <!-- -->
84 * <tr><td> {@link #getNumTimers} </td><td> Y </td>
85 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
86 * <tr><td> {@link #getStatus} </td><td> Y </td>
87 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
88 * <tr><td> {@link #Params_init} </td><td> N </td>
89 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
90 * <tr><td> {@link #construct} </td><td> N </td>
91 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
92 * <tr><td> {@link #create} </td><td> N </td>
93 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
94 * <tr><td> {@link #delete} </td><td> N </td>
95 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
96 * <tr><td> {@link #destruct} </td><td> N </td>
97 * <td> N </td><td> N </td><td> N </td><td> N </td></tr>
98 * <tr><td> {@link #getCount} </td><td> Y </td>
99 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
100 * <tr><td> {@link #getFreq} </td><td> Y </td>
101 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
102 * <tr><td> {@link #getFunc} </td><td> Y </td>
103 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
104 * <tr><td> {@link #getPeriod} </td><td> Y </td>
105 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
106 * <tr><td> {@link #reconfig} </td><td> Y </td>
107 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
108 * <tr><td> {@link #setFunc} </td><td> Y </td>
109 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
110 * <tr><td> {@link #setPeriod} </td><td> Y </td>
111 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
112 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td>
113 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
114 * <tr><td> {@link #start} </td><td> Y </td>
115 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
116 * <tr><td> {@link #stop} </td><td> Y </td>
117 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
118 * <tr><td colspan="6"> Definitions: <br />
119 * <ul>
120 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
121 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
122 * <li> <b>Task</b>: API is callable from a Task thread. </li>
123 * <li> <b>Main</b>: API is callable during any of these phases: </li>
124 * <ul>
125 * <li> In your module startup after this module is started
126 * (e.g. Timer_Module_startupDone() returns TRUE). </li>
127 * <li> During xdc.runtime.Startup.lastFxns. </li>
128 * <li> During main().</li>
129 * <li> During BIOS.startupFxns.</li>
130 * </ul>
131 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
132 * <ul>
133 * <li> During xdc.runtime.Startup.firstFxns.</li>
134 * <li> In your module startup before this module is started
135 * (e.g. Timer_Module_startupDone() returns FALSE).</li>
136 * </ul>
137 * </ul>
138 * </td></tr>
139 *
140 * </table>
141 * @p
142 *
143 * @p(html)
144 * <h3> Timer Mapping Tables </h3>
145 * <p>
146 * The Timer module allows the user to use and configure the various timers
147 * that exist on a particular device. This is achieved by specifying a timer
148 * ID when statically creating the Timer instance.
149 * A convention is used to assign logical IDs to physical timers. ID '0'
150 * corresponds to the first Timer_A peripheral (TA0). ID '1' is assigned to
151 * the next Timer_A (TA1), until there are no more Timer_A peripherals. Then
152 * the next ID is assigned to the first Timer_B peripheral (if present), and
153 * so on.
154 * These tables are provided to show which timers map to which timer IDs.
155 * </p>
156 * {@link ./doc-files/TimerTables.html Timer Mapping Tables}
157 * @p
158 */
159 @InstanceFinalize
160 @InstanceInitError
161 @ModuleStartup
162
163 module Timer inherits ti.sysbios.interfaces.ITimer
164 {
165 /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
166 override metaonly config Bool supportsDynamic = true;
167
168 /*! override defaultMode - use RunMode_PERIODIC by default */
169 override metaonly config Bool defaultDynamic = false;
170
171
172
173 /*! Lists of input clock sources for timers */
174 enum Source {
175 Source_ACLK = 0x100, /*! ACLK */
176 Source_SMCLK = 0x200, /*! SMCLK */
177 Source_EXTERNAL = 0x000, /*! External clock */
178 Source_EXTERNAL_INVERTED = 0x300 /*! Inverted external clock */
179 };
180
181 /*! Input divider (ID) bit field values */
182 enum ID {
183 ID_1 = 0x0, /*! /1 */
184 ID_2 = 0x40, /*! /2 */
185 ID_4 = 0x80, /*! /4 */
186 ID_8 = 0xC0 /*! /8 */
187 };
188
189 /*! Input Divider Expansion (IDEX) bit field values */
190 enum IDEX {
191 IDEX_1 = 0x0, /*! /1 */
192 IDEX_2 = 0x1, /*! /2 */
193 IDEX_3 = 0x2, /*! /3 */
194 IDEX_4 = 0x3, /*! /4 */
195 IDEX_5 = 0x4, /*! /5 */
196 IDEX_6 = 0x5, /*! /6 */
197 IDEX_7 = 0x6, /*! /7 */
198 IDEX_8 = 0x7 /*! /8 */
199 };
200
201 /*! Max value of Timer period for PeriodType_COUNTS */
202 const UInt MAX_PERIOD = 0x0000ffff;
203
204 /*! @_nodoc
205 * Min instructions to use in trigger().
206 */
207 const Int MIN_SWEEP_PERIOD = 1;
208
209 /*! Timer Configuration struct.
210 *
211 * @field(source) Timer clock source.
212 */
213 struct Control {
214 UInt source; /*! 0x100=ACLK, 0x200=SMCLK, 0=EXT, 0x300=EXT_INVERT */
215 };
216
217 /*! @_nodoc */
218 @XmlDtd
219 metaonly struct BasicView {
220 Ptr halTimerHandle;
221 String label;
222 UInt id;
223 Control configuration;
224 String startMode;
225 String runMode;
226 UInt period;
227 String periodType;
228 Bool synchronous;
229 UInt intNum;
230 String tickFxn[];
231 UArg arg;
232 UInt frequency;
233 String hwiHandle;
234 };
235
236 /*! @_nodoc */
237 metaonly struct DeviceView {
238 UInt id;
239 String device;
240 String devAddr;
241 UInt intNum;
242 String runMode;
243 UInt period;
244 UInt currCount;
245 UInt remainingCount;
246 UInt prevThreshold;
247 String state;
248 };
249
250 /*! @_nodoc */
251 metaonly struct ModuleView {
252 String availMask;
253 }
254
255 /*! @_nodoc */
256 @Facet
257 metaonly config ViewInfo.Instance rovViewInfo =
258 ViewInfo.create({
259 viewMap: [
260 [
261 'Basic',
262 {
263 type: ViewInfo.INSTANCE,
264 viewInitFxn: 'viewInitBasic',
265 structName: 'BasicView'
266 }
267 ],
268 [
269 'Device',
270 {
271 type: ViewInfo.INSTANCE,
272 viewInitFxn: 'viewInitDevice',
273 structName: 'DeviceView'
274 }
275 ],
276 [
277 'Module',
278 {
279 type: ViewInfo.MODULE,
280 viewInitFxn: 'viewInitModule',
281 structName: 'ModuleView'
282 }
283 ],
284 ]
285 });
286
287 /*!
288 * ======== E_invalidTimer ========
289 * Error raised when specified timer id is not supported
290 */
291 config Error.Id E_invalidTimer = {
292 msg: "E_invalidTimer: Invalid Timer Id %d"
293 };
294
295 /*!
296 * ======== E_notAvailable ========
297 * Error raised when requested timer is in use
298 */
299 config Error.Id E_notAvailable = {
300 msg: "E_notAvailable: Timer not available %d"
301 };
302
303 /*!
304 * ======== E_cannotSupport ========
305 * Error raised when requested period is not supported
306 */
307 config Error.Id E_cannotSupport = {
308 msg: "E_cannotSupport: Timer cannot support requested period %d"
309 };
310
311 /*!
312 * ======== E_runtimeCreate ========
313 * Error raised when dynamic Timer create is attempted
314 */
315 config Error.Id E_runtimeCreate = {
316 msg: "E_runtimeCreate: Runtime Timer create is not supported %d"
317 };
318
319 /*!
320 * ======== anyMask ========
321 * Mask of available timers
322 *
323 * This mask is used to identify the timers that can be used when
324 * Timer_create() is called with an id equal to
325 * {@link Timer#ANY Timer_ANY}.
326 */
327 config UInt anyMask = 0x7;
328
329 /*!
330 * ======== keepAwake ========
331 * Wakeup (enable) CPU when Timer ISR returns
332 *
333 * If set to `true`, all Timer instances keep the CPU awake upon
334 * return from interrupt.
335 */
336 config Bool keepAwake = false;
337
338 /*!
339 * ======== oneShotStub ========
340 * @_nodoc
341 *
342 * @param(arg) Unused.
343 */
344 Void oneShotStub(UArg arg);
345
346 /*!
347 * ======== oneShotNestStub ========
348 * @_nodoc
349 *
350 * @param(arg) Unused.
351 */
352 Void oneShotNestStub(UArg arg);
353
354 /*!
355 * ======== periodicStub ========
356 * @_nodoc
357 *
358 * @param(arg) Unused.
359 */
360 Void periodicStub(UArg arg);
361
362 /*!
363 * ======== periodicNestStub ========
364 * @_nodoc
365 *
366 * @param(arg) Unused.
367 */
368 Void periodicNestStub(UArg arg);
369
370 /*!
371 * ======== getHandle ========
372 * @_nodoc
373 * Used by TimestampProvider module to get hold of timer handle used by
374 * Clock.
375 *
376 * @param(id) timer Id.
377 */
378 Handle getHandle(UInt id);
379
380 instance:
381
382 /*! Hwi Params for Hwi Object. Default is null. */
383 config Hwi.Params *hwiParams = null;
384
385 /*! Clock source input select. Default is ACLK. */
386 config Source clockSource = Source_ACLK;
387
388 /*! Selected clock source is synchronous to CPU clock? Default is false. */
389 config Bool synchronous = false;
390
391 /*! Clock Input Divider (ID) select. Default is /1. */
392 config ID inputDivider = ID_1;
393
394 /*! Clock Input Divider Expansion (IDEX) select. Default is /1. */
395 config IDEX inputDividerExp = IDEX_1;
396
397 /*! Enable nesting of other interrupts on top of this Timer's ISR? */
398 config Bool nesting = false;
399
400 /*! Previous threshold count value. */
401 config UInt prevThreshold = 0;
402
403 /*! Control register configuration. Default source = ACLK. */
404 config UInt controlRegInit = Source_ACLK;
405
406 /*!
407 * ======== reconfig ========
408 * Modify timer instances at runtime
409 *
410 * @param(timerParams) timer Params
411 * @param(tickFxn) function that runs when timer expires.
412 */
413 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
414
415
416 internal:
417
418 /*!
419 * ======== noStartupNeeded ========
420 * Flag used to prevent misc code from being brought in
421 * un-necessarily
422 */
423 config UInt startupNeeded = false;
424
425 426 427 428
429 Void initDevice(Object *timer);
430
431 432 433 434
435 Int postInit(Object *timer, Error.Block *eb);
436
437 438 439
440 Bool checkOverflow(UInt32 a, UInt32 b);
441
442 /*! Information about timer */
443 struct TimerDevice {
444 UInt intNum;
445 Ptr baseAddr;
446 };
447
448 /*!
449 * ======== numTimerDevices ========
450 * The number of physical timers on the device
451 */
452 config Int numTimerDevices;
453
454 struct Instance_State {
455 Bool staticInst;
456 Int id;
457 UInt controlRegInit;
458 ITimer.RunMode runMode;
459 ITimer.StartMode startMode;
460 UInt period;
461 ITimer.PeriodType periodType;
462 UInt intNum;
463 UArg arg;
464 Hwi.FuncPtr tickFxn;
465 Types.FreqHz frequency;
466 Hwi.Handle hwi;
467 UInt prevThreshold;
468 Bool synchronous;
469 UInt inputDivider;
470 UInt inputDividerExp;
471 }
472
473 struct Module_State {
474 UInt availMask;
475 TimerDevice device[];
476 Handle handles[];
477 }
478 }