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