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
38 package ti.sysbios.timers.dmtimer;
39
40 import xdc.rov.ViewInfo;
41
42 import xdc.runtime.Error;
43 import xdc.runtime.Types;
44 import ti.sysbios.interfaces.ITimer;
45 import ti.sysbios.hal.Hwi;
46
47 /*!
48 * ======== Timer ========
49 * Timer Peripheral Manager.
50 *
51 * This Timer module manages the Dual Mode timer (dmtimer) peripherals
52 * available on the ARM and C6000 devices (see
53 * {@link ./doc-files/TimerTables.html Timer Mapping Tables} for supported
54 * device information).
55 *
56 * The dmtimer Timer module supports the timer in 'one shot', 'continuous',
57 * and 'dynamic' modes.
58 *
59 * In 'one shot' mode, a timer function will "fire" (run) when the timer period
60 * expires (counts up to zero). In 'one shot' mode this will only happen
61 * once.
62 *
63 * In 'continuous' mode, the specified timer function will "fire" every
64 * time the period expires, throughout the lifetime of the program. When the
65 * period expires in 'continuous mode', the period is then reset to its
66 * original value and then begins counting up to zero again. At this point
67 * the timer function will fire again and the cycle repeats itself.
68 *
69 * In 'dynamic' mode, the specified timer function will "fire" every
70 * time the period expires. But the period of the timer can be changed
71 * dynamically, to correspond to the next tick interrupt needed from the
72 * timer. The timer will continually count upwards, and the timer's compare
73 * mode is used to generate an interrupt when a specific threshold count is
74 * reached. This mode is used by the SYS/BIOS Clock module, for implementing
75 * dynamic tick suppression, which reduces the number of interrupts from the
76 * timer to the minimum required for currently scheduled timeouts.
77 *
78 * @p(html)
79 * <h3> Calling Context </h3>
80 * <table border="1" cellpadding="3">
81 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
82 * </colgroup>
83 *
84 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
85 * <th> Task </th><th> Main </th><th> Startup </th></tr>
86 * <!-- -->
87 * <tr><td> {@link #getNumTimers} </td><td> Y </td>
88 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
89 * <tr><td> {@link #getStatus} </td><td> Y </td>
90 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
91 * <tr><td> {@link #Params_init} </td><td> Y </td>
92 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
93 * <tr><td> {@link #construct} </td><td> Y </td>
94 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
95 * <tr><td> {@link #create} </td><td> N </td>
96 * <td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
97 * <tr><td> {@link #delete} </td><td> N </td>
98 * <td> N </td><td> Y </td><td> Y </td><td> N </td></tr>
99 * <tr><td> {@link #destruct} </td><td> Y </td>
100 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
101 * <tr><td> {@link #getCount} </td><td> Y </td>
102 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
103 * <tr><td> {@link #getFreq} </td><td> Y </td>
104 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
105 * <tr><td> {@link #getFunc} </td><td> Y </td>
106 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
107 * <tr><td> {@link #getPeriod} </td><td> Y </td>
108 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
109 * <tr><td> {@link #reconfig} </td><td> Y </td>
110 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
111 * <tr><td> {@link #setFunc} </td><td> Y </td>
112 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
113 * <tr><td> {@link #setPeriod} </td><td> Y </td>
114 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
115 * <tr><td> {@link #setPeriodMicroSecs} </td><td> Y </td>
116 * <td> Y </td><td> Y </td><td> Y </td><td> N </td></tr>
117 * <tr><td> {@link #start} </td><td> Y </td>
118 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
119 * <tr><td> {@link #stop} </td><td> Y </td>
120 * <td> Y </td><td> Y </td><td> N </td><td> N </td></tr>
121 * <tr><td colspan="6"> Definitions: <br />
122 * <ul>
123 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
124 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
125 * <li> <b>Task</b>: API is callable from a Task thread. </li>
126 * <li> <b>Main</b>: API is callable during any of these phases: </li>
127 * <ul>
128 * <li> In your module startup after this module is started
129 * (e.g. Timer_Module_startupDone() returns TRUE). </li>
130 * <li> During xdc.runtime.Startup.lastFxns. </li>
131 * <li> During main().</li>
132 * <li> During BIOS.startupFxns.</li>
133 * </ul>
134 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
135 * <ul>
136 * <li> During xdc.runtime.Startup.firstFxns.</li>
137 * <li> In your module startup before this module is started
138 * (e.g. Timer_Module_startupDone() returns FALSE).</li>
139 * </ul>
140 * </ul>
141 * </td></tr>
142 *
143 * </table>
144 * @p
145 *
146 * @p(html)
147 * <h3> Timer Mapping Tables </h3>
148 * <p>
149 * The Timer module allows the user to use and configure the various timers
150 * that exist on a particular device. This is achieved by specifying a timer
151 * ID when calling {@link ti.sysbios.hal.Timer#Timer_create}.
152 * However, the timer ID
153 * specified may not always map to that timer; for example, specifying an ID
154 * value of 1 does not necessarily mean that this will map to "GPTimer1".
155 * These tables are provided to show which timers map to which timer IDs.
156 * </p>
157 * {@link ./doc-files/TimerTables.html Timer Mapping Tables}
158 * @p
159 */
160 @InstanceFinalize
161 @InstanceInitError
162 @ModuleStartup
163
164 module Timer inherits ti.sysbios.interfaces.ITimer
165 {
166 /*! override supportsDynamic - this Timer does support RunMode_DYNAMIC */
167 override metaonly config Bool supportsDynamic = true;
168
169 /*! Max value of Timer period for PeriodType_COUNTS*/
170 const UInt MAX_PERIOD = 0xffffffff;
171
172 /*! L4 interface Configuration Register (TIOCP_CFG). */
173 struct TiocpCfg {
174 Bits8 idlemode; /*! 0=force-idle;1=no-idle;2=Smart-idle;3=Smart-idle */
175 Bits8 emufree; /*! 0=counter frozen; 1=counter free-running */
176 Bits8 softreset; /*! 0=normal mode; 1=soft reset */
177 };
178
179 /*! Interrupt Enable Register (TIER). */
180 struct Tier {
181 Bits8 mat_it_ena; /*! Enable match interrupt */
182 Bits8 ovf_it_ena; /*! Enable overflow interrupt */
183 Bits8 tcar_it_ena; /*! Enable capture interrupt */
184 };
185
186 /*! WakepUp Enable Register (TWER). */
187 struct Twer {
188 Bits8 mat_wup_ena; /*! Enable match wake-up */
189 Bits8 ovf_wup_ena; /*! Enable overflow wake-up */
190 Bits8 tcar_wup_ena; /*! Enable capture wake-up */
191 };
192
193 /*! Control Register (TCLR). */
194 struct Tclr {
195 Bits32 ptv; /*! Trigger output mode */
196 Bits8 pre; /*! Prescalar enable */
197 Bits8 ce; /*! Compare enable */
198 Bits8 scpwm;/*! Pulse-width modulation */
199 Bits16 tcm; /*! Transition capture mode */
200 Bits16 trg; /*! Trigger output mode */
201 Bits8 pt; /*! Pulse or toggle select bit */
202 Bits8 captmode; /*! Capture mode select bit */
203 Bits8 gpocfg; /*! PWM output/event detection input pin */
204 };
205
206 /*! L4 Interface Synchronization Control Register (TSICR). */
207 struct Tsicr {
208 Bits8 sft; /*! Reset software functional registers */
209 Bits8 posted; /*! Posted mode selection */
210 };
211
212 /*! Timer Settings. */
213 metaonly struct TimerSetting {
214 Bool master; /*! specifies whether this is the master */
215 Ptr baseAddr; /*! specify the base address */
216 Int intNum; /*! specify which interrupt vector */
217 String name; /*! specify the timer name */
218 };
219
220 /*!
221 * ======== BasicView ========
222 * @_nodoc
223 */
224 metaonly struct BasicView {
225 Ptr halTimerHandle;
226 String label;
227 UInt id;
228 String name;
229 String startMode;
230 String runMode;
231 UInt period;
232 String periodType;
233 UInt intNum;
234 String tickFxn[];
235 UArg arg;
236 String extFreqLow;
237 String extFreqHigh;
238 String hwiHandle;
239 };
240
241
242 /*!
243 * ======== ModuleView ========
244 * @_nodoc
245 */
246 metaonly struct ModuleView {
247 String availMask;
248 String intFrequency;
249 }
250
251 /*!
252 * ======== rovViewInfo ========
253 * @_nodoc
254 */
255 @Facet
256 metaonly config ViewInfo.Instance rovViewInfo =
257 ViewInfo.create({
258 viewMap: [
259 [
260 'Basic',
261 {
262 type: ViewInfo.INSTANCE,
263 viewInitFxn: 'viewInitBasic',
264 structName: 'BasicView'
265 }
266 ],
267 [
268 'Module',
269 {
270 type: ViewInfo.MODULE,
271 viewInitFxn: 'viewInitModule',
272 structName: 'ModuleView'
273 }
274 ],
275 ]
276 });
277
278 /*!
279 * Error raised when timer id specified is not supported.
280 */
281 config Error.Id E_invalidTimer = {
282 msg: "E_invalidTimer: Invalid Timer Id %d"
283 };
284
285 /*!
286 * Error raised when timer requested is in use
287 */
288 config Error.Id E_notAvailable = {
289 msg: "E_notAvailable: Timer not available %d"
290 };
291
292 /*!
293 * Error raised when period requested is not supported
294 */
295 config Error.Id E_cannotSupport = {
296 msg: "E_cannotSupport: Timer cannot support requested period %d"
297 };
298
299 /*!
300 * Error raised when timer frequency does not match expected frequency
301 *
302 * BIOS does not configure the DMTimer clock source and expects this
303 * configuration to be performed via a GEL script or on the host OS. This
304 * error is raised if BIOS detects a mismatch between {@link #intFreq} and
305 * the actual operating frequency. The check is performed by comparing
306 * the timestamp operating frequency with the DMTimer frequency.
307 *
308 * To change the expected timer frequency to match the actual operating
309 * frequency, use the following example configuration:
310 * @p(code)
311 * var Timer = xdc.useModule('ti.sysbios.timers.dmtimer.Timer');
312 * Timer.intFreq.lo = 20000000; //For 20Mhz
313 * Timer.intFreq.hi = 0;
314 * @p
315 *
316 * This check can be skipped by setting {@link #checkFrequency} to FALSE.
317 */
318 config Error.Id E_freqMismatch = {
319 msg: "E_freqMismatch: Frequency mismatch: Expected %d Hz, actual: %d Hz. You need to modify Timer.intFreq.lo to match the actual frequency."
320 };
321
322 /*!
323 * ======== anyMask ========
324 * Available mask to be used when select = Timer_ANY.
325 *
326 * Default value is device specific.
327 */
328 config Bits32 anyMask;
329
330 /*!
331 * ======== checkFrequency ========
332 * Whether to check the timer operating frequency at startup
333 *
334 * When this flag is set to 'TRUE', the Timer module will verify that the
335 * operating frequency equals the frequency at which BIOS expects the
336 * timers to operate. This check is performed by checking the timer count
337 * rate against the {@link xdc.runtime.Timestamp} count rate.
338 */
339 config Bool checkFrequency = true;
340
341 /*!
342 * ======== timerSettings ========
343 * Global Control configuration for each physical timer.
344 */
345 metaonly config TimerSetting timerSettings[] = [];
346
347 /*!
348 * ======== intFreq ========
349 * Default internal timer input clock frequency.
350 */
351 metaonly config Types.FreqHz intFreq = {lo: 0, hi: 0};
352
353 /*!
354 * ======== stub ========
355 * @_nodoc
356 * Timer requires acknowledgement
357 *
358 * @param(arg) timer object passed in as argument.
359 */
360 @DirectCall
361 Void stub(UArg arg);
362
363 /*!
364 * ======== dynStub ========
365 * @_nodoc
366 * Acknowledges timer interrupt and sets next threshold for interrupt.
367 *
368 * @param(arg) timer object passed in as argument.
369 */
370 @DirectCall
371 Void dynStub(UArg arg);
372
373 instance:
374
375 /*!
376 * ======== tiocpCfg ========
377 * Initial Timer TIOCP_CFG Register bit settings.
378 *
379 * For a detailed description of this timer register, please
380 * refer to your device's Technical Reference Manual.
381 */
382 config TiocpCfg tiocpCfg = {idlemode: 0, emufree: 0, softreset: 1};
383
384 /*!
385 * ======== tier ========
386 * Initial Timer IRQSTATUS_SET Register bit settings.
387 *
388 * For a detailed description of this timer register, please
389 * refer to your device's Technical Reference Manual.
390 */
391 config Tier tier = {mat_it_ena: 0, ovf_it_ena: 1, tcar_it_ena: 0};
392
393 /*!
394 * ======== twer ========
395 * Initial Timer IRQ Wakeup Enable Register bit settings.
396 *
397 * For a detailed description of this timer register, please
398 * refer to your device's Technical Reference Manual.
399 */
400 config Twer twer = {mat_wup_ena: 0, ovf_wup_ena: 0, tcar_wup_ena: 0};
401
402 /*!
403 * ======== tclr ========
404 * Initial Timer Control Register bit settings.
405 *
406 * For a detailed description of this timer register, please
407 * refer to your device's Technical Reference Manual.
408 */
409 config Tclr tclr = {ptv: 0, pre: 0, ce: 0, scpwm: 0, tcm: 0, trg: 0,
410 pt: 0, captmode: 0, gpocfg: 0};
411
412 /*!
413 * ======== tsicr ========
414 * Initial Timer Synchronous Interface Control Register bit settings.
415 *
416 * For a detailed description of this timer register, please
417 * refer to your device's Technical Reference Manual.
418 */
419 config Tsicr tsicr = {sft: 0, posted: 1};
420
421 /*!
422 * ======== tmar ========
423 * Initial Timer Match Register setting.
424 *
425 * For a detailed description of this timer register, please
426 * refer to your device's Technical Reference Manual.
427 */
428 config UInt32 tmar = 0;
429
430 /*! Hwi Params for Hwi Object. Default is null. */
431 config Hwi.Params *hwiParams = null;
432
433 /*!
434 * ======== reconfig ========
435 * Used to modify static timer instances at runtime.
436 *
437 * @param(timerParams) timer Params
438 * @param(tickFxn) functions that runs when timer expires
439 */
440 @DirectCall
441 Void reconfig(FuncPtr tickFxn, const Params *timerParams, Error.Block *eb);
442
443 /*!
444 * ======== getRollovers ========
445 * @_nodoc
446 * Returns the total number of timer rollovers since the timer was
447 * started. This API is used internally for implementing timestamping
448 * when the timer is shared with Clock, and running with RunMode_DYNAMIC.
449 * It has no other intended purpose.
450 *
451 * @b(returns) number of rollovers since timer was started
452 */
453 @DirectCall
454 UInt32 getRollovers();
455
456 /*!
457 * ======== enableTimestamping ========
458 * @_nodoc
459 * Enables the timer to be used for timestamping purposes. This API is
460 * used internally for enabling timestamping when the timer is shared with
461 * Clock, and running with RunMode_DYNAMIC. It has no other intended
462 * purpose.
463 *
464 */
465 @DirectCall
466 Void enableTimestamping();
467
468
469 internal:
470
471
472 /*! Device-specific Timer implementation. */
473 proxy TimerSupportProxy inherits ti.sysbios.interfaces.ITimerSupport;
474
475 /*!
476 * ======== startupNeeded ========
477 * This flag is use to prevent Timer_startup code (includes postInit(),
478 * deviceConfig(), initDevice() to be brought in un-necessarily.
479 */
480 config Bool startupNeeded = false;
481
482 /*! Information about timer */
483 struct TimerDevice {
484 UInt intNum;
485 UInt eventId;
486 Ptr baseAddr;
487 };
488
489 /*!
490 * ======== numTimerDevices ========
491 * The number of logical timers on a device.
492 */
493 config Int numTimerDevices;
494
495 /*!
496 * ======== spinLoop ========
497 * used by trigger function.
498 */
499 Void spinLoop(UInt count);
500
501 /*!
502 * ======== checkFreq ========
503 * Used to verify that the DMTimer is operating at the right frequency.
504 */
505 Void checkFreq(Timer.Object *obj);
506
507 /*! Instance state structure */
508 struct Instance_State {
509 Bool staticInst;
510 Int id;
511 UInt tiocpCfg;
512 UInt tmar;
513 UInt tier;
514 UInt twer;
515 UInt tclr;
516 UInt tsicr;
517 ITimer.RunMode runMode;
518 ITimer.StartMode startMode;
519 UInt period;
520 ITimer.PeriodType periodType;
521 UInt intNum;
522 UArg arg;
523 Hwi.FuncPtr tickFxn;
524 Types.FreqHz extFreq;
525 Hwi.Handle hwi;
526 UInt prevThreshold;
527 UInt rollovers;
528 }
529
530 /*! Module state structure */
531 struct Module_State {
532 Bits32 availMask;
533 Types.FreqHz intFreq;
534 TimerDevice device[];
535 Handle handles[];
536 Bool firstInit;
537 }
538 }
539 540 541 542
543