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 /*! @_nodoc */
208 @XmlDtd
209 metaonly struct BasicView {
210 Ptr halTimerHandle;
211 String label;
212 UInt id;
213 String startMode;
214 String runMode;
215 UInt period;
216 String periodType;
217 Bool synchronous;
218 UInt intNum;
219 String tickFxn[];
220 UArg arg;
221 UInt frequency;
222 String hwiHandle;
223 };
224
225 /*! @_nodoc */
226 metaonly struct DeviceView {
227 UInt id;
228 String device;
229 String devAddr;
230 UInt intNum;
231 String runMode;
232 String clockSource;
233 UInt period;
234 UInt currCount;
235 UInt remainingCount;
236 UInt prevThreshold;
237 String state;
238 };
239
240 /*! @_nodoc */
241 metaonly struct ModuleView {
242 String availMask;
243 }
244
245 /*! @_nodoc */
246 @Facet
247 metaonly config ViewInfo.Instance rovViewInfo =
248 ViewInfo.create({
249 viewMap: [
250 [
251 'Basic',
252 {
253 type: ViewInfo.INSTANCE,
254 viewInitFxn: 'viewInitBasic',
255 structName: 'BasicView'
256 }
257 ],
258 [
259 'Device',
260 {
261 type: ViewInfo.INSTANCE,
262 viewInitFxn: 'viewInitDevice',
263 structName: 'DeviceView'
264 }
265 ],
266 [
267 'Module',
268 {
269 type: ViewInfo.MODULE,
270 viewInitFxn: 'viewInitModule',
271 structName: 'ModuleView'
272 }
273 ],
274 ]
275 });
276
277 /*!
278 * ======== E_invalidTimer ========
279 * Error raised when specified timer id is not supported
280 */
281 config Error.Id E_invalidTimer = {
282 msg: "E_invalidTimer: Invalid Timer Id %d"
283 };
284
285 /*!
286 * ======== E_notAvailable ========
287 * Error raised when requested timer is in use
288 */
289 config Error.Id E_notAvailable = {
290 msg: "E_notAvailable: Timer not available %d"
291 };
292
293 /*!
294 * ======== E_cannotSupport ========
295 * Error raised when requested period is not supported
296 */
297 config Error.Id E_cannotSupport = {
298 msg: "E_cannotSupport: Timer cannot support requested period %d"
299 };
300
301 /*!
302 * ======== anyMask ========
303 * Mask of available timers
304 *
305 * This mask is used to identify the timers that can be used when
306 * Timer_create() is called with an id equal to
307 * {@link Timer#ANY Timer_ANY}.
308 */
309 config UInt anyMask = 0xF;
310
311 /*!
312 * ======== getAvailMask ========
313 * Returns the availMask.
314 *
315 * @b(returns) Mask of available timers
316 */
317 UInt getAvailMask();
318
319 /*!
320 * ======== oneShotStub ========
321 * @_nodoc
322 *
323 * @param(arg) Unused.
324 */
325 Void oneShotStub(UArg arg);
326
327 /*!
328 * ======== oneShotNestStub ========
329 * @_nodoc
330 *
331 * @param(arg) Unused.
332 */
333 Void oneShotNestStub(UArg arg);
334
335 /*!
336 * ======== periodicStub ========
337 * @_nodoc
338 *
339 * @param(arg) Unused.
340 */
341 Void periodicStub(UArg arg);
342
343 /*!
344 * ======== periodicNestStub ========
345 * @_nodoc
346 *
347 * @param(arg) Unused.
348 */
349 Void periodicNestStub(UArg arg);
350
351 /*!
352 * ======== setAvailMask ========
353 * Set the availMask to given mask.
354 *
355 * This function validates the given mask to ensure it does not mark
356 * any currently used timer as available. If validation is successful,
357 * the mask overwrites the current availMask and the function returns
358 * TRUE. Otherwise, the mask is discarded and the function returns
359 * FALSE.
360 *
361 * @param(mask) Mask used to write to availMask
362 */
363 Bool setAvailMask(UInt mask);
364
365 /*!
366 * ======== getHandle ========
367 * @_nodoc
368 * Used by TimestampProvider module to get hold of timer handle used by
369 * Clock.
370 *
371 * @param(id) timer Id.
372 */
373 Handle getHandle(UInt id);
374
375 instance:
376
377 /*! Hwi Params for Hwi Object. Default is null. */
378 config Hwi.Params *hwiParams = null;
379
380 /*! Clock source input select. Default is ACLK. */
381 config Source clockSource = Source_ACLK;
382
383 /*! Selected clock source is synchronous to CPU clock? Default is false. */
384 config Bool synchronous = false;
385
386 /*! Clock Input Divider (ID) select. Default is /1. */
387 config ID inputDivider = ID_1;
388
389 /*! Clock Input Divider Expansion (IDEX) select. Default is /1. */
390 config IDEX inputDividerExp = IDEX_1;
391
392 /*! Enable nesting of other interrupts on top of this Timer's ISR? */
393 config Bool nesting = false;
394
395 /*! Previous threshold count value. */
396 config UInt prevThreshold = 0;
397
398 /*! Control register configuration. Default source = ACLK. */
399 config UInt controlRegInit = Source_ACLK;
400
401 /*!
402 * ======== reconfig ========
403 * Modify timer instances at runtime
404 *
405 * @param(timerParams) timer Params
406 * @param(tickFxn) function that runs when timer expires.
407 */
408 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
409
410
411 internal:
412
413 /*!
414 * ======== noStartupNeeded ========
415 * Flag used to prevent misc code from being brought in
416 * un-necessarily
417 */
418 config UInt startupNeeded = false;
419
420 421 422 423
424 Void initDevice(Object *timer);
425
426 427 428 429
430 Int postInit(Object *timer, Error.Block *eb);
431
432 433 434
435 Bool checkOverflow(UInt32 a, UInt32 b);
436
437 /*! Information about timer */
438 struct TimerDevice {
439 UInt intNum;
440 Ptr baseAddr;
441 };
442
443 /*!
444 * ======== numTimerDevices ========
445 * The number of physical timers on the device
446 */
447 config Int numTimerDevices;
448
449 struct Instance_State {
450 Bool staticInst;
451 Int id;
452 UInt16 controlRegInit;
453 ITimer.RunMode runMode;
454 ITimer.StartMode startMode;
455 UInt period;
456 ITimer.PeriodType periodType;
457 UInt intNum;
458 UArg arg;
459 Hwi.FuncPtr tickFxn;
460 Types.FreqHz frequency;
461 Hwi.Handle hwi;
462 UInt16 prevThreshold;
463 UInt16 savedCurrCount;
464 UInt32 rollovers;
465 Bool synchronous;
466 UInt inputDivider;
467 UInt inputDividerExp;
468 }
469
470 struct Module_State {
471 UInt availMask;
472 TimerDevice device[];
473 Handle handles[];
474 }
475 }