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.timers.dmtimer;
37
38 import xdc.rov.ViewInfo;
39
40 import xdc.runtime.Assert;
41 import xdc.runtime.Error;
42 import xdc.runtime.Types;
43 import ti.sysbios.interfaces.ITimer;
44 import ti.sysbios.hal.Hwi;
45
46 /*!
47 * ======== Timer ========
48 * Timer Peripheral Manager.
49 *
50 * This Timer module manages the Dual Mode timer (dmtimer) peripherals
51 * available on the ARM and C6000 devices (see
52 * {@link ./doc-files/TimerTables.html Timer Mapping Tables} for supported
53 * device information).
54 *
55 * The dmtimer Timer module supports the timer in 'one shot', 'continuous',
56 * and 'dynamic' modes.
57 *
58 * In 'one shot' mode, a timer function will "fire" (run) when the timer period
59 * expires (counts up to zero). In 'one shot' mode this will only happen
60 * once.
61 *
62 * In 'continuous' mode, the specified timer function will "fire" every
63 * time the period expires, throughout the lifetime of the program. When the
64 * period expires in 'continuous mode', the period is then reset to its
65 * original value and then begins counting up to zero again. At this point
66 * the timer function will fire again and the cycle repeats itself.
67 *
68 * In 'dynamic' mode, the specified timer function will "fire" every
69 * time the period expires. But the period of the timer can be changed
70 * dynamically, to correspond to the next tick interrupt needed from the
71 * timer. The timer will continually count upwards, and the timer's compare
72 * mode is used to generate an interrupt when a specific threshold count is
73 * reached. This mode is used by the SYS/BIOS Clock module, for implementing
74 * dynamic tick suppression, which reduces the number of interrupts from the
75 * timer to the minimum required for currently scheduled timeouts.
76 *
77 * @p(html)
78 * <h3> Calling Context </h3>
79 * <table border="1" cellpadding="3">
80 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
81 * </colgroup>
82 *
83 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
84 * <th> Task </th><th> Main </th><th> Startup </th></tr>
85 * <!-- -->
86 * <tr><td> {@link #getNumTimers} </td><td> Y </td>
87 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
88 * <tr><td> {@link #getStatus} </td><td> Y </td>
89 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
90 * <tr><td> {@link #Params_init} </td><td> Y </td>
91 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
92 * <tr><td> {@link #construct} </td><td> Y </td>
93 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
94 * <tr><td> {@link #create} </td><td> N </td>
95 * <td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
96 * <tr><td> {@link #delete} </td><td> N </td>
97 * <td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
98 * <tr><td> {@link #destruct} </td><td> Y </td>
99 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
100 * <tr><td> {@link #getCount} </td><td> Y </td>
101 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
102 * <tr><td> {@link #getFreq} </td><td> Y </td>
103 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
104 * <tr><td> {@link #getFunc} </td><td> Y </td>
105 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
106 * <tr><td> {@link #getPeriod} </td><td> Y </td>
107 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
108 * <tr><td> {@link #reconfig} </td><td> Y </td>
109 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
110 * <tr><td> {@link #setFunc} </td><td> Y </td>
111 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
112 * <tr><td> {@link #setPeriod} </td><td> Y </td>
113 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
114 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td>
115 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
116 * <tr><td> {@link #start} </td><td> Y </td>
117 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
118 * <tr><td> {@link #stop} </td><td> Y </td>
119 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
120 * <tr><td colspan="6"> Definitions: <br />
121 * <ul>
122 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
123 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
124 * <li> <b>Task</b>: API is callable from a Task thread. </li>
125 * <li> <b>Main</b>: API is callable during any of these phases: </li>
126 * <ul>
127 * <li> In your module startup after this module is started
128 * (e.g. Timer_Module_startupDone() returns TRUE). </li>
129 * <li> During xdc.runtime.Startup.lastFxns. </li>
130 * <li> During main().</li>
131 * <li> During BIOS.startupFxns.</li>
132 * </ul>
133 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
134 * <ul>
135 * <li> During xdc.runtime.Startup.firstFxns.</li>
136 * <li> In your module startup before this module is started
137 * (e.g. Timer_Module_startupDone() returns FALSE).</li>
138 * </ul>
139 * </ul>
140 * </td></tr>
141 *
142 * </table>
143 * @p
144 *
145 * @p(html)
146 * <h3> Timer Mapping Tables </h3>
147 * <p>
148 * The Timer module allows the user to use and configure the various timers
149 * that exist on a particular device. This is achieved by specifying a timer
150 * ID when calling {@link ti.sysbios.hal.Timer#Timer_create}.
151 * However, the timer ID
152 * specified may not always map to that timer; for example, specifying an ID
153 * value of 1 does not necessarily mean that this will map to "GPTimer1".
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 @ModuleStartup
160 @InstanceInitStatic
161
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 /*! Max value of Timer period for PeriodType_COUNTS*/
169 const UInt MAX_PERIOD = 0xffffffff;
170
171 /*! L4 interface Configuration Register (TIOCP_CFG). */
172 struct TiocpCfg {
173 Bits8 idlemode; /*! 0=force-idle;1=no-idle;2=Smart-idle;3=Smart-idle */
174 Bits8 emufree; /*! 0=counter frozen; 1=counter free-running */
175 Bits8 softreset; /*! 0=normal mode; 1=soft reset */
176 };
177
178 /*! Interrupt Enable Register (TIER). */
179 struct Tier {
180 Bits8 mat_it_ena; /*! Enable match interrupt */
181 Bits8 ovf_it_ena; /*! Enable overflow interrupt */
182 Bits8 tcar_it_ena; /*! Enable capture interrupt */
183 };
184
185 /*! WakepUp Enable Register (TWER). */
186 struct Twer {
187 Bits8 mat_wup_ena; /*! Enable match wake-up */
188 Bits8 ovf_wup_ena; /*! Enable overflow wake-up */
189 Bits8 tcar_wup_ena; /*! Enable capture wake-up */
190 };
191
192 /*! Control Register (TCLR). */
193 struct Tclr {
194 Bits32 ptv; /*! Trigger output mode */
195 Bits8 pre; /*! Prescalar enable */
196 Bits8 ce; /*! Compare enable */
197 Bits8 scpwm;/*! Pulse-width modulation */
198 Bits16 tcm; /*! Transition capture mode */
199 Bits16 trg; /*! Trigger output mode */
200 Bits8 pt; /*! Pulse or toggle select bit */
201 Bits8 captmode; /*! Capture mode select bit */
202 Bits8 gpocfg; /*! PWM output/event detection input pin */
203 };
204
205 /*!
206 * ======== Tsicr ========
207 * L4 Interface Synchronization Control Register (TSICR).
208 *
209 * Note: 'readmode' field is not available on some older Silicon.
210 * Please check the technical reference manual of your device to
211 * determine if this field is available before using it.
212 */
213 struct Tsicr {
214 Bits8 sft; /*! Reset software functional registers */
215 Bits8 posted; /*! Posted mode selection */
216 Bits8 readmode; /*! Select posted/non-posted mode for read operation */
217 };
218
219 /*! Timer Settings. */
220 metaonly struct TimerSetting {
221 Bool master; /*! specifies whether this is the master */
222 Ptr baseAddr; /*! specify the base address */
223 Int intNum; /*! specify which interrupt vector */
224 Int eventId; /*! specify which event number to use */
225 String name; /*! specify the timer name */
226 };
227
228 /*!
229 * ======== BasicView ========
230 * @_nodoc
231 */
232 metaonly struct BasicView {
233 Ptr halTimerHandle;
234 String label;
235 UInt id;
236 String name;
237 String startMode;
238 String runMode;
239 UInt period;
240 String periodType;
241 UInt intNum;
242 String eventId;
243 String tickFxn[];
244 UArg arg;
245 String extFreqLow;
246 String extFreqHigh;
247 String hwiHandle;
248 };
249
250 /*!
251 * ======== DeviceView ========
252 * @_nodoc
253 */
254 metaonly struct DeviceView {
255 UInt id;
256 String deviceAddr;
257 UInt intNum;
258 String eventId;
259 String runMode;
260 String timerState;
261 UInt period;
262 String currCount;
263 String remainingCount;
264 };
265
266 /*!
267 * ======== ModuleView ========
268 * @_nodoc
269 */
270 metaonly struct ModuleView {
271 String availMask;
272 String intFrequency[];
273 }
274
275 /*!
276 * ======== rovViewInfo ========
277 * @_nodoc
278 */
279 @Facet
280 metaonly config ViewInfo.Instance rovViewInfo =
281 ViewInfo.create({
282 viewMap: [
283 [
284 'Basic',
285 {
286 type: ViewInfo.INSTANCE,
287 viewInitFxn: 'viewInitBasic',
288 structName: 'BasicView'
289 }
290 ],
291 [
292 'Device',
293 {
294 type: ViewInfo.INSTANCE,
295 viewInitFxn: 'viewInitDevice',
296 structName: 'DeviceView'
297 }
298 ],
299 [
300 'Module',
301 {
302 type: ViewInfo.MODULE,
303 viewInitFxn: 'viewInitModule',
304 structName: 'ModuleView'
305 }
306 ],
307 ]
308 });
309
310 /*!
311 * Assert raised when statically created timer is not available
312 */
313 config xdc.runtime.Assert.Id A_notAvailable = {
314 msg: "A_notAvailable: statically created timer not available"
315 };
316
317 /*!
318 * Error raised when timer id specified is not supported.
319 */
320 config Error.Id E_invalidTimer = {
321 msg: "E_invalidTimer: Invalid Timer Id %d"
322 };
323
324 /*!
325 * Error raised when timer requested is in use
326 */
327 config Error.Id E_notAvailable = {
328 msg: "E_notAvailable: Timer not available %d"
329 };
330
331 /*!
332 * Error raised when period requested is not supported
333 */
334 config Error.Id E_cannotSupport = {
335 msg: "E_cannotSupport: Timer cannot support requested period %d"
336 };
337
338 /*!
339 * Error raised when timer frequency does not match expected frequency
340 *
341 * BIOS does not configure the DMTimer clock source and expects this
342 * configuration to be performed via a GEL script or on the host OS. This
343 * error is raised if BIOS detects a mismatch between {@link #intFreq} and
344 * the actual operating frequency. The check is performed by comparing
345 * the timestamp operating frequency with the DMTimer frequency.
346 *
347 * To change the expected timer frequency to match the actual operating
348 * frequency, use the following example configuration:
349 * @p(code)
350 * var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
351 * Timer.intFreq.lo = 20000000; //For 20Mhz
352 * Timer.intFreq.hi = 0;
353 * @p
354 *
355 * This check can be skipped by setting {@link #checkFrequency} to FALSE.
356 */
357 config Error.Id E_freqMismatch = {
358 msg: "E_freqMismatch: Frequency mismatch: Expected %d Hz, actual: %d Hz. You need to modify Timer.intFreq.lo to match the actual frequency."
359 };
360
361 /*!
362 * Error raised when intNum not supplied by user or device table
363 */
364 config Error.Id E_badIntNum = {
365 msg: "E_badIntNum: Timer requires a valid intNum. Please use DMTimer module's timerSettings config param to assign a valid intNum for the selected timer."
366 };
367
368 /*!
369 * ======== anyMask ========
370 * Available mask to be used when select = Timer_ANY.
371 *
372 * Default value is device specific.
373 */
374 config Bits32 anyMask;
375
376 /*!
377 * ======== checkFrequency ========
378 * Whether to check the timer operating frequency at startup
379 *
380 * When this flag is set to 'TRUE', the Timer module will verify that the
381 * operating frequency equals the frequency at which BIOS expects the
382 * timers to operate. This check is performed by checking the timer count
383 * rate against the {@link xdc.runtime.Timestamp} count rate.
384 *
385 * @a(NOTE)
386 * The frequency check operation is performed with interrupts disabled in
387 * order to obtain an accurate measurement of the actual clock frequency.
388 * At low input clock frequencies such as 32,768Hz, this can result in
389 * a very long period of time with interrupts disabled. As the frequency
390 * check is only performed at Timer create/construct time, the latency
391 * effect can be minimized by performing all runtime Timer creates/constructs
392 * within main() or within a Task when it is known to be safe to incur the
393 * the potential latency hit.
394 */
395 config Bool checkFrequency = true;
396
397 /*!
398 * ======== timerSettings ========
399 * Global Control configuration for each physical timer.
400 */
401 metaonly config TimerSetting timerSettings[] = [];
402
403 /*!
404 * ======== intFreq ========
405 * Default internal timer input clock frequency.
406 *
407 * If intFreq is set, its value will be copied into all
408 * {@link #intFreqs}[] array entries except any entry which was
409 * explicitly written to in the application's config script.
410 *
411 * For example, if intFreq is set to {hi:0, lo:32768} on a device
412 * with 3 timers, it will be copied into intFreqs[0], intFreqs[1] &
413 * intFreqs[2]. If the application explicitly sets one of the
414 * {@link #intFreqs}[] entries, say intFreqs[1], then intFreq is not
415 * copied into intFreqs[1] and intFreqs[1] retains the value it was
416 * set to in the config script.
417 */
418 metaonly config Types.FreqHz intFreq = {lo: 0, hi: 0};
419
420 /*!
421 * ======== intFreqs ========
422 * Default internal timer input clock frequency array.
423 *
424 * This array can be used to change the input clock frequency
425 * for a particular timer.
426 *
427 * For example, if it is required to change the input clock frequency
428 * for timer id 2 to 32768Hz on a device that has 4 timers, the
429 * intFreqs[2] config param can be set to {hi:0, lo:32768} in the
430 * config script.
431 *
432 * For a list of default timer frequencies for different devices,
433 * please refer {@link ./doc-files/TimerTables.html Timer Mapping Tables}.
434 */
435 metaonly config Types.FreqHz intFreqs[];
436
437 /*!
438 * ======== stub ========
439 * @_nodoc
440 * Timer requires acknowledgement
441 *
442 * @param(arg) timer object passed in as argument.
443 */
444 Void stub(UArg arg);
445
446 /*!
447 * ======== dynStub ========
448 * @_nodoc
449 * Acknowledges timer interrupt and sets next threshold for interrupt.
450 *
451 * @param(arg) timer object passed in as argument.
452 */
453 Void dynStub(UArg arg);
454
455 /*!
456 * ======== getHandle ========
457 * Get Handle associated with a timer id.
458 *
459 * @param(id) timer Id
460 * @b(returns) timer handle
461 */
462
463 Handle getHandle(UInt id);
464
465 instance:
466
467 /*!
468 * ======== tiocpCfg ========
469 * Initial Timer TIOCP_CFG Register bit settings.
470 *
471 * For a detailed description of this timer register, please
472 * refer to your device's Technical Reference Manual.
473 */
474 config TiocpCfg tiocpCfg = {idlemode: 0, emufree: 0, softreset: 1};
475
476 /*!
477 * ======== tier ========
478 * Initial Timer IRQSTATUS_SET Register bit settings.
479 *
480 * For a detailed description of this timer register, please
481 * refer to your device's Technical Reference Manual.
482 */
483 config Tier tier = {mat_it_ena: 0, ovf_it_ena: 1, tcar_it_ena: 0};
484
485 /*!
486 * ======== twer ========
487 * Initial Timer IRQ Wakeup Enable Register bit settings.
488 *
489 * For a detailed description of this timer register, please
490 * refer to your device's Technical Reference Manual.
491 */
492 config Twer twer = {mat_wup_ena: 0, ovf_wup_ena: 0, tcar_wup_ena: 0};
493
494 /*!
495 * ======== tclr ========
496 * Initial Timer Control Register bit settings.
497 *
498 * For a detailed description of this timer register, please
499 * refer to your device's Technical Reference Manual.
500 */
501 config Tclr tclr = {ptv: 0, pre: 0, ce: 0, scpwm: 0, tcm: 0, trg: 0,
502 pt: 0, captmode: 0, gpocfg: 0};
503
504 /*!
505 * ======== tsicr ========
506 * Initial Timer Synchronous Interface Control Register bit settings.
507 *
508 * For a detailed description of this timer register, please
509 * refer to your device's Technical Reference Manual.
510 */
511 config Tsicr tsicr = {sft: 0, posted: 0, readmode: 0};
512
513 /*!
514 * ======== tmar ========
515 * Initial Timer Match Register setting.
516 *
517 * For a detailed description of this timer register, please
518 * refer to your device's Technical Reference Manual.
519 */
520 config UInt32 tmar = 0;
521
522 /*!
523 * ======== intNum ========
524 * Hwi interrupt number to be used by Timer.
525 */
526 config Int intNum = -1;
527
528 /*!
529 * ======== eventId ========
530 * Hwi event Id to be used by Timer.
531 */
532 config Int eventId = -1;
533
534 /*! Hwi Params for Hwi Object. Default is null. */
535 config Hwi.Params *hwiParams = null;
536
537 /*!
538 * ======== reconfig ========
539 * Used to modify static timer instances at runtime.
540 *
541 * @param(timerParams) timer Params
542 * @param(tickFxn) functions that runs when timer expires
543 */
544
545 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
546
547 /*!
548 * ======== getRollovers ========
549 * @_nodoc
550 * Returns the total number of timer rollovers since the timer was
551 * started. This API is used internally for implementing timestamping
552 * when the timer is shared with Clock, and running with RunMode_DYNAMIC.
553 * It has no other intended purpose.
554 *
555 * @b(returns) number of rollovers since timer was started
556 */
557 UInt32 getRollovers();
558
559 /*!
560 * ======== enableTimestamping ========
561 * @_nodoc
562 * Enables the timer to be used for timestamping purposes. This API is
563 * used internally for enabling timestamping when the timer is shared with
564 * Clock, and running with RunMode_DYNAMIC. It has no other intended
565 * purpose.
566 *
567 */
568 Void enableTimestamping();
569
570 /*!
571 * ======== restoreRegisters ========
572 * Restore timer registers to their nominal state following a power down.
573 *
574 * All registers are restored to their nominal operating state, except
575 * for those registers and bits associated with starting the timer.
576 *
577 * Following a power down, the user should do the following to restore
578 * and restart the timer:
579 *
580 * @p(code)
581 * Timer_handle timer;
582 * Error_Block eb;
583 *
584 * Timer_restoreRegisters(timer, &eb);
585 * Timer_start(timer);
586 * @p
587 *
588 */
589
590 Void restoreRegisters(Error.Block *eb);
591
592 /*! @_nodoc
593 * ======== getIntNum ========
594 * Get Timer's Interrupt number.
595 *
596 * @b(returns) Timer's Interrupt number
597 */
598 Int getIntNum();
599
600 internal:
601
602
603 /*! Information about timer */
604 struct TimerDevice {
605 Int intNum;
606 Int eventId;
607 Ptr baseAddr;
608 };
609
610 /*! Device-specific Timer implementation. */
611 proxy TimerSupportProxy inherits ti.sysbios.interfaces.ITimerSupport;
612
613 /*!
614 * ======== startupNeeded ========
615 * This flag is use to prevent Timer_startup code (includes postInit(),
616 * deviceConfig(), initDevice() to be brought in un-necessarily.
617 */
618 config Bool startupNeeded = false;
619
620 /*!
621 * ======== numTimerDevices ========
622 * The number of logical timers on a device.
623 */
624 config Int numTimerDevices;
625
626 627 628 629
630 Int deviceConfig(Object *timer, Error.Block *eb);
631
632 633 634 635
636 Void initDevice(Object *timer, Error.Block *eb);
637
638 639 640 641
642 Void initObj(Object *timer, FuncPtr tickFxn, const Params *timerParams);
643
644 645 646 647
648 Int postInit(Object *timer, Error.Block *eb);
649
650 651 652
653 Bool checkOverflow(UInt32 a, UInt32 b);
654
655 656 657
658 UInt getNextAvailableTimerId(Object *timer);
659
660 /*!
661 * ======== spinLoop ========
662 * used by trigger function.
663 */
664 Void spinLoop(UInt count);
665
666 /*!
667 * ======== checkFreq ========
668 * Used to verify that the DMTimer is operating at the right frequency.
669 */
670 Void checkFreq(Timer.Object *obj);
671
672 /*! Instance state structure */
673 struct Instance_State {
674 Bool staticInst;
675 Int id;
676 UInt tiocpCfg;
677 UInt tmar;
678 UInt tier;
679 UInt twer;
680 UInt tclr;
681 UInt tsicr;
682 ITimer.RunMode runMode;
683 ITimer.StartMode startMode;
684 UInt period;
685 ITimer.PeriodType periodType;
686 UInt intNum;
687 Int eventId;
688 UArg arg;
689 Hwi.FuncPtr tickFxn;
690 Types.FreqHz extFreq;
691 Hwi.Handle hwi;
692 UInt prevThreshold;
693 UInt rollovers;
694 UInt savedCurrCount;
695 696 697 698
699 Bool useDefaultEventId;
700 }
701
702 /*! Module state structure */
703 struct Module_State {
704 Bits32 availMask;
705 Types.FreqHz intFreqs[];
706 TimerDevice device[];
707 Handle handles[];
708 Bool firstInit;
709 }
710 }